Збережіть лише один файл із кількох файлів, які були змінені Git?


3068

Як я можу зберігати лише один із декількох змінених файлів у своїй гілці?


109
Я не думаю, що прийнята відповідь @ bukzor є правильною відповіддю на запитання, яке було задано. git stash --keep-indexвін зберігає індекс, але він приховує все - і в індексі, і в зовнішньому.
Раман

@Antonio Мені здається, що ваша щедрість насправді має бути окремим питанням, оскільки оригінальне запитання не має нічого спільного з TortoiseGit.
JesusFreke

1
@JesusFreke Так, з огляду на результат, я міг би пощадити 50 представників :) Просто це питання, на яке ви перенаправляєтесь, якщо спробуєте шукати "частковий прихований черепах". Tortoisegit, здається, не є популярною темою тут stackoverflow.com/questions/tagged/tortoisegit
Антоніо

7
>>>>>>>>> git diff -- *filename* > ~/patchтоді git checkout -- *filename*і пізніше ви можете повторно застосувати патч за допомогоюgit apply ~/patch
неаумузичного

36
Більшість наявних відповідей нижче застаріли. Оскільки Git 2.13 (Q2 2017), він підтримується git stash push [--] [<pathspec>...].
Охад Шнайдер

Відповіді:


1372

Відмова від відповідальності : наступна відповідь стосується git перед git 2.13. Для git 2.13 і більше, перегляньте ще одну відповідь далі .


Увага

Як зазначається в коментарях, це ставить усе в сховище, як поетапне, так і нестандартне. --Keep-індекс просто залишає індекс в спокої після того, як буде зроблено сховано. Це може спричинити конфлікти злиття, коли пізніше викинете скрипт.


Це приховає все, що ви раніше не додавали. Просто git addті речі, які ви хочете зберегти, потім запустіть їх.

git stash --keep-index

Наприклад, якщо ви хочете розділити стару комісію на декілька наборів змін, ви можете скористатися цією процедурою:

  1. git rebase -i <last good commit>
  2. Позначити деякі зміни як edit.
  3. git reset HEAD^
  4. git add <files you want to keep in this change>
  5. git stash --keep-index
  6. Виправте речі за потребою. Не забувайте про git addбудь-які зміни.
  7. git commit
  8. git stash pop
  9. Повторіть, з №5, за необхідності.
  10. git rebase --continue

47
Я вважаю , що такий підхід до набагато більш простіше: stackoverflow.com/a/5506483/457268
k0pernikus

561
Я не впевнений, чому це вимагається. Кожен повинен мати інше очікування, ніж я. У початковому дописі запитується "як я зберігаю лише частину невідомих змін?" Коли я використовую git stash save -k, так, індекс (зелений в git stat) зберігається, але весь набір змін (і зелений, і червоний) переходить у сховище. Це порушує запит ОП, "приховуйте лише деякі зміни". Я хочу приховати лише частину червоного (для подальшого використання).
Пістос

70
Якщо вас більше цікавить відповідь на питання, поставлене @Pistos (як я був), тоді дивіться тут: stackoverflow.com/questions/5506339/…
Раман

27
@Raman: Відмінно! git stash -pсаме те, що я шукав. Цікаво, чи цей перемикач був доданий лише нещодавно.
Пістос

14
ПОПЕРЕДЖЕННЯ: git stash --keep-indexзламано. Якщо ви внесете більше змін, то спробуйте git stash popпізніше отримати конфлікти злиття, оскільки схована скринька включає зміни файлів, які ви зберегли, а не лише ті, які ви не зберегли. Наприклад: я змінюю файли A і B, потім зберігаю B, тому що хочу перевірити зміни в A; Я знаходжу проблему з A, яку потім виправляю; Я вчиняю А; Тепер я не можу зняти знімок, тому що стара версія A стоїть у сховці без поважних причин, що викликає конфлікт злиття. На практиці A і B може бути багато файлів, можливо, навіть двійкові зображення або щось подібне, тому я, в основному, маю відмовитися і втратити B.
rjmunro

