GitHub Merge分支'主人'

Jon*_*noB 42 git github

经过多年的svn使用后,我一直在尝试Git和Github.我似乎已经掌握了基础知识,但有一项令我困惑.

  • UserA对FileA进行了更改并推送到远程服务器(GitHub)

  • UserB对FileB进行了更改.他首先从远程服务器拉出,然后将他的更改推送到FileB到远程服务器

  • GitHub提交历史记录显示来自UserA的推送和来自UserB的推送

  • 但是,UserB的提交历史记录中还有一个名为"Merge branch"master" https://github.com/xxx/yyy " 的附加条目.在Github中查看diff表明这是UserA对FileA所做的更改的精确副本

为什么显示这个副本 - 从UserA到FileA的推送和Merge分支主条目都是相同的...第二个对我来说似乎是多余的.

Mar*_*air 68

存储在git中的每个版本("提交")都构成了图形的一部分,并且根据该图表思考您在git中所做的事情通常很有帮助.

当用户A开始,让我们说,有只发生过两次提交创建的,我们称之为PQ:

P--Q (master)
Run Code Online (Sandbox Code Playgroud)

然后他修改了FileA,更改了阶段并创建了一个表示源代码新状态的提交 - 假设调用了commit R.这有一个父,即提交Q:

P--Q--R (master)
Run Code Online (Sandbox Code Playgroud)

成功推送后,GitHub存储库的提交图看起来是一样的.

UserB以相同的历史开头:

P--Q (master)
Run Code Online (Sandbox Code Playgroud)

...但是创建了一个不同的提交,比如叫做S,它有自己修改过的FileB版本:

P--Q--S (master)
Run Code Online (Sandbox Code Playgroud)

UserB尝试将其推送到GitHub,但推送被拒绝 - 除非您"强制"推送,否则不允许更新远程分支,除非您推送的版本包含该远程分支中的所有历史记录.所以,UserB来自GitHub.拉实际上包括两个步骤,取和合并.的获取更新文件origin/master,这是等远程分支的状态的高速缓存master从远端origin.(这是"远程跟踪分支"的示例.)

P--Q--S (master)
    \
      R (origin/master)
Run Code Online (Sandbox Code Playgroud)

此图中的历史记录有所不同,因此合并尝试通过创建合并提交(例如M)来统一这两个历史记录,该合并提交具有两个SR作为父项,并且希望表示来自两个分支的更改:

P--Q--S--M (master)
    \   /
     \ /
      R (origin/master)
Run Code Online (Sandbox Code Playgroud)

当GitHub向您展示表示提交引入的更改的差异时,在提交一个父项的情况下它很简单 - 它只能从该版本执行差异.但是,在提交(例如M,具有多个父级)的情况下,必须选择父级来显示差异.这就解释了为什么在合并显示的DIFF提交M可能看起来是一样所示的一个SR.git中的提交是由源树的确切状态定义的,而不是使树进入该状态的更改.

  • 我们使用`git config --global branch.autosetuprebase always`自动将远程分支设置为`git pull --rebase`.可以使用`git config branch.<branch> .rebase true`设置各个分支.这可以防止引入这些额外的合并提交.它使历史更加一致和有规律. (13认同)
  • 值得注意的是(a)许多人使用`git pull --rebase`来保持历史线性 - 在获取之后,将尝试重新应用不在"origin/master"中的任何提交,以及(b)如果提交您尝试合并到当前分支已经包含当前分支的历史记录,默认情况下git不会创建合并提交 - 它只是将您的分支"快速转发"到您正在合并的分支状态. (4认同)
  • 这是否意味着如果UserB仅在FileA上撤消了FileB之后修改并推送了FileB,那么合并分支"master"将不会被创建?如果是,那么我想我明白了. (2认同)