У меня иногда возникает ситуация, когда забыл при коммите указать еще какой-либ
файл(-ы). Можно ли как-либо в последний коммит добавить файл(-ы) ?
В Mercurial я делаю так:
hg qinit
Преобразовываю коммит в патч
Обновляю патч
Преобразовываю патч в коммит
Возможно есть способ и для GIT ?
Ответы
Ответ 1
Да, для этого используется опция --amend.
Пример использования
Просмотрим историю коммитов.
$ git log
commit 5c4a8e76f951eb7ee157f4136257f6666fddf1d1
Author: John Doe
Date: Sun Aug 28 14:40:30 2016 +0300
Changed 1.txt
commit 7f2ad8c26ad032800c049d0d6122c43410a5cbbc
Author: John Doe
Date: Sun Aug 28 14:39:30 2016 +0300
Initial commit
Допустим существует файл который нужно добавить в предыдущий коммит.
$ git status
On branch master
Untracked files:
(use "git add ..." to include in what will be committed)
test.txt
Добавьте этот файл в индекс при помощи команды git add.
$ git add --all
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD ..." to unstage)
new file: test.txt
После этого вы можете добавить файл в последний коммит посредством
использования --amend в команде git commit. Вы можете также
изменить сообщение коммита добавив -m 'Commit message'. Чтобы
оставить сообщение коммита тем же просто передайте пустую строку
вместо сообщения -m ''.
$ git commit -m 'Added test' --amend
[master aad3e76] Added test
Date: Sun Aug 28 14:40:30 2016 +0300
2 files changed, 2 insertions(+), 1 deletion(-)
create mode 100644 test.txt
Проверим историю коммитов.
$ git log --stat
commit aad3e7653cd76c4afa1a9272bd421493b4e3055c
Author: John Doe
Date: Sun Aug 28 14:40:30 2016 +0300
Added test
1.txt | 3 ++-
test.txt | 0
2 files changed, 2 insertions(+), 1 deletion(-)
commit 7f2ad8c26ad032800c049d0d6122c43410a5cbbc
Author: John Doe
Date: Sun Aug 28 14:39:30 2016 +0300
Initial commit
1.txt | 1 +
1 file changed, 1 insertion(+)
Другие способы изменения истории
Для изменения истории коммитов можно использовать такие команды как git rebase
git filter-branch, но они используются в гораздо более сложных случаях. Например, если вы хотите изменить коммит который был сделан несколько коммитов назад, то можете использовать интерактивный rebase - git rebase -i.
Подробнее об изменении истории в git можно прочесть здесь.
P.S. Будьте осторожны, используя этот приём, потому что git commit --amend по сут
создает новый коммит, который включает изменения из коммита который вы меняете + добавленные изменения. Не правьте последний коммит, если вы его уже отправили в удаленный репозиторий.
Ответ 2
Важно: подразумевается, что ваш последний коммит ещё не был запушен,
потому что в командной работе не рекомендуется вносить изменения в
репозиторий через push -f. Об этом же был постскриптум @Volen.
Существует два способа, один уже описан выше @Volen, поэтому повторять не будут
второй вариант использует rebase. Что нужно сделать.
Есть коммит A, в который вы хотите добавить файл.
Вы создаёте коммит B, в который добавляете этот файл.
Потом вы даёте команду git rebase -i HEAD~2 и у коммита B заменяете pick на squash (можно просто букву s подставить)
Т.е. исходно вам покажет что-то типа:
[ak@hostname testfolder]$ git rebase -i HEAD~2
pick 7921448 Commit A
pick 8a84e59 Commit B
# Rebase ce97832..8a84e59 onto ce97832
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out
~
~
~
"~/testfolder/.git/rebase-merge/git-rebase-todo" 20L, 650C
Вам нужно влить коммит Б в А следующим образом:
pick 7921448 Commit A
s 8a84e59 Commit B
После сохранения будет окно в котором вам предложат выбрать имя нового, объединённого коммита:
Rebasing (2/2)
# This is a combination of 2 commits.
# The first commit's message is:
Commit A
# This is the 2nd commit message:
Commit B
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# HEAD detached at 7921448
# You are currently editing a commit while rebasing branch 'master' on 'ce97832'.
#
# Changes to be committed:
# (use "git reset HEAD^1 ..." to unstage)
#
# new file: file2
# new file: file3
#
~
~
".git/COMMIT_EDITMSG" 20L, 494C
Возможно, вам покажется, что способ через amend проще. Это действительно так.
Однако на базе rebase можно будет потом настолько широко модифицировать коммиты -
разбивать, объединять, переставлять местами -- что другие способы не идут ни в какое сравнение по функциональности.
Поэтому я люблю как раз показывать возможности с rebase именно с простых операций, а у вас как раз такая показательно простая.
PS Приводил пример из командной строки git, разумеется графические клиенты такж
умеют rebase -- например в SourceTree вы кликаете правое меню на предыдущем перед А коммитом и выбираете в контекстном меню пункт Rebase children interactively.
Ответ 3
Буду краток:
git add file.txt
git commit --amend
Если последний коммит перед этим уже заpushили на сервер, то следующий push придется делать с --force, чтоб переписать.
Ответ 4
Если на сервер еще не запушили, то можно отменить последний коммит git reset --soft HEAD^, добавить недостающий файл с помощью git add, повторить коммит снова.
git reset --soft HEAD^ # отменить последний коммит
git add filename
git status # видим зелёненькие файлики
git commit -m 'commit all files'
Более кратко:
amend cделает то же самое (добавит изменения в последний коммит):
git commit --amend
Комментариев нет:
Отправить комментарий