如何在git中找到origin/master的位置,并且如何更改它?

236

我是一个 Git 新手,最近将一个 Rails 项目从 Subversion 迁移到了 Git。我遵循了这里的教程:http://www.simplisticcomplexity.com/2008/03/05/cleanly-migrate-your-subversion-repository-to-a-git-repository/

我还使用 unfuddle.com 存储我的代码。我在通勤途中使用 Mac 笔记本电脑进行更改,然后使用以下命令在拥有网络连接时将它们推送到 unfuddle:

git push unfuddle master

我使用Capistrano进行部署,并从unfuddle存储库使用master分支拉取代码。

最近在我笔记本电脑上运行"git status"时,注意到以下信息:

# On branch master
# Your branch is ahead of 'origin/master' by 11 commits.
#
nothing to commit (working directory clean)

我很困惑为什么会出现这种情况。我原以为是我的笔记本电脑的问题,但不确定是最初从Subversion拉取还是推送到Unfuddle引起了此消息。我该如何:

  1. 找出Git认为“origin/master”在哪里?
  2. 如果它在其他地方,我该如何将我的笔记本电脑变成“origin/master”?
  3. 让这条消息消失。它让我觉得Git对某些事情感到不满意。

我的Mac正在运行Git版本1.6.0.1。


当我像dbr建议的那样运行git remote show origin时,我得到以下结果:

~/Projects/GeekFor/geekfor 10:47 AM $ git remote show origin
fatal: '/Users/brian/Projects/GeekFor/gf/.git': unable to chdir or not a git archive
fatal: The remote end hung up unexpectedly

按照 Aristotle Pagaltzis 的建议,当我运行 git remote -v 时,我会得到以下输出:

~/Projects/GeekFor/geekfor 10:33 AM $ git remote -v
origin  /Users/brian/Projects/GeekFor/gf/.git
unfuddle    git@spilth.unfuddle.com:spilth/geekfor.git

有趣的是,我正在geekfor目录中开发我的项目,但它显示我的源是在gf目录的本地机器上。我相信在将我的项目从 Subversion 转换为 Git 时,gf 是我使用的临时目录,也可能是我从中向 unfuddle 推送的目录。然后我相信我从 unfuddle 检出了一个新副本到geekfor目录。

所以看起来我应该遵循dbr的建议,执行:

git remote rm origin
git remote add origin git@spilth.unfuddle.com:spilth/geekfor.git
13个回答

286

我阅读这个问题是为了解释“your branch is ahead by...”这个消息在git中的一般意义。虽然此处没有答案,但由于当你搜索短语“Your branch is ahead of 'origin/master'”时,这个问题目前会显示在Google的顶部,我已经弄清楚了这个消息的真正含义,所以我想在这里发布信息。

那么,作为一个git新手,我可以看到我需要的答案显然是一个初学者的答案。具体来说,“your branch is ahead by...”这个短语的意思是,你添加并提交到本地存储库中的文件从未推送到源头。这条消息的意图进一步被“git diff”的事实所混淆,至少对我来说,它没有显示任何差异。直到我运行“git diff origin/master”,我才被告知我的本地存储库和远程主分支之间存在差异。

因此,要明确:


"your branch is ahead by..." => 您需要将其推送到远程主分支。运行"git diff origin/master"以查看本地存储库和远程主存储库之间的差异。


希望这能帮助其他新手。

(此外,我认识到有一些配置细节可能部分使这个解决方案无效,例如主分支实际上可能并不是“remote”,而且“origin”是一种重新配置的名称按惯例使用等等。但新手不关心这类事情。我们需要简单、直接的答案。我们可以在解决紧迫问题后再阅读这些细节。)

Earl


2
@Earl,使用git diff --cached origin/master不是更好的指令吗?因为它说明了下一次推送的结果。你上面突出显示的命令还显示了未提交和未暂存的文件(我想,我也是一个Git新手)。 - nhed
48
如果在执行 git pull remote branch 后出现这个错误,很可能是你需要运行 git fetch 命令。这可能是由于你的引用已经过时所致,git fetch 命令可以解决这个问题。 - bryan kennedy
1
请注意,此描述不完整。我目前遇到的问题是:# On branch master # Your branch is ahead of 'origin/master' by 3 commits.但是git diff origin/master没有显示任何内容(使用--cached选项也无效)。而且,git fetch和git pull都不能解决这个问题,git reset --hard也无法解决。为了解决这个问题,我需要运行:git reset --hard origin/master我选择这种方法是因为其他人也在这个仓库中工作,我不想使他们的测试失效,并且我找不到这些提交是什么。 - rdm
git reset --hard HEAD这是进行硬重置的常用方法。 - Earl Jenkins
1
当我需要从origin/master 拉取 而不是推送时,我也会收到这个消息。例如,如果我从另一个分支 git checkout master ,我会收到这个消息,这意味着在开始工作之前应该先 git pull origin master。但我发现这非常令人困惑,因为消息的措辞似乎暗示了相反的意思。 - Anentropic
显示剩余3条评论