3015

Ви також можете використовувати git stash save -p "my commit message". Таким чином ви можете вибрати, які файли слід додати до сховища, також можна вибрати цілі файли.

Вам буде запропоновано виконати кілька дій для кожної частини:

   y - stash this hunk
   n - do not stash this hunk
   q - quit; do not stash this hunk or any of the remaining ones
   a - stash this hunk and all later hunks in the file
   d - do not stash this hunk or any of the later hunks in the file
   g - select a hunk to go to
   / - search for a hunk matching the given regex
   j - leave this hunk undecided, see next undecided hunk
   J - leave this hunk undecided, see next hunk
   k - leave this hunk undecided, see previous undecided hunk
   K - leave this hunk undecided, see previous hunk
   s - split the current hunk into smaller hunks
   e - manually edit the current hunk
   ? - print help

5
Це не так. Він був запозичений у Дарка, приблизно через 7 років після факту.
іменник

6
Я наркоман TortoiseGit. Однак TortoiseGit не підтримує stash -p. Цю відповідь я нагороджую, оскільки вона залишається найбільш інтерактивною / зручною для користувачів.
Антоніо

27
ви можете додати git stash save -p my stash message:; оскільки порядок аргументації не дуже інтуїтивний ...
Кріс Мейс

15
Між цим і git log -p, я думаю, -pпрапор повинен означати "роби класну річ, яку я хочу, але не знаю, як висловити".
Кайл Странд

2
чому на землі ця велика відповідь знаходиться на 12-й позиції ?? після всіх тих 0, +1, +2 відповідей ??????
ДенисФЛАШ

547

Оскільки git в основному полягає в управлінні усім вмістом та індексом сховища (а не одним або кількома файлами) git stash, не дивно,з усім робочим каталогом.

Насправді, оскільки Git 2.13 (Q2 2017), ви можете зберігати окремі файли, використовуючи git stash push:

git stash push [--] [<pathspec>...]

Коли pathspecзадано ' git stash push', новий сховище записує змінені стани лише для файлів, які відповідають шляху проспекту. Докладніше див. У статті " Сховання змін до конкретних файлів ".

Спрощений приклад:

 git stash push path/to/file

У тестовому випадку для цієї функції вимкнено ще кілька варіантів:

test_expect_success 'stash with multiple pathspec arguments' '
    >foo &&
    >bar &&
    >extra &&
    git add foo bar extra &&

    git stash push -- foo bar &&   

    test_path_is_missing bar &&
    test_path_is_missing foo &&
    test_path_is_file extra &&

    git stash pop &&
    test_path_is_file foo &&
    test_path_is_file bar &&
    test_path_is_file extra

Оригінальна відповідь (нижче, червень 2010 р.) Стосувалася вибору вручну того, що потрібно зберігати.

Коментарі Casebash :

Це ( stash --patchоригінальне рішення) приємно, але часто я змінював багато файлів, тому використання патча дратує

bukzor «s відповідь (upvoted, листопад 2011) пропонує більш практичне рішення, засноване на
git add+git stash --keep-index .
Іди подивись та підтверди його відповідь, яка повинна бути офіційною (замість моєї).

Щодо цього варіанту, chhh вказує альтернативний робочий процес у коментарях:

вам слід " git reset --soft" після такої скринінгу, щоб отримати чіткий показ сценарію:
Для того, щоб дійти до початкового стану - це чітка область постановки та лише з деякими вибраними нестадійними модифікаціями, можна м'яко скинути індекс, щоб отримати (без вчинив щось подібне до вас - букзор - зробив).


(Оригінальна відповідь червень 2010 року: приховування вручну)

Тим git stash save --patchне менш, може дозволити вам досягти часткового перегляду, який ви шукаєте:

