2013-07-08 2 views
3

У меня есть ветка, где я внес некоторые изменения в несколько файлов в несколько коммитов. Однажды, некоторое время назад, я начал выполнять некоторую работу над подмножеством этих файлов и проверил некоторые изменения. После этого мы решили, что эти файлы должны быть удалены как часть вещей, выполняемых в другой ветке. Таким образом, я хочу «отменить» эти файлы - они больше не имеют отношения к тому, что я делаю в своем филиале, и из-за этого я не хочу вызывать конфликты слияния с другими удаленными файлами.Отмена изменений в определенных файлах в старых коммитах, не оставляющая следов из них

Есть ли способ обновить коммит, который сделал эти изменения, чтобы оставить эти файлы нетронутыми, и за пределами истории моего филиала?

В более конкретном плане:

Рассмотрим следующий дерево исходного кода, в текущем состоянии:

src/A.java 
src/B.java 
src/C.java 
src/D.java 

Некоторые 10 совершает или назад, так в истории, коммит был сделан, что внесены изменения следующим образом:

M src/B.java 
M src/C.java 
A src/D.java 

есть ли способ я могу удалить изменения C.java из я История электронной, так что, когда вы смотрите на коммит над ней вместо выглядит

M src/B.java 
A src/D.java 

Как вы видите, он будет выглядеть так, что C.java никогда не трогали моей отрасли.

Я просмотрел git revert, но не смог найти способ сделать это, не создавая новую фиксацию, которая сбрасывает изменения, сделанные старым. Я знаю, что я мог бы также избежать конфликтов слияния, просто удалив файлы в моей ветке, но это похоже на «уродливое» решение, которое работает на этот раз, но, возможно, не следующее (что, если изменение в другой ветке не является удалением, но модификация?), поэтому, если есть более чистый способ, я бы хотел его изучить.

+0

Возможный дубликат [Git: лучший способ удалить все изменения из заданного файла для одного филиала] (http://stackoverflow.com/questions/9751928/git-best-way-to-remove-all-changes- from-a-given-file-for-one-branch) – RyPeck

ответ

1

Хотя the now deleted answer by RyPeck RyPeck linked to a good way of doing this using git filter-branch в комментариях, я решил по-другому, так что я думал, что я разделю, как я это сделал - если для каких-либо других целей, то в качестве основы для будущего меня (который неизбежно должен будет снова спросите в Интернете этот вопрос, возможно, скоро ...):

Во-первых, я сделал интерактивную перезагрузку, используя git rebase -i master. Это открыло мой текстовый редактор (я, случается, есть мерзавец, сконфигурированный, чтобы открыть Notepad ++) с файлом, подобный следующему:

pick First commit message 
pick Second commit message 
pick This is where I touched the files I didn't want to touch 
pick Another commit 
pick This goes on for a while 
pick I think you get the point 
pick I'll stop now 

следуют некоторые комментарии о том, как редактировать файл. То, что я сделал, заключалось в изменении линии с фиксацией, которую я хотел изменить на

... 
edit This is where I touched the files I didn't want to touch 
... 

, а затем сохранить и закрыть редактор.Что происходит тогда, что мерзавец применяет три первых фиксаций, затем останавливается и говорит

Stopped at <hash>... This is where I touched the files I didn't want to touch 
You can amend the commit now, with 

    git commit --amend 

Once you are satisfied with your changes, run 

    git rebase --continue 

Затем сбросить файлы в состоянии они были до этого совершить, используя что-то похожее на

git reset HEAD^ src/C.java # undoes the changes to the file 
git add src/C.java   # stages the undoing of the changes 
git commit --amend   # amends the undoing to the last commit 

После этого фиксация изменила файл дважды - сначала изменение, которое я сделал, а затем снова - и git сжал эти два набора изменений в один, в котором они отменяют и ничего не делают. Теперь я запускаю

git rebase --continue 

, чтобы закончить работу. Если я сейчас посмотрю на историю src/C.java, в этом наборе коммитов ничего нет.

Эта техника чрезвычайно гибкая - с использованием режима фиксации edit вы можете сделать любое изменение, которое вы хотите.

+1

Это было бы большой болью для большой истории проекта. Как раз для обсуждений, насколько это отличается от того, что заканчивается «git filter-branch»? – RyPeck

+0

@IamReck: Я не знаю. Я не нашел ответа, пока не сделал это, поэтому у меня не было возможности проверить 'git filter-branch' и посмотреть, что произойдет. Если у меня будет время, я могу проверить фиктивную ветвь и провести несколько тестов. –

+2

@IamReck: Кроме того, в отношении «большой истории проекта»: это определенно не то, что я рекомендовал бы делать в более крупном масштабе, или на все, что было распространено среди нескольких разработчиков. В моем случае я работал один, в подразделении функций, и решил, что некоторые изменения должны действительно быть в их филиале, поскольку они были частью другой функции. Таким образом, мои изменения были на локальной, неопубликованной ветке - такие истории ветвей (надеюсь) никогда не были бы слишком большими ... –