Git 撤消从上一次提交中删除文件
我正在使用gitflow分支模型进行开发。 我已经从Git 撤消从上一次提交中删除文件,git,version-control,git-rewrite-history,Git,Version Control,Git Rewrite History,我正在使用gitflow分支模型进行开发。 我已经从develope扩展到feature/X,在feature/X的第一次提交中,我还删除了一些文件(使用git rm)。 现在,在该分支中进行了几次其他提交之后,我意识到我需要先前删除的文件 这里有一个简短的示例来说明我的澄清意思: git flow init -d echo "file contents" > file.txt git commit -m "Added file.txt" git checkout -b feature/X
develope
扩展到feature/X
,在feature/X
的第一次提交中,我还删除了一些文件(使用git rm
)。
现在,在该分支中进行了几次其他提交之后,我意识到我需要先前删除的文件
这里有一个简短的示例来说明我的澄清意思:
git flow init -d
echo "file contents" > file.txt
git commit -m "Added file.txt"
git checkout -b feature/X
git rm file.txt
echo "foo" > foo.txt
git add --all
git commit -m "Deleted file.txt and added another file"
<some more commits in feature/X>
git log -u
...
commit 04948fc4fc36d83901a0862b057657f3ccb9cf0d
Author: <...>
Date: Wed Aug 10 12:26:58 2016 +0200
Deleted file.txt and added another file
diff --git a/file.txt b/file.txt
deleted file mode 100644
index d03e242..0000000
--- a/file.txt
+++ /dev/null
@@ -1 +0,0 @@
-file contents
diff --git a/foo.txt b/foo.txt
new file mode 100644
index 0000000..257cc56
--- /dev/null
+++ b/foo.txt
@@ -0,0 +1 @@
+foo
...
git流初始化-d
echo“文件内容”>file.txt
git commit-m“Added file.txt”
git签出-b功能/X
git rm file.txt
echo“foo”>foo.txt
git add--all
git commit-m“删除了file.txt并添加了另一个文件”
git日志-u
...
提交04948fc4fc36d83901a0862b057657f3ccb9cf0d
作者:
日期:星期三8月10日12:26:58 2016+0200
删除file.txt并添加另一个文件
diff——git a/file.txt b/file.txt
已删除文件模式100644
索引d03e242..0000000
---a/file.txt
+++/dev/null
@@ -1 +0,0 @@
-文件内容
diff——git a/foo.txt b/foo.txt
新文件模式100644
索引0000000..257cc56
---/dev/null
+++b/foo.txt
@@ -0,0 +1 @@
+福
...
我不想在新提交中重新添加文件,以避免在将feature/X
合并到develope
时出现问题,而develope
分支中的file.txt
有一些更改
有没有办法从先前的提交中删除file.txt
我已经尝试了git reset file.txt
,但是没有将文件恢复到我的工作副本中
编辑1:我知道重写历史的负面影响,而这已经被推到了遥远的地方。然而,我知道除了我之外,没有人在
功能/X上做过任何提交,因此我应该可以安全地重写历史记录,尽管它已经被推送了。Git不是SVN,我认为只要在新提交中重新添加该文件就不会有任何问题。
与SVN不同,Git不跟踪文件,它跟踪碰巧存储在文件中的内容。
如果在SVN中删除并重新添加文件,则它们的历史记录不会连接,但它们是SVN的不同文件
如果在Git中删除并重新添加一个文件,那么删除并重新添加的只是内容,所以合并应该可以正常工作。重新基础可能会有问题,因为提交会一个接一个地应用于新的基本提交,因此会出现编辑/删除冲突。但是在合并时,只应将已完成的更改作为一个整体应用,因此不会出现任何问题。您现在拥有的是某个分支上的一系列提交:
...--o--*--B1--B2--B3 <-- branch
现在,您可以复制第二次提交,B2
。如果有您不想要的删除,请使用相同的三部分序列(cherry pick-n
,checkout
,commit
)。如果没有问题,请省去-n
,只需复制并提交:
...--o--*--B1--B2--B3 <-- branch
\
G1--G2 <-- new branch [new copies being made]
我会成功的。如果返回的步骤较多或较少,则需要调整波浪号~
字符后的数字
请注意,无论您做什么,都将获得原始提交的副本。另外,git-rebase
通常在复制时删除合并提交。这两种情况都意味着,如果您已经向其他人提供了这些提交(通过git push
或类似方式),或者如果您在第一次错误提交后进行了合并,并且打算“替换”(实际上,复制,然后忽略原件),则必须谨慎
1事实上,git-rebase
有时确实会运行git-cherry-pick
。其他时候,它使用的是几乎相同的其他东西。根据重写功能/X
分支的历史记录是否安全,有几种方法可以恢复该文件
选项1:在新提交中还原文件
如果您已经推送了提交,最简单的方法就是从删除它的提交的父级检索foo.txt
文件,然后再次提交
例如,假设删除文件的提交的SHA-1是123abc
:
git checkout feature/X
git checkout 123abc^ path/to/file.txt
git add path/to/file.txt
git commit -m "Restore the file.txt file"
选项2:恢复原始提交中的文件
另一方面,如果您尚未推送这些提交,则可以安全地重写本地feature/X
分支的历史,以撤消对该文件的删除。为了做到这一点,您必须执行并编辑删除文件的提交:
git checkout feature/X
git rebase -i 123abc^
在todo列表中,将提交左侧的单词从pick
更改为edit
;然后保存文件并退出
Git到达要编辑的提交后,您可以通过以下方式还原已删除的文件:
git checkout HEAD^ path/to/file.txt
git add path/to/file.txt
git commit --amend -C HEAD # where -C HEAD reuses the commit message of HEAD
然后用以下方法完成重基:
git rebase --continue
答复
我不想在新提交中重新添加该文件,以避免在将feature/X合并到development时出现问题,同时development分支中的file.txt中也有一些更改
是的,您确实希望在新提交中重新添加该文件。git在这方面是明智的(事实上,这里没有特殊的智能,它只是来自git处理文件的方式)
例子
git init test#init a repos,create test.txt
cd试验
echo start>test.txt
git-add-A;git提交-m'x'
git checkout-b bra#创建分支,添加一行
echo line1>>test.txt
git-add-A;git提交-m'x'
git rm test.txt#删除文件+提交
git提交-m“x”
echo start>test.txt#恢复文件并添加一行
echo line2>>test.txt
git-add-A;git提交-m'x'
git checkout master#返回master,添加同一行和另一行
echo line2>>test.txt
echo line3>>test.txt
git-add-A;git提交-m'x'
git merge bra#merge
cat test.txt
开始
第2行
>胸罩
冲突正如所料(原文如此!);重要的是,line2
不是冲突的一部分git merge
并不关心所有
git checkout HEAD^ path/to/file.txt
git add path/to/file.txt
git commit --amend -C HEAD # where -C HEAD reuses the commit message of HEAD
git rebase --continue
git init test # init a repos, create test.txt
cd test
echo start > test.txt
git add -A ; git commit -m 'x'
git checkout -b bra # create branch, add a line
echo line1 >> test.txt
git add -A ; git commit -m 'x'
git rm test.txt # delete file + commit
git commit -m "x"
echo start > test.txt # restore file and add a line
echo line2 >> test.txt
git add -A ; git commit -m 'x'
git checkout master # back to master, add the same line and another one
echo line2 >> test.txt
echo line3 >> test.txt
git add -A ; git commit -m 'x'
git merge bra # merge
cat test.txt
start
line2
<<<<<<< HEAD
line3
=======
>>>>>>> bra