За допомогою цього --patchви можете інтерактивно вибирати луки в різниці між ГОЛОВОЮ та робочим деревом, яке потрібно приховати.
Запис у сховищі побудований таким чином, що його стан індексу такий самий, як стан індексу вашого сховища, а його робоче дерево містить лише ті зміни, які ви вибрали інтерактивно. Вибрані зміни потім повертаються з робочого дерева.

Однак це збереже повний індекс (який може бути не тим, що ви хочете, оскільки він може включати інші файли, вже індексовані), і часткове робоче дерево (яке може виглядати як той, який ви хочете зберігати).

git stash --patch --no-keep-index

може бути більш підходящим.


Якщо --patchне працює, ручний процес може:

Для одного або декількох файлів проміжним рішенням буде:

  • скопіюйте їх поза Git repo
    (насправді, eleotlecram пропонує цікаву альтернативу )
  • git stash
  • скопіюйте їх назад
  • git stash # цього часу зберігаються лише потрібні файли
  • git stash pop stash@{1} # повторно застосувати всі свої модифікації файлів
  • git checkout -- afile # скиньте файл до вмісту HEAD перед будь-якими локальними модифікаціями

В кінці цього досить громіздкого процесу у вас буде збережено лише один або кілька файлів.


3
Це добре, але часто я змінював багато файлів, тому використання патча дратує
Casebash

6
@VonC: Це гарний стиль мати лише одну відповідь на відповідь. Крім того, скопіювати відповіді інших у себе - це погані манери.
bukzor

3
@bukzor: Мені шкода, якщо моя відредагована відповідь видалася неправильною. Мій єдиний намір полягав у тому, щоб надати Вашій відповіді більше наочності. Я знову відредагував свою посаду, щоб зробити цей намір яснішим.
VonC

1
@Kal: правда, stackoverflow.com/a/13941132/6309 передбачає git reset(змішаний)
VonC

3
git is fundamentally about managing a all repository content and index and not one or several files- це реалізація, що затьмарює вирішувану проблему; це пояснення, але не виправдання. Будь-яка система управління джерелом ВІДЧИВАЄ "управління кількома файлами". Подивіться, які коментарі найбільше отримують перевагу
Віктор Сергієнко

90

Коли git stash -p(або git add -pз stash --keep-index) буде занадто громіздко, мені стало простіше у використанні diff, checkoutі apply:

Щоб "сховати" певний файл / dir:

git diff path/to/dir > stashed.diff
git checkout path/to/dir

Потім після цього

git apply stashed.diff

1
Цікава альтернатива тому, про що git add -pя згадував у власній відповіді вище. +1.
VonC

11
Зауважте, що якщо у вас є двійкові файли (наприклад, PNG), вони не будуть виводитись у файл diff. Тож це не 100% рішення.
void.pointer

1
@RobertDailey: Це цікавий момент для мене, як git diff > file.diffі git applyє моїми звичайними інструментами часткового сховання. Можливо, доведеться розглянути можливість переходу на git stash -pбільші набори змін.
thekingoftruth

1
@thekingoftruth Ось псевдонім я використовую для створення файлів виправлень, і це робить підтримку бінарні файли: patch = log --pretty=email --patch-with-stat --reverse --full-index --binary. Однак зауважте, що для зміни виправлення потрібні зміни.
void.pointer

2
Це не працювало для мене чисто, якщо файл для зберігання був чимось на зразок ../../foo/bar.txt. Патч генерує ОК, але мені потім потрібно перейти до кореня сховища, щоб отримати патч для застосування. Тож якщо у вас виникають проблеми з цим - просто переконайтеся, що ви робите це з кореневого каталогу репозиторію.
Майкл Андерсон

86

Використовуйте git stash pushтак:

git stash push [--] [<pathspec>...]

Наприклад:

git stash push -- my/file.sh

Це доступно з Git 2.13, випущеного навесні 2017 року.


