Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/git/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Git 撤消从上一次提交中删除文件_Git_Version Control_Git Rewrite History - Fatal编程技术网

Git 撤消从上一次提交中删除文件

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

我正在使用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
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