GIT: добавление локальных изменений в нерабочую ветвь
Мне обычно бывает, что я делаю некоторые локальные изменения, только чтобы обнаружить, что я сделал это на неправильной ветке, поэтому мне нужно переключить ветвь перед фиксацией. Проблема в том, что я не могу переключить ветвь, когда есть локальные изменения. Есть ли способ сделать это?
Очевидно, что я могу скопировать обновленные файлы, переключить ветвь, а затем скопировать их обратно, но это на самом деле не кажется умным!
Ответы
Ответ 1
Вы можете переключаться между ветвями, если у вас есть локальные модификации, если ваши локальные изменения не совпадают с различием между двумя ветвями. В этом случае вы можете использовать параметр -m
или --merge
для checkout
для выполнения проверки в любом случае и выполнить изменения слияния betwee и изменения, вызванные переключением ветвей.
git checkout -m other-branch
Ответ 2
Я использую git stash
, когда это произойдет. Он создает временную фиксацию текущего состояния рабочей копии (как кэшированных, так и незашифрованных файлов) и возвращает рабочую копию в текущую HEAD. Затем вы можете переключиться на другую ветку и сделать git stash pop
.
Ответ 3
Как сказано другим, вы можете использовать stash
или checkout --merge
. Однако этот параметр приведет к изменению временной метки некоторого файла. Если вы работаете над большим проектом, в котором компиляция может занять много времени (наш текущий проект занимает полчаса, чтобы скомпилировать с распределенными сборками), это может оказаться не оптимальным.
В этой ситуации вы можете использовать другой репозиторий для перемещения фиксации в правильную ветку. Во-первых, вам нужно клонировать ваш текущий репозиторий (это нужно сделать только один раз):
$ git clone /path/to/repository repository.clone
$ cd repository.clone
$ git remote add origin repository.clone
$ git fetch origin
Затем в вашем текущем репозитории вы совершаете свои изменения:
$ cd /path/to/repository
$ git add path/to/modified/files
$ git commit -m 'Commit message'
В другом репозитории вы извлекаете новую фиксацию и переместите ее в нужную ветку:
$ cd ../repository.clone
$ git fetch origin
$ git checkout correct-branch
$ git reset --hard origin/correct-branch
$ git cherry-pick origin/current-branch
$ # resolve conflicts if any, commit with -c option in this case
$ git push origin correct-branch:correct-branch
Затем в исходном репозитории вы удаляете временную фиксацию и удаляете связанную модификацию (за исключением случаев, когда вы хотите сохранить их в обеих ветвях).
$ cd /path/to/repository
$ git reset HEAD^
$ # edit file and remove modifications moved to other branch
Это сложнее и требует перезаписи истории, но когда ваш проект действительно большой, а время компиляции является ограничивающим фактором, может быть полезно знать технику. Обратите внимание, что вы можете повторно использовать клонированный репозиторий, поэтому нет необходимости каждый раз удалять/воссоздавать его (если время компиляции длинное, то репозиторий, вероятно, большой, а клонирование может занять некоторое время).