1
Але я git stash pushвже згадую у своїй відповіді вище, березня, 5 місяців тому. І я детально розповів тут нову команду Git 2.13: stackoverflow.com/a/42963606/6309 .
VonC

Я щасливий, що Git просувається так швидко, тривалий час це було неможливо, і тоді 2.13 виходить і раптом є просте рішення!
пісок

1
@VonC ти маєш рацію, ти також згадуєш правильну відповідь, однак між двома відповідями ця легка для читання (без заплутаного тексту і є також приклад). Можливо, вони мали б замість цього відредагувати Вашу відповідь
Utopik

@Utopik Ви мали мене на "ви праві" ... але так, я змінив свою відповідь, щоб включити приклад.
VonC

Чи використовується потім git stash applyдля відновлення прихованих змін?
Чад

49

Скажімо, у вас є 3 файли

a.rb
b.rb
c.rb

і ви хочете зберігати лише b.rb і c.rb, але не a.rb

ви можете зробити щось подібне

# commit the files temporarily you don't want to stash
git add a.rb
git commit -m "temp" 

# then stash the other files
git stash save "stash message"

# then undo the previous temp commit
git reset --soft HEAD^
git reset

І ви зробили! HTH.


29

Ще один спосіб зробити це:

# Save everything
git stash 

# Re-apply everything, but keep the stash
git stash apply

git checkout <"files you don't want in your stash">

# Save only the things you wanted saved
git stash

# Re-apply the original state and drop it from your stash
git stash apply stash@{1}
git stash drop stash@{1}

git checkout <"files you put in your stash">

Я придумав це після того, як я (ще раз) зайшов на цю сторінку і мені не сподобалися перші два відповіді (перша відповідь просто не відповідає на питання, і мені не дуже подобалось працювати з -pінтерактивним режимом).

Ідея така ж, як і @VonC запропонував використовувати файли поза сховищем, ви зберігаєте десь потрібні зміни, видаляєте зміни, які ви не хочете, у своєму сховищі, а потім повторно застосовуєте зміни, які ви перемістили з шляху. Однак я використав git stash як "десь" (і як результат, є ще один додатковий крок у кінці: вилучення cahnges, які ви помістили в копію, тому що ви також перемістили їх із шляху).


1
Я найбільше віддаю перевагу такому підходу. Він забезпечує легкий робочий процес у tortoisegit, використовуючи лише команди приховування та повернення.
Марк Ч.

Посилатися на відповіді на SO, використовуючи позиції, не рекомендується. Позиції змінюються по мірі зміни рейтингів.
Брайан Еш,

2
@BryanAsh Ну, це не так, як це має значення тут. Я даю анекдот, а не справді посилаюся на інші відповіді. Повідомлення полягає в тому, що мені не сподобалися відповіді, які сподобалися громаді, а не те, що ці відповіді насправді містять. Крім того, розрив у 900 голосів між другою та третьою відповіддю робить це малоймовірним для зміни у найближчому майбутньому, і якщо він коли-небудь зміниться, я завжди можу його відредагувати, щоб сказати "верх на відповіді в той час". Дійсно, я не бачу, як це якась проблема в цій ситуації.
Джаспер

23

Оновлення (14.02.2015) - я трохи переписав сценарій, щоб краще впоратися із випадками конфліктів, які тепер мають бути подані як конфлікти, що не вмикаються, а не файли .rej.


Мені часто буває більш інтуїтивно зрозуміти зворотний підхід @ bukzor. Тобто провести деякі зміни, а потім сховати лише ті поетапні зміни.

На жаль, git не пропонує приховування git - тільки-індекс або подібне, тому я скопіював сценарій для цього.

#!/bin/sh

# first, go to the root of the git repo
cd `git rev-parse --show-toplevel`

# create a commit with only the stuff in staging
INDEXTREE=`git write-tree`
INDEXCOMMIT=`echo "" | git commit-tree $INDEXTREE -p HEAD`