217

1. 使用git-remote查找Git认为的 'origin/master' 的位置。

git remote show origin

...这将返回类似于...

* remote origin
  URL: me@remote.example.com:~/something.git
  Remote branch merged with 'git pull' while on branch master
    master
  Tracked remote branch
    master

远程仓库就像是指向远程代码仓库的链接。当你执行某些操作时,如推送(push)或拉取(pull)代码,你需要使用远程来访问该仓库。

git remote add unfuddle me@unfuddle.com/myrepo.git
git push unfuddle

使用 git push 命令可以将更改推送到你添加的地址,就像远程仓库的书签一样。

当你运行 git status 命令时,它会检查远程仓库是否缺少提交(与本地仓库相比),如果确实缺少,则会显示缺少几个提交。如果你将所有更改推送到“origin”,两者将保持同步,这样你就不会收到该消息。

2. 如果远程仓库在其他地方,如何将我的笔记本电脑变成“origin/master”?

这样做没有意义。假设“origin”被重命名为“laptop”,你永远不想从你的笔记本电脑执行 git push laptop 命令。

如果你想删除 origin 远程仓库,请执行以下操作..

git remote rm origin

这不会删除任何东西(指文件内容/修订历史记录)。这将停止“your branch is ahead by…”的提示,因为它不再将您的存储库与远程进行比较(因为远程已经不存在了!)

需要记住的一件事是,origin 没有特殊之处,它只是 Git 使用的默认名称。

当你执行像 git pushgit pull 这样的操作时,Git 默认使用 origin。因此,如果您经常使用某个远程仓库(例如Unfuddle),我建议将其添加为 “origin”:

git remote rm origin
git remote add origin git@subdomain.unfuddle.com:subdomain/abbreviation.git

或者使用 set-url 命令一次执行上述操作:

git remote set-url origin git@subdomain.unfuddle.com:subdomain/abbreviation.git

你可以直接使用git pushgit pull进行更新,而无需使用git push unfuddle master



1
他写道,他将代码推送到origin仓库(尽管他对git术语的工作原理并不了解)- 对于他来说,删除远程仓库几乎没有任何用处。 - Aristotle Pagaltzis
10
我不明白为什么人们要改述问题。这会改变问题的意思,使现有答案毫无意义,并且不让其他人知道提问者需要更多信息,因为他们的问题可能略有不当。 - stu
9
删除远程源是我需要的,因为它指向一个不再存在的本地存储库,而不是 unfuddle 存储库。请注意,“exactly” 翻译为“恰好”。 - Brian Kelly
3
重述是好事情!如果他们一开始没有清晰表达,得到的答案就毫无意义,因为它们无法解决实际问题。 - dbr
4
但是生气和心怀不满会更容易。 :-) 但我理解你的观点。 - stu
显示剩余5条评论

39

我曾经遇到类似的问题,我的工作目录比 origin 多了 X 个提交,但使用 git pull 却显示 Everything up-to-date。我根据这篇建议修复了这个问题。我在这里发帖是为了帮助其他遇到类似问题的人。

基本修复步骤如下:

$ git push {remote} {localbranch}:{remotebranch}

方括号内的单词应该替换成你的远程仓库名称、本地分支名称和远程分支名称。例如:

$ git push origin master:master

1
谢谢,这对我有用。git diff 没有显示任何内容,在按照您所描述的操作后,我不再收到这个令人困惑和烦人的消息了。 - Mathieu Dhondt
1
需要更多的赞:)。得到更高票数的答案对我来说都是“没有效果”的(即“git fetch”——什么也没做……检查“git remote show origin”——没有错误,也没有需要更改的内容)。 - Adam

24
有时候本地缓存的"origin master"(origin/master)与真正的远程"origin master"存在差异。
如果运行 "git remote update" 命令,将会将 "origin master" 与 "origin/master" 进行同步。
参见这个问题的被接受的答案: git pull origin master与 git pull origin/master 的区别

10

