合并如何在Git中运行

时间:2014-03-26 18:57:20

标签: git

假设我有一个存储库,它是一条直线。我签出了第一个提交,然后我添加了一个文件并提交它。这会隐式地创建一个新的分支吗?如果确实如此,我将其合并回父级,那么所有基于父级的提交会发生什么?我如何回到历史记录中进行更改并将其传播到所有未来的提交中?

3 个答案:

答案 0 :(得分:1)

  

我签出了第一个提交,然后我添加了一个文件并提交了它。   这会隐式地创建一个新的分支吗?

没有。在Git中,当您签出提交时,它会更新工作目录的内容以匹配该提交的内容。你可以四处看看并玩它,但你不能提交更改。这称为分离的HEAD 状态。

在此状态下,您可以使用git checkout -b branchname创建一个分支,这样您就可以进入正确的分支,提交更改,并与原始分支分开。

  

如果确实如此,我将其合并回父级,那么所有基于父级的提交会发生什么?

假设您从第一次提交创建了一个分支,并且您希望将此独立分支合并到原始分支中。原始分支中的提交不会更改。新分支中的唯一提交将附加到原始分支,它们的更改将应用​​于文件。

结果将如下所示:

$ git log --graph --oneline --decorate
*   69d6cc5 (HEAD, master) Merge branch 'mybranch'
|\
| * 01ca942 (mybranch) added something
* | e715c4a 3rd commit
* | 4f88705 2nd commit
|/
* e7a9e79 Initial commit
  

我如何回到历史记录中进行更改并将其传播到所有未来的提交中?

这称为变基,最好尽量避免。重新定位会重写历史记录。如果您考虑一下,这违背了版本控制的精神,现有的提交应该保持不变,不可变,并且所有更改都应该是增量的。但是,Git让你做到这一点,你就是老板。这一系列命令将执行此操作:

# create branch from a specific older commit
git checkout -b mybranch SOMESHA

# work work work
git commit -m 'fixed something important'

# switch to the master branch
git checkout master

# rebase on top of mybranch
git rebase mybranch

就是这样。这会将master的历史记录回滚到mybranch的提示,并逐一应用master之后SOMESHA中发生的所有更改。

坚持使用前面的示例repo,结果将如下所示:

$ git log --graph --oneline --decorate
* 7e3dd9d (HEAD, master) 3rd commit
* 027589b 2nd commit
* 01ca942 (mybranch) added something
* e7a9e79 Initial commit

请注意,第一个提交和mybranch中的提交具有与之前相同的SHA1,但第二个和第三个提交具有不同的SHA1。即使他们的内容实际上是相同的。我们重写了历史。无论是合并还是变基,最终结果在文件内容方面都应该相同。

避免重新定位的另一个原因是,执行此操作后,必须告知已克隆存储库的所有用户强制更新其克隆。这可能令人困惑,给他们带来了很大的不便。

答案 1 :(得分:0)

我签出了第一个提交,然后我添加了一个文件并提交了它。这会隐式地创建一个新的分支吗?

  

它被附加到当前LOCAL分支的末尾。假设你有一个REMOTE分支,它们会有所不同。

如果确实如此,我将其合并回父级,那么所有基于父级的提交会发生什么?

  

LOCAL和REMOTE分支不同,当您希望它们再次同步时,您必须合并/重新绑定,并将本地分支推送到远程分支以将其更新给其他所有人。

如何回溯历史记录进行更改并将其传播到所有未来的提交中

  

如果您在本地重写历史记录并推送它,则必须告诉其他使用远程分支的其他人删除其本地分支并提取您的分支。你永远不应该这样做,只需在将其推送到REMOTE之前用合并或rebase更新你的本地分支。

答案 2 :(得分:0)

当您签出提交(而不是分支)时,您将进入“分离的HEAD”状态。这意味着当您对HEAD进行后续更改时(使用git commitgit reset等),这将不会自动更新任何分支。此外,一旦它不再是分支或标记的父级,您的HEAD将不会在gitk中显示,这可能会造成混淆。

您的主分支不受此影响,这意味着一旦您签出主分支,您将失去在此状态下完成的所有工作(除非您记下提交ID或从reflog中检索它)。 / p>

如果要创建新分支,则必须明确地执行此操作:

git checkout -b new_branch_name

您可以照常将更改合并回主分支:

git merge master new_branch_name

  

我如何回到历史记录中进行更改并将其传播到所有未来的提交中?

有两种方法可以实现这一目标:

  • 使用git rebase -i并将命令从pick更改为edit以获取相应的行。请确保您不删除任何行,因为这将删除提交。
  • 按上述步骤操作,然后使用git rebase new_branch_name master在新分支的顶部重新绑定旧的主分支。可选择执行git branch -d new_branch_name

但是,您不应该更改公共存储库的历史记录。