# create a child commit with the changes in the working tree
git add -A
WORKINGTREE=`git write-tree`
WORKINGCOMMIT=`echo "" | git commit-tree $WORKINGTREE -p $INDEXCOMMIT`

# get back to a clean state with no changes, staged or otherwise
git reset -q --hard

# Cherry-pick the index changes back to the index, and stash.
# This cherry-pick is guaranteed to succeed
git cherry-pick -n $INDEXCOMMIT
git stash

# Now cherry-pick the working tree changes. This cherry-pick may fail
# due to conflicts
git cherry-pick -n $WORKINGCOMMIT

CONFLICTS=`git ls-files -u`
if test -z "$CONFLICTS"; then
    # If there are no conflicts, it's safe to reset, so that
    # any previously unstaged changes remain unstaged
    #
    # However, if there are conflicts, then we don't want to reset the files
    # and lose the merge/conflict info.
    git reset -q
fi

Ви можете зберегти вищезазначений скрипт як git-stash-indexдесь на своєму шляху, а потім можете викликати його як git stash-index

# <hack hack hack>
git add <files that you want to stash>
git stash-index

Тепер скринька містить новий запис, який містить лише зміни, які ви інсценували, а ваше робоче дерево все ще містить незмінені зміни.

У деяких випадках зміни робочого дерева можуть залежати від змін індексу, тому коли ви зберігаєте зміни індексу, зміни робочого дерева мають конфлікт. У цьому випадку у вас вийдуть звичайні незмінені конфлікти, які ви можете вирішити за допомогою git merge / git mergetool / тощо.


Рекомендуйте pushdзамість cdі popdв кінці сценарію, тому якщо сценарій успішний, користувач опиняється в тому ж каталозі, що і до запуску.
Нейт

1
@Nate: наскільки я знаю, він повинен змінити каталог для користувача лише у тому випадку, коли вони знайшли сценарій. Якщо сценарій запускається нормально (~ / bin / git-stash-index) або через git (git stash-index), він запускається в окремому сеансі терміналу, і будь-які зміни робочого каталогу в цьому сеансі не впливають на робочий каталог у термінальному сеансі користувача. Чи знаєте ви про поширений випадок використання, коли це не відповідає дійсності? (окрім пошуку сценарію, який я б не вважав "загальним")
JesusFreke

20

Якщо ви не хочете вказувати повідомлення з прихованими змінами, передайте ім'я файлу після подвійного тире.

$ git stash -- filename.ext

Якщо це файл без відстеження / новий файл, вам доведеться спершу встановити його.

Цей метод працює у версіях git 2.13+


Ця відповідь є багатослівною, це стисло. Якщо хтось допоможе, я його залишу. Ніхто на цій сторінці не згадує про цей синтаксис і результат - вони замість цього згадують "git stash push".
морський лоток

Це відповідь, яку я шукав. Дякую! +1
nicodp

19

Оскільки створення гілок у Git тривіально, ви можете просто створити тимчасову гілку та перевірити в ній окремі файли.


2
Ви не можете створити гілку з нестандартними правками. Ви можете легко перемістити всі зміни до нової гілки (скринька / скринька), але потім повернетесь до прямої: як ви протестуєте гілку лише з деякими з цих змін, не втрачаючи інших?
bukzor

7
Ви не можете перемикати гілки, якщо у вас є місцеві зміни. Однак ви можете створити нову гілку і вибірково додавати / вводити файли, а потім створювати іншу гілку і робити те саме рекурсивно ... потім перевіряти оригінальну гілку і вибірково об'єднуватися назад. Я щойно це зробив. Насправді це здається природним способом робити речі, оскільки ви по суті створюєте гілки функцій.
Іен

3
@iain ви можете перемикати гілки, якщо у вас є місцеві зміни, якщо вони не потребують об'єднання. Див. Приклад суті . Це стосується як мінімум Git v2.7.0.
Колін Д Беннетт

18