我原以为我的笔记本是源...

这有点毫无意义:origin 是指默认的远程存储库,通常你从中获取/拉取其他人的更改。

我该如何:

  1. git remote -v 将向您显示 origin 是什么; origin/master 是您对 origin 存储库的 主分支 的最后已知状态的“书签”,而您自己的masterorigin/master 的跟踪分支。 这一切都是正确的

  2. 你不能这样做。至少对于一个存储库来说,它成为自身的默认远程存储库是毫无意义的。

  3. 不是这样的。它只是告诉您,根据那个存储库的最后已知状态,您在本地进行了这么多次提交,而这些提交并没有在远程存储库中。


1
我假设我的笔记本电脑是源,因为那是我最初创建存储库(它的起源)的地方。 - Brian Kelly
1
相比之下,我认为将“origin”指向本地笔记本电脑是完全有道理的,因为对于像笔记本电脑这样的便携设备而言,离线或切换网络是非常常见的情况。这样,您可以随时使用“git push”和“git pull”,无需考虑当前是否连接到正确的网络。当网络链接可用时,此本地“origin”可以根据当前漫游状态自动与真实远程同步。问题在于何时运行哪个同步,与GIT部分相比,这部分相当容易。 - Tino
2
origin指向笔记本电脑上的另一个存储库是有道理的。然而,将存储库的origin指向自身则没有意义:无论您运行git push还是git pull都不会有任何区别,因为存储库始终与自身完全同步。这有点自证不同样。 - Aristotle Pagaltzis

3

[解决方案]

$ git push origin

对我来说,这解决了我的问题。它将我的主分支(在笔记本电脑上)与位于远程服务器上的“origin”同步。


1

我正在为这个问题苦苦挣扎,之前的答案都没有解决我的问题。我已经将问题简化到基础层面,以便更清楚地表达我的问题。

我创建了一个新的代码库(rep1),放入一个文件并提交了它。

mkdir rep1
cd rep1
git init
echo "Line1" > README
git add README
git commit -m "Commit 1"

我创建了rep1的克隆并将其命名为rep2。我查看rep2的内部并确认文件是正确的。
cd ~
git clone ~/rep1 rep2
cat ~/rep2/README

在rep1中,我对文件进行了单个更改并提交。然后在rep1中,我创建了一个远程指向rep2并推送更改的操作。
cd ~/rep1
<change file and commit>
git remote add rep2 ~/rep2
git push rep2 master

现在当我进入rep2并执行'git status'时,会告诉我我领先于origin。
# On branch master
# Your branch is ahead of 'origin/master' by 1 commit.
#
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   modified:   README
#

rep2 中的 README 是在第二次提交之前的原始版本。我所做的唯一修改是在 rep1 中,我想要的只是将它们推送到 rep2 中。我没有理解错什么吧?


1
两件事情:rep2的“origin/master”检查实际上并没有查看rep1。如果在rep2中执行“git pull”,它将注意到它们处于相同的状态并停止抱怨。要在工作副本中实际查看推送的更改,您需要执行“git checkout”--推送从不触及目标存储库的工作副本。 - Walter Mundt
我以为可能是这种情况,但是我得到的结果是: "git checkout M README 你的分支比 'origin/master' 提前了1个提交。"但是我的工作副本实际上是落后了1个提交,而不是提前。 - Steve Hindmarch

1

它正在等待您“推送”。尝试:

$ git push


1

最近我遇到了这个问题,我发现是因为我删除了一些不再需要的文件。问题在于git并不知道这些文件已被删除,它仍然认为服务器(即origin)上还有这些文件。

所以我运行了

git rm $(git ls-files --deleted)

然后运行了提交和推送。

问题得到了解决。


1
只有当提交信息为 delete -- <文件名> 时,此方法才有效。 - looneydoodle

1

我也是一个 Git 新手。我遇到了“你的分支领先于 origin/master N 个提交”的问题。按照建议执行“git diff origin/master”确实显示了一些差异,但我并不想保留它们。

由于我的 Git 克隆是为托管而设计的,我想要一个精确的主仓库副本,并且不想保留任何本地更改,所以我决定保存整个仓库,并创建一个新的:

(在托管机器上)

mv myrepo myrepo
git clone USER@MASTER_HOST:/REPO_DIR myrepo

为了方便起见,我曾经在我的托管机器上对克隆进行更改。不再如此。我将对主分支进行更改,git commit,然后执行git pull。希望这样可以使我的托管机器上的git克隆完全同步。
/Nara

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