理解git fetch和merge

71

作为一个svn背景的人,我有这个问题:

svn status -u的git等价物

(svn status -u 的 git 等价物是什么)

我了解到,你需要执行:

git fetch
git log ..origin/master

但是,我猜测 origin/master 部分取决于分支?如果我跟踪的是远程分支,它并不一定是 master 分支?

我还不太理解 git merge origin/master 的含义。我猜这只是表示 git fetch 从远程获取了更改,并将它们作为 origin/master 放入 git 数据库系统中,而我当前在 master 分支?如果我获取了更改,检查了更改内容,发现更改令人震惊,不想合并怎么办?如何放弃它们?


还有一件事: "origin master" 是远程的,而 "origin/master" 是本地的吗?或者这与此无关? - Hans
使用新的 Git,可能是 git log ..@{u} - Jakub Narębski
2个回答

129

git fetch

git fetch会从远程仓库中获取更改,并将其放入您的仓库对象数据库中。它还会获取远程仓库中的分支,并将它们存储为远程跟踪分支

当您正在获取内容时,Git会告诉您每个获取的远程仓库分支存储在何处。例如,您可能会看到以下信息:

   7987baa..2086e7b  master -> origin/master

在获取时,'origin/master' 存储了 'master' 在 'origin' 仓库中的位置。

如果你查看 .git/config 文件,你会看到以下代码块:

[remote "origin"]
        url = git://git.example.com/repo.git
        fetch = +refs/heads/*:refs/remotes/origin/*

这意味着,来自原始远程仓库(你克隆的仓库)的任何分支 'A' ('refs/heads/A') 都将被保存为 'origin/A' ('refs/remotes/origin/A')。

git log ..origin/master

如你所见,'origin/master' 就是原远程仓库中的 'master'。 如果你在(默认的) 'master' 分支上,则 git log ..origin/master,它等同于 git log HEAD..origin/master,当在 'master' 分支上时等同于 git log master..origin/master,将列出所有在远程仓库的 'master' 分支上但不在你本地工作的 'master' 分支上的提交记录。

现代 git 的更通用版本(假设存在 upstream / tracking 信息)将使用简单的

$ git log ..@{u}

(这里@{u}@{upstream}的同义词,参见gitrevisions手册页)。

git merge origin/master

git merge用于合并两行历史记录。如果其中一方自上次分支点(合并基础)以来没有进行任何工作,则情况要么是快进(您所在的分支简单地更新到正在合并的分支的末端),要么是最新的(没有新内容需要合并,您所在的分支保持不变)。

在'master'分支上时,执行git fetch后跟git merge origin/master相当于执行

$ git pull
如果你不想合并,那就不需要合并。请注意,如果你不喜欢 git pull 的结果,你可以使用 git reset --hard HEAD@{1} 回到之前的状态并丢弃它的结果。

这解决了很多问题,谢谢Jakub;但是,假设我从远程获取,现在origin/master有一些更改,我“git log ..origin/master”查看已完成的更改,但我不想要它。如果我再次想要合并,我必须先让做出更改的人撤销它,然后才能合并,对吗?我想我也可以从以前的提交中检出文件,对吗?有什么方法可以摆脱它,以便我可以再次合并。 - Hans
1
@Hans:对的。 'origin / master' 中的内容不是您的,但它跟踪了 'origin' 存储库中的开发过程。最好使用 特性分支 进行开发,可以合并也可以不合并,而不是直接在主干('master')上进行;我认为这需要达成协议 谁是维护者 并要合并变更。为了避免合并来自 'origin / master' 的更改,您可以执行 '--strategy = ours' 合并,它创建合并提交,但采用您的结果;它将 'origin / master' 保存在历史记录中,但实际上 丢弃 其结果。 - Jakub Narębski
1
如何“撤销”是非常有用的信息,但通常被忽略。 - ahnbizcad

7

git fetch 命令用于下载所需的所有更改以表示给定的远程分支。通常这是 origin/master 或类似的名称。

git merge 命令通过创建新的提交或快进(或两者的组合)将两个分支合并在一起。它不会更改您已经做出的任何提交,您始终可以回滚到旧的分支(使用 git resetgit checkout 命令)。

请注意,git pull 命令是 git fetch 命令后跟 git merge 命令(如果给出了 --rebase 则为 git rebase 命令)。


origin/master只是对本地机器上未合并信息的引用吗?它不是远程的"origin"吧? - Hans
如果您决定不合并已获取的更改,该如何放弃它们? - Hans
@Hans:正确的,origin/master 是一个本地引用,指向你获取时 origin 的 master 所在的本地副本。(它被称为远程分支。)如果你不想合并它,就不要合并它。 - Cascabel
@strager(谢谢),我在想,如果我从别人那里拉取代码,查看更改,然后决定不使用它们,但是以后又想再次拉取,那么最终我是否需要合并它们?我知道可以使用“git branch -d”删除主题分支之类的东西,但是如果有人在origin/master中做了一些我想要消除的更改怎么办? - Hans
所以如果您不想合并这些更改,您就不需要本地副本,该副本由origin/master引用。那么我们如何删除更改的本地副本呢? - Sebi2020
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接