Ви можете просто зробити це:

git stash push "filename"

або з додатковим повідомленням

git stash push -m "Some message" "filename"

1
Це не додає нічого нового. Git stash push вже згадується у кількох відповідях
JesusFreke

12

Збережіть наступний код у файлі, наприклад, з ім'ям stash. Використання є stash <filename_regex>. Аргумент - регулярний вираз для повного шляху файлу. Наприклад, для зберігання a / b / c.txt stash a/b/c.txtабо stash .*/c.txtтощо

$ chmod +x stash
$ stash .*.xml
$ stash xyz.xml

Код для копіювання у файл:

#! /usr/bin/expect --
log_user 0
set filename_regexp [lindex $argv 0]

spawn git stash -p

for {} 1 {} {
  expect {
    -re "diff --git a/($filename_regexp) " {
      set filename $expect_out(1,string)
    }
    "diff --git a/" {
      set filename ""
    }
    "Stash this hunk " {
      if {$filename == ""} {
        send "n\n"
      } else {
        send "a\n"
        send_user "$filename\n"
      }
    }
    "Stash deletion " {
      send "n\n"
    }
    eof {
      exit
    }
  }
}

2
Чудовий метод. Я б вибрав це як відповідь. Порада для майбутніх читачів: вам доведеться відповідати повним шляхом. наприклад, stash subdir / foo.c
er0

12

На всякий випадок, якщо ви дійсно маєте на увазі відмінити зміни кожного разу, коли ви користуєтесь git stash(і не використовуйте Git Stash, щоб тимчасово їх зберігати ), у такому випадку ви можете використовувати

git checkout -- <file>

[ ПРИМІТКА ]

Це git stashпросто швидша та проста альтернатива розгалуженню та роботі.


8

Проблема з «проміжним» рішенням VonC щодо копіювання файлів за межами Git repo полягає в тому, що ви втрачаєте інформацію про шлях, через що пізніше копіювати купу файлів можна дещо без проблем.

Знайдіть простіше використовувати tar (замість копії, можливо, подібні інструменти) замість копії:

  • tar cvf /tmp/stash.tar шлях / до / деякий / шлях до файлу / до / деякий / інший / файл (... тощо)
  • git checkout path / до / деякого / шляху до файлу / до / деякого / іншого / файлу
  • git stash
  • tar xvf /tmp/stash.tar
  • тощо (див. "проміжну пропозицію" VonC)

checkout -fне потрібно, checkout(без -f) достатньо, я оновив відповідь.
eleotlecram

8

Іноді я вносив незв'язані зміни до своєї гілки, перш ніж це здійснив, і хочу перенести її в іншу гілку і зробити її окремо (наприклад, головним). Я роблю це:

git stash
git checkout master
git stash pop
git add <files that you want to commit>
git commit -m 'Minor feature'
git stash
git checkout topic1
git stash pop
...<resume work>...

Зверніть увагу, що перші stashта stash popможуть бути усунені, ви можете перенести всі свої зміни у masterвідділення під час оформлення замовлення, але тільки якщо немає конфліктів. Крім того, якщо ви створюєте нову гілку для часткових змін, вам знадобиться скрипка.

Ви можете спростити його, якщо немає конфліктів та немає нової гілки:

git checkout master
git add <files that you want to commit>
git commit -m 'Minor feature'
git checkout topic1
...<resume work>...

Стек навіть не потрібен ...


8

Це легко зробити в 3 етапи за допомогою SourceTree.

  1. Тимчасово виконайте все, що ви не хочете сховати
  2. Git додайте все інше, а потім приберіть їх.
  3. Розмістіть тимчасову фіксацію, виконавши скидання git, націлюючи її на тимчасовий.

