Git. Как откатить изменения в определенном файле в цепочке коммитов? - PullRequest
0 голосов
/ 28 мая 2019

У меня есть репо с тремя файлами: 1.txt, 2.txt и 3.txt.Я создал ветку 'new_branch' и сделал коммиты (назовем их A, B и C), каждый из этих коммитов содержит изменения в нескольких файлах из моего репо.Тогда я понял, что 1.txt был обновлен по ошибке.Можно ли удалить изменения, сделанные в 1.txt, из коммитов A, B и C, но сохранить изменения в 2.txt и 3.txt?

UPD. Я хочу такжеудалить изменения, сделанные 1.txt, из истории коммитов.В результате 'git log -p' должен показать, что только 2.txt и 3.txt были изменены в коммитах A, B и C.

Большое спасибо.

Ответы [ 4 ]

2 голосов
/ 28 мая 2019

Предполагая, что ваше дерево редакций выглядит следующим образом:

-- S <s.sha> -- A -- B -- C (HEAD)

Вы можете использовать git filter-branch, чтобы удалить изменения из коммитов A..C, внесенных в один файл.

git filter-branch --tree-filter 'git checkout <s.sha> -- 1.txt' HEAD~3..

Это будет:

  • проверить каждый из трех последних коммитов,
  • запустить 'git checkout' для файла 1.txt, приведя его к нужной версии,
  • помещает измененные коммиты обратно в дерево.

Это, очевидно, переписывает историю, поэтому действуют те же соображения, что и для толкания перебазировки.

1 голос
/ 28 мая 2019

Вы можете попробовать проверить 1.txt при коммите перед коммитом A, первым коммитом, с которого вы начали вносить нежелательные изменения:

git checkout abc123 -- 1.txt

Это предполагает вашу структуру ветвлениявыглядит так (с коммитом S, имеющим хэш SHA-1 abc123):

S -- A -- B -- C

Затем просто добавьте изменения и зафиксируйте.

0 голосов
/ 28 мая 2019

Вот еще один не очень аккуратный способ [Решение, предоставленное Тимом, хотя лучше всего подходит к ситуации] -

При условии, что ваши топ-3 коммитов A, B, C, вы можете сделать git reset --soft HEAD~3. Все ваши изменения будут внесены в вашу область подготовки. Вы можете отключить 1.txt и зафиксировать остальные файлы.

Это приведет к изменению истории с коммитами A, B и C, которые будут заменены новым коммитом D, который будет иметь все изменения в A, B и C, за исключением файла 1.txt.

0 голосов
/ 28 мая 2019

git checkout <commit reference> <file> - это то, что вы ищете.

> git init
Initialized empty Git repository in /Users/ody/temp/git-co/.git/
> touch 1 2 3
> echo foo > 1 > 2 > 3
> git add 1 2 3
> git commit -m "foo"
[master (root-commit) 470f4e8] foo
 3 files changed, 3 insertions(+)
 create mode 100644 1
 create mode 100644 2
 create mode 100644 3
> echo bar > 1 > 2 > 3
> git add 1 2 3
> git commit -m "bar"  
[master 916819d] bar
 3 files changed, 3 insertions(+), 3 deletions(-)
> git checkout :/foo 1
> cat 1
foo

ПРИМЕЧАНИЕ : нотация :/ позволяет ссылаться на коммит по части его имени вместо хэша коммита.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...