Если у вас есть изменения - т. Е. Грязное рабочее дерево - , вам нужно что-то зафиксировать .Самое большее, у вас есть что-то, что вы хотите временно временно .
В других системах контроля версий вы можете сделать это, зафиксировав это в ветке.В Git вы тоже можете сделать это: у вас нет для использования ветки, но это может быть и самый удобный способ справиться с этим и в Git.
Вы упомянулиначальный сценарий, для которого у меня есть рабочий шаблон, который я нахожу полезным:
Очень распространенный сценарий, возникающий, когда люди пишут код, состоит в том, чтобы принести себя (скажем, ветвь функций, над которой вы работаете)on) актуальный.
Допустим, вы работаете над feature-X
, который в конечном итоге будет помещен в dev
(ветка разработки).Другие разработчики работали над функциями Y и Z, и один из них завершен, и dev
теперь обновлен, поэтому вы запускаете:
$ git fetch
и видите, что ваш dev
теперь отстает от origin/dev
,То есть теперь у вас есть:
...--C--D--H <-- master
\
\ I--J <-- origin/dev
\ /
E--F--G <-- dev, feature-X (HEAD)
в вашем хранилище.У вас также есть некоторые вещи в вашем рабочем дереве, которые отличаются от файлов в коммите G
.(Возможно, у вас еще нет ветви с именем feature-X
, и вместо нее HEAD
присоединен к dev
. Если это так, вы можете просто создать его сейчас с помощью git checkout -b feature-X
, и теперь вы соответствуете изображению.)
На этом этапе нужно сделать то, над чем вы работаете.Это делает один новый коммит K
:
...--C--D--H <-- master
\
\ I--J <-- origin/dev
\ /
E--F--G <-- dev
\
K feature-X (HEAD)
Теперь вы можете перемотать свой собственный dev
до origin/dev
.Основной метод команды:
$ git checkout dev # safe, since your work is committed
$ git merge --ff-only origin/dev # or `git pull` if you really insist
Рисунок теперь выглядит так:
...--C--D--H <-- master
\
\
\
E--F--G--I--J <-- dev (HEAD), origin/dev
\
K <-- feature-X (HEAD)
Вот где большинство людей просто запускают git checkout feature-X; git rebase dev
, , что хорошо и вы должны смело использовать этот метод.(Я делаю это большую часть времени. Подумайте об этом, следуя описанному ниже приему git reset HEAD^
.) Но иногда я просто делаю переименовываю feature-X
в feature-X.0
, а затем создаю new feature-X
с git checkout -b feature-X
:
...--C--D--H <-- master
\
\
\
E--F--G--I--J <-- dev, origin/dev, feature-X (HEAD)
\
K <-- feature-X.0
Теперь я готов снова начать работу над feature-X
, и в этот момент я просто выбираю все feature-X.0
commitits:
$ git cherry-pick dev..feature-X.0
, который производит коммит K'
, который является копией K
:
...--C--D--H <-- master
\
\ K' <-- feature-X (HEAD)
\ /
E--F--G--I--J <-- dev, origin/dev
\
K <-- feature-X.0
Это работает, даже если на feature-X.0
есть несколько коммитов:
...--C--D--H <-- master
\
\ K'-L' <-- feature-X (HEAD)
\ /
E--F--G--I--J <-- dev, origin/dev
\
K--L <-- feature-X.0
Если последний коммит этого нового feature-X
(L'
в этой версии, K'
в том, который имел только один коммит), действительно, серьезно не-готов к принятию, на данный момент я просто использую git reset HEAD^
(можно записать HEAD~
, если это проще, как, очевидно, имеет место в Windows), чтобы переместить имя ветви на один шаг назад.Это удаляет самый последний коммит из текущей ветви, давая:
...--C--D--H <-- master
\
\ K' <-- feature-X (HEAD)
\ /
E--F--G--I--J <-- dev, origin/dev
\
K--L <-- feature-X.0
и оставляет «грязное» рабочее дерево таким же, каким оно было до того, как я начал весь этот процесс.(В общем, частичная фиксация - это хорошо, так как я буду использовать git rebase -i
позже, чтобы очистить все, когда feature-X
в основном готов.)
Если по какой-либо причине мне придется повторить процесс,Я переименовываю текущее состояние feature-X
в feature-X.1
, или feature-X.2
, или как угодно.Я выращиваю небольшую коллекцию feature-X
, и иногда выхожу в сад и обрезаю самых слабых. Самая последняя и самая лучшая версия по-прежнему называется feature-X
, но у меня есть все мои предыдущие работы, доступные по мере необходимости, до тех пор, пока я их не отсею. Это лучше, чем перебазировка или stash, потому что, если код сложный и я что-то пропустил, у меня все еще есть более старая версия под узнаваемым именем, а не просто какой-то непонятный хэш-идентификатор в журнале ссылок и не тайник, который неотличим от дюжины других тайников.