Це все можна зробити за лічені секунди в SourceTree, де ви можете просто натиснути на файли (або навіть окремі рядки), які ви хочете додати. Після додавання просто докладіть їх до тимчасового. Далі встановіть прапорець, щоб додати всі зміни, а потім натисніть приховати, щоб усе приховати. Коли приховані зміни перешкоджають перегляду, перегляньте свій список фіксування та відзначте хеш для фіксації перед тимчасовою фіксацією, а потім запустіть "git reset hash_b4_temp_commit", що в основному нагадує "вискакування" комісії шляхом перезавантаження вашої гілки на вчинити прямо перед цим. Тепер вам залишаються лише речі, які ви не хотіли приховувати.


8

Я б користувався git stash save --patch. Я не вважаю інтерактивність прикрою, оскільки під час неї є варіанти застосувати потрібну операцію до всіх файлів.


3
Вражений, що так мало підстав для цієї відповіді, що це найкраще рішення, не потребуючи есе.
robstarbuck

Однозначно хороша відповідь git stash -pдозволяє швидко зберігати цілий файл і після цього залишати його.
Річард Даллі

7

Кожна відповідь тут така складна ...

Що з цього приводу "приховувати":

git diff /dir/to/file/file_to_stash > /tmp/stash.patch
git checkout -- /dir/to/file/file_to_stash

Це, щоб відкрити зміну файлу назад:

git apply /tmp/stash.patch

Точна поведінка, як зберігання одного файлу та вивільнення його назад.


Я спробував це, але нічого не відбувається. Коли я git applyне маю жодної помилки, але зміни також не повертаються
ClementWalter

Файл виправлення, який ви створили в / tmp, ймовірно видалено. Можливо, ви перезавантажилися між різницею та застосувати. Спробуйте ще одне постійне місцеположення. Це дійсно працює. Також перевірте вміст файлу патчів.
Крістоф Фондчічі

4

Я переглянув відповіді та коментарі до цього та низку подібних тем. Майте на увазі, що жодна з наведених нижче команд не є правильною для того, щоб мати змогу зберігати будь-які конкретні відслідковувані / відслідковувані файли :

  • git stash -p (--patch): вибирайте перемикання вручну, виключаючи незатребувані файли
  • git stash -k (--keep-index): зберігайте всі відслідковані / відслідковувані файли та зберігайте їх у робочому каталозі
  • git stash -u (--include-untracked): зберігає всі відстежені / відслідковувані файли
  • git stash -p (--patch) -u (--include-untracked): недійсна команда

В даний час найбільш розумним методом, щоб можна було зберігати будь-які конкретні відслідковувані / відслідковувані файли, є:

  • Тимчасово закріпіть файли, які ви не хочете зберігати
  • Додайте та зберігайте
  • Виконайте тимчасову комісію

Я написав простий скрипт для цієї процедури у відповідь на інше питання , і тут є кроки для виконання процедури в SourceTree .


4

Рішення

Місцеві зміни:

  • file_A (модифікований) не інсценовано
  • file_B (модифікований) не інсценовано
  • file_C (модифікований) не інсценовано

Щоб створити скриньку "my_stash" лише із змінами у file_C :

1. git add file_C
2. git stash save --keep-index temp_stash
3. git stash save my_stash
4. git stash pop stash@#{1}

Зроблено.


Пояснення

  1. додайте файл_C до області постановки
  2. створити тимчасовий сховище з назвою "temp_stash" та зберегти зміни у file_C
  3. створіть потрібний скрипт ("my_stash") лише із змінами у file_C
  4. застосуйте зміни до "temp_stash" (file_A та file_B) у вашому локальному коді та видаліть скриньку

Ви можете використовувати статус git між кроками, щоб побачити, що відбувається.


3

Коли ви намагаєтесь перемикатися між двома гілками, така ситуація виникає.

Спробуйте додати файли за допомогою " git add filepath".

Пізніше виконати цей рядок

git stash --keep-index


3

Для зберігання одного файлу використовуйте git stash --patch [file].

