git 在提交之间移动文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18569931/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-19 08:59:56  来源:igfitidea点击:

Move files between commits

gitgit-commit

提问by Val

I have two consequential commits, somewhere in the local history, and one file was mistakenly added into the second. I want to fix the situation.

我有两个相应的提交,在本地历史的某个地方,一个文件被错误地添加到第二个文件中。我想解决这个问题。

I do not understand how should I use the interactive rebase. I did git rebase -i HEAD~10and choosen to edit the commit with file in order to check it out from there. I use git guit but, see no files in the commit area. I can choose to amend the previous commit then I see the files. But, I cannot add the misplaced file to that previous commit since I do not see the file in the current commit to start with.

我不明白我应该如何使用交互式 rebase。我做了git rebase -i HEAD~10并选择用文件编辑提交,以便从那里检出。我使用 git guit 但是,在提交区域中看不到任何文件。我可以选择修改以前的提交然后我看到文件。但是,我无法将放错位置的文件添加到之前的提交中,因为我在当前提交中没有看到该文件。

采纳答案by elmart

If I don't get it wrong, what you want is move some change that was included commit 2 to commit 1.

如果我没有弄错,您想要的是将包含提交 2 的一些更改移动到提交 1。

I find the easiest way to do that is doing two consecutive interactive rebases.

我发现最简单的方法是做两个连续的交互式变基。

In the first one, you split commit 2 into two commits: the first including just the change you want to move, and the second including all the rest. We have now commits 1, 2.1, and 2.2.

在第一个中,您将提交 2 分成两个提交:第一个只包含您要移动的更改,第二个包含所有其余的更改。我们现在提交了 1、2.1 和 2.2。

Then you rebase again, and this time choose to squash commit 2.1 into 1.

然后你再次变基,这次选择将提交 2.1 压缩为 1。

回答by dwarduk

So, when rebasing, choose to edit both the commit where you added the file by mistake, and the one you want to add it to in that order. If the file is in a later commit, but should be in an earlier one, you will have to reorder the lines. For example, I start with

因此,在重新定位时,请选择编辑您错误添加文件的提交,以及要按该顺序添加文件的提交。如果文件在较晚的提交中,但应该在较早的提交中,则您必须重新排列行。例如,我从

pick 8de731b Commit with missing file.
pick bbef925 Commit with too many files.
pick 52490ce More history.

I need to change it to

我需要把它改成

edit bbef925 Commit with too many files.
edit 8de731b Commit with missing file.
pick 52490ce More history.

Then,

然后,

# In the commit containing an extra file
git reset HEAD^ badfile.c
git commit --amend
git rebase --continue

# Now in the commit to add it to
git add badfile.c
git commit --amend
git rebase --continue

Unfortunately, when editing history in one branch, I don't know of any way to avoid editing history in all branches. Rebasing should be done as early as possible to avoid problems like this. In my simple case here, I can merge master and the other branch, but the commits don't merge, then I have to rebase in master, and reorder and squash the commits, like this:

不幸的是,在一个分支中编辑历史时,我不知道有什么方法可以避免在所有分支中编辑历史。应尽早进行重新定位,以避免出现此类问题。在我这里的简单情况下,我可以合并 master 和另一个分支,但提交不会合并,然后我必须在 master 中变基,并重新排序和压缩提交,如下所示:

pick 7cd915f Commit with missing file.
fixup 8de731b Commit with missing file. #This was the higher of the two entries
pick 8b92c5a Commit with too many files.
fixup bbef925 Commit with too many files. #This was the higher of the two entries
pick 94c3f7f More history.
fixup 52490ce More history. #This was the higher of the two entries

Late edit:I just noticed I was accidentally reordering the commit history as a carryover from my original answer. Swapping the lines in the rebase changes the order you commit; after editing, you can rebase again and swap them back to go back to the original commit order.

后期编辑:我刚刚注意到我不小心将提交历史重新排序为我原始答案的结转。交换 rebase 中的行会更改您提交的顺序;编辑后,您可以再次变基并将它们交换回原始提交顺序。

回答by Mikhail Golubtsov

As I often stumble upon this issue, I wrote a script for this. It works fully automatically. You can find it on Github. Copy it to the local filesystem, add it to PATH and you'll be able to run it as:

由于我经常偶然发现这个问题,因此我为此编写了一个脚本。它完全自动工作。你可以在Github上找到它。将其复制到本地文件系统,将其添加到 PATH 中,您将能够以以下方式运行它:

mv-changes <source-commit> <destination-commit> <path>...

You can also run the script in Git-Bash shell on Windows.

您还可以在 Windows 上的 Git-Bash shell 中运行该脚本。

Note that, if there are changes of <path>in intermediate commits between source-commitand destination-commit, it will not work.

请注意,如果<path>source-commit和之间的中间提交中有 的更改destination-commit,它将不起作用。

More details are provided here.

此处提供更多详细信息。

回答by jo_

First take info on short history

首先获取关于短史的信息

> git log --oneline -n 3 --decorate=short
333333  (HEAD -> work_AAA) added test              /*file is updated here*/
222222  corrected bug 
111111  (origin/master, origin/HEAD, master) version XXX 

so we can rebase and stop on commit 22222

所以我们可以重新设定并停止提交 22222

> git rebase -i master 
pick 22222 corected bug 
pick 33333 added test

change to :

改成 :

edit 22222 corected bug 
pick 33333 added test

then you will be in update mode in commit 22222 it shows something like this:

那么您将在提交 22222 中处于更新模式,它显示如下内容:

Stopped at 22222... corrected bug
You can amend the commit now, with
   git commit --amend 
Once you are satisfied with your changes, run
   git rebase --continue

here copy file from commit 3 to commit 2

这里将文件从提交 3 复制到提交 2

git show 33333:path/to/file  >  path/to/file

amend commit 2 and continue rebase

修改提交 2 并继续变基

git commit --amend --no-edit path/to/file
git rebase --continue

Done !

完毕 !

回答by Droidum

I had the same problem and want to explain what I did.

我遇到了同样的问题,想解释一下我做了什么。

In commit A I added a file f that I had to remove in the following commit B.

在提交 AI 中添加了一个文件 f,我必须在以下提交 B 中删除该文件。

Now I wanted to get rid of the file in both commits but also wanted to avoid splitting the commit because there were many other files involved. I did this

现在我想删除两个提交中的文件,但也想避免拆分提交,因为涉及许多其他文件。我做了这个

  • recover the file
  • add it again in commit ADD
  • remove it in commit REM - now there is the history A - B - ADD - REM
  • squash commit A with REM - then the file vanishes out of A andB
  • drop commit ADD - now the file is gone as it should be
  • 恢复文件
  • 在提交 ADD 中再次添加它
  • 在提交 REM 中删除它 - 现在有历史记录 A - B - ADD - REM
  • 用 REM 挤压提交 A - 然后文件从 AB 中消失
  • drop commit ADD - 现在文件已经消失了

Perhaps this is a quirky solution but for me it worked.
Please comment if you feel this is bad for some reasons.

也许这是一个古怪的解决方案,但对我来说它奏效了。
如果您因为某些原因觉得这很糟糕,请发表评论。