Це буде карта: Stash this hunk [y,n,q,a,d,j,J,g,/,e,?]? ?. Просто введіть a(збережіть цю частину та всі пізніші записки у файлі), і ви все добре.


Відсутній pushяк уgit stash push --patch [file]
Філіпе Есперандіо

@FilipeEsperandio pushпрацює лише в останніх версіях Git, які раніше були save. У будь-якому випадку pushабо saveмаються на увазі під викликом stash: "Виклик git stash без будь-яких аргументів еквівалентно git stash push", документи
патрік

2

Схожа ситуація. Зробив і зрозумів, що це не нормально.

git commit -a -m "message"
git log -p

На основі відповідей це мені допомогло.

# revert to previous state, keeping the files changed
git reset HEAD~
#make sure it's ok
git diff
git status
#revert the file we don't want to be within the commit
git checkout specs/nagios/nagios.spec
#make sure it's ok
git status
git diff
#now go ahead with commit
git commit -a -m "same|new message"
#eventually push tu remote
git push

2

У цій ситуації я git add -p(інтерактивна), git commit -m blahа потім приховую те, що залишилося, якщо потрібно.


2

Я не знаю, як це зробити в командному рядку, лише використовуючи SourceTree. Скажімо, ви змінили файл A та маєте два файли змін у файлі B. Якщо ви хочете зберегти лише другу частину у файлі B, а все інше залишити недоторканим, зробіть це:

  1. Поставити все
  2. Виконайте зміни у своїй робочій копії, які скасують усі зміни у файлі А. (наприклад, запустіть зовнішній інструмент різниці та зрівняйте файли.)
  3. Зробіть так, щоб файл B виглядав так, ніби до нього застосована лише друга зміна. (наприклад, запустіть зовнішній інструмент різниці та скасуйте першу зміну.)
  4. Створіть скриньку, використовуючи "Зберігати поетапні зміни".
  5. Нестабільне все
  6. Готово!

2
git add .                           //stage all the files
git reset <pathToFileWillBeStashed> //unstage file which will be stashed
git stash                           //stash the file(s)
git reset .                         // unstage all staged files
git stash pop                       // unstash file(s)

1
Ну, не варто цього робити. Відповідь повинен забезпечити вирішення питання. Ви можете просто задати власне запитання.
L_J

це рішення є однією з найпростіших відповідей на ЦЕ питання. читайте питання, порівнюйте всі відповіді і мої відповіді, то якщо ви сумніваєтесь, що ця відповідь не є застосовним рішенням або недостатньою інформацією про це, ми можемо поговорити ще раз.
celikz

Це не спрацює, оскільки третя команда "git stash" не вшановуватиме поетапні файли. І поетапні, і нестандартні файли перейдуть у сховище. Питання конкретно запитують, як
зберігати

0

Одним із складних способів було б спочатку зробити все:

git add -u
git commit // creates commit with sha-1 A

Скиньте назад до початкового комітету, але перевірте the_one_file з нового комітету:

git reset --hard HEAD^
git checkout A path/to/the_one_file

Тепер ви можете зберігати the_one_file:

git stash

Очищення, зберігаючи закріплений вміст у вашій файловій системі, скидаючи назад до початкового файлу:

git reset --hard A
git reset --soft HEAD^

Так, трохи незручно ...


0

Я не знайшов відповіді як те, що мені потрібно, і це так просто, як:

git add -A
git reset HEAD fileThatYouWantToStash
git commit -m "committing all but one file"
git stash

Це зберігає рівно один файл.


0

Швидкий відповідь


Щоб відновити певний змінений файл у git, ви можете виконати наступний рядок:

git checkout <branch-name> -- <file-path>

Ось фактичний приклад:

git checkout master -- battery_monitoring/msg_passing.py


0

Якщо ви хочете сховати деякі змінені файли, просто просто

Додайте файли, які не хочете зберігати, у " Етап" , а потім виконайтеgit stash save --keep-index

Він зберігає всі нестандартні змінені файли

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.