working on git branch
我读了很多书,但对如何在不同地方的Git分支上工作仍然不太清楚。怎么做?
首先,我必须在分支机构工作的原因是我确实有一个"上游"回购,我需要不时地将其重新调整到我的
更新2:
好啊。这比我现在想象的要复杂得多。我从源位置执行的方式是,
- 更新Github fork并
- 如何更新Github分叉存储库?
问题是,我想在这样的Git分支上工作,就像在普通的Git上工作一样——也就是说,当我做某种
当我从第二个位置开始做
PS.我找到的信息,来自http://longair.net/blog/2009/04/16/git-fetch-and-merge/
If you want to create a local branch based on a remote-tracking branch (i.e. in order to actually work on it) you can do that with git branch –track or git checkout –track -b, which is similar but it also switches your working tree to the newly created local branch. For example, if you see in git branch -r that there’s a remote-tracking branch called origin/refactored that you want, you would use the command:
号
1 | git checkout --track -b refactored origin/refactored |
不过,这是我从源位置的
1 2 3 | $ git branch -r origin/HEAD -> origin/master origin/master |
号
也就是说,没有一个称为origin/something的远程跟踪分支,但我显然在一个分支中工作:
1 2 3 4 5 6 7 | $ git status . On branch newfeature nothing to commit, working directory clean $ git branch -vv master 55e1d6f [origin/master] Remove ... * newfeature 8c4266a - [+] add ... |
由于
更新3:
最后,我可以确认问题在我的源端,也就是说,远程跟踪分支没有列出。再次,将它们并排列出。
首先,我目前的坏消息来源:
1 2 3 4 5 6 7 | $ git branch -r origin/HEAD -> origin/master origin/master $ git branch -vv master 55e1d6f [origin/master] Remove ... * newfeature 8c4266a - [+] add ... |
。
第二,它应该是什么:
1 2 3 4 5 6 7 8 9 | $ git branch -r origin/HEAD -> origin/master origin/master origin/newfeature $ git branch -vv master 7b1fc0f [origin/master] Add readme * newfeature 7b1fc0f [origin/newfeature] Add readme ^^^^^^^^^^^^^^^^^^^ |
1 2 | $ git config --get-all remote.origin.fetch +refs/heads/master:refs/remotes/origin/master |
。
最终更新:
多亏了@torek的不懈帮助,我终于把事情弄清楚了。以下是按照@torek的指示修复
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | git checkout master # then fix the `.git/config` file git config --edit $ git branch -vv * master 55e1d6f [origin/master] Remove ... newfeature 8c4266a [origin/newfeature: gone] - [+] add ... ^^^^ $ git branch -r origin/HEAD -> origin/master origin/master upstream/master # The"origin/newfeature" is missing $ git checkout newfeature Switched to branch 'newfeature' Your branch is based on 'origin/newfeature', but the upstream is gone. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ (use"git branch --unset-upstream" to fixup) $ git branch --set-upstream-to origin/newfeature error: the requested upstream branch 'origin/newfeature' does not exist hint: hint: If you are planning on basing your work on an upstream hint: branch that already exists at the remote, you may need to hint: run"git fetch" to retrieve it. hint: hint: If you are planning to push out a new local branch that hint: will track its remote counterpart, you may want to use hint:"git push -u" to set the upstream config as you push. $ git push -u origin newfeature Branch newfeature set up to track remote branch newfeature from origin. Everything up-to-date $ git branch -r origin/HEAD -> origin/master origin/master origin/newfeature upstream/master # The"origin/newfeature" is now listed $ git branch -vv master 55e1d6f [origin/master] Remove ... * newfeature 8c4266a [origin/newfeature] - [+] add ... # Horay!!! |
。
因此,要重新总结,首先要纠正问题,请遵循http://www.gitguys.com/topics/adding-and-removing-remote-branches中的说明。我能用那个小演示获得高于正确的结果。也就是说,我一直遵循的方向
- 更新Github fork并
- 如何更新Github分叉存储库?
可能是也可能不是原因。但是,现在我们有了一种方法来解决它,如果您遇到类似的情况。
最终更新结束
所以,让我问最后一个问题——是否可以纠正我的坏消息来源?
根据签出跟踪的远程分支,我认为问题出在我的源端,也就是说,我没有看到我的分支在跟踪的远程分支部分中列出。这是我的:
1 2 3 4 5 6 7 8 9 10 11 12 13 | $ git remote show origin * remote origin Fetch URL: [email protected]:me/myproj.git Push URL: [email protected]:me/myproj.git HEAD branch: master Remote branch: master tracked Local branches configured for 'git pull': master merges with remote master newfeature merges with remote newfeature Local refs configured for 'git push': master pushes to master (up to date) newfeature pushes to newfeature (up to date) |
当我从第二个位置执行
更新:
我从我的第二个位置看到了
1 2 3 4 5 6 | $ git ls-remote From [email protected]:me/myproj.git 55e1d6fd9048336c7f0b178fbbf78231ca28ff06 HEAD 55e1d6fd9048336c7f0b178fbbf78231ca28ff06 refs/heads/master 8c4266a6a98f498c129a2a9e806e00e6c6d196b1 refs/heads/newfeature 8c4266a6a98f498c129a2a9e806e00e6c6d196b1 refs/tags/v1 |
。
但是,我不知道如何从第二个位置使用它:
1 2 3 | $ git checkout --track -b newfeature Branch newfeature set up to track local branch master. Switched to a new branch 'newfeature' |
也许我不该使用
1 2 3 4 5 | $ git checkout --track newfeature fatal: Missing branch name; try -b $ git checkout newfeature error: pathspec 'newfeature' did not match any file(s) known to git. |
。
根据下面的评论,这是最后一个(我希望)拼图。我要求输出来自:好的。
1 | git config --get-all remote.origin.fetch |
这是一条单行线:好的。
1 | +refs/heads/master:refs/remotes/origin/master |
号
此输出不是正常设置(尽管允许)。正常设置为:好的。
1 | +refs/heads/*:refs/remotes/origin/* |
我认为修复它的最简单方法是运行:好的。
1 | git config --edit |
。
这会在该存储库的git配置文件(通常是
1 2 3 | [remote"origin"] url = [whatever the URL is] fetch = +refs/heads/master:refs/remotes/origin/master |
第三行应该是:好的。
1 | fetch = +refs/heads/*:refs/remotes/origin/* |
。
也就是说,两次出现的
这些
修正后的refspec说您的Git应该从
(前面的加号告诉Git这些引用应该被复制,即使复制操作不是快速转发的。对于远程跟踪分支,这是您想要的。)好的。
一旦确定了这一点,
1 2 | git checkout newfeature git branch --set-upstream-to origin/newfeature |
。
(在任何还没有
新答案主要基于最新更新中的新问题(这可能真的应该是一个新问题)。这又是一个(新的)问题,因为否则我就不能直截了当地说出哪个部分是哪个:好的。
UPDATE:
Ok.
I see the
newfeature in thegit ls-remote from my second place:Ok.
1
2
3
4
5
6 $ git ls-remote
From [email protected]:me/myproj.git
55e1d6fd9048336c7f0b178fbbf78231ca28ff06 HEAD
55e1d6fd9048336c7f0b178fbbf78231ca28ff06 refs/heads/master
8c4266a6a98f498c129a2a9e806e00e6c6d196b1 refs/heads/newfeature
8c4266a6a98f498c129a2a9e806e00e6c6d196b1 refs/tags/v1However, I don't know how to use it from my second place:
Ok.
1
2
3 $ git checkout --track -b newfeature
Branch newfeature set up to track local branch master.
Switched to a new branch 'newfeature'and
git log is not showing the commits I've published to github.Ok.
Maybe I shouldn't have used the
-b ?Ok.
号
事实上,这就是(新)问题的根源。好的。
由于第二行和第三行的输出,我们可以看出:好的。
埃多克斯1〔17〕埃多克斯1〔18〕好的。
我在这里添加了三种不同的强调(斜体、粗体和粗体斜体),以便我可以讨论三个不同的点。好的。
首先,Git告诉我们这是一个新的分支。很好:这就是我们想要的!我们希望在此存储库中创建一个新(和本地)分支名称。好的。
但我们不希望新的本地分支跟踪另一个本地分支。Git告诉我们这是跟踪(本地)分支主机。我们希望它跟踪一个远程跟踪分支,可能是
命令
使用
通常我们只使用
在另一个有帮助的尝试中,Git给
1 | $ git checkout newfeature |
调用dwim代码("做我想说的,而不是我实际说的"):git猜测您打算使用命令:好的。
1 | git checkout -b newfeature --track origin/newfeature |
号
这是一个非常明确的请求:"根据
也就是说,这通常都是为你做的。DWIM代码很聪明,但并不完美。为此,必须满足以下所有条件:好的。
- 您的存储库至少有一个远程。它可以有多个遥控器,例如,您可以将
github 和laptop 作为您的两个遥控器(在本例中,两个遥控器都没有命名为origin ;origin 只是标准的遥控器名称)。 - 您的存储库至少有一个远程跟踪分支正在跟踪该远程上名为
newfeature 的分支。在本例中,如果存在远程跟踪分支github/newfeature ,则满足此要求。 - 最后,这就是当您有多个远程设备时事情会变得混乱的地方,您的存储库必须只有一个这样的远程跟踪分支。在这种情况下,如果
github/newfeature 和laptop/newfeature 都存在,则dwim代码失败!
确保存在一个且只有一个远程跟踪分支
目前还不清楚
记住,每个Git存储库都完全独立于其他Git存储库。这意味着,Github上的存储库G是否有
如果我们现在在工作机器上,在存储库w中,我们已经设置了两个远程服务器
我们还可以运行
如果我们这样做,我们就击败了
这个设置,使用具有远程
1 2 | git checkout -b lapfeature --track laptop/newfeature git checkout -b hubfeature --track github/newfeature |
现在,在您的工作机器w存储库中,本地分支
很高兴能只做一件事。要做到这一点,你必须小心你有多少个遥控器。只有一个普通的
缺点是你必须通过Github来回铲平所有东西。(通常都是正常工作的,但还记得Github倒下的那一天吗?)好的。吉特很困惑,因为…
维护git的人似乎喜欢将尽可能多的功能插入到一个命令中,比如
- 切换到现有分支
- 切换到特定提交("分离头"模式)
- 创建新分支
- 创建新的"孤立"分支(尚未创建的分支)
- 创建分支的reflog
- 从提交中提取文件
- 从索引/临时区域提取文件
- 恢复合并冲突(从
git add 撤消合并解决) - 以交互方式修补工作树中的文件
这些都是相关的,但它们也与诸如移动分支(
根据您的评论回复,您正在寻找使用远程、远程跟踪分支和远程分支的方法。似乎这些东西应该是相似的,如果不是一样的话,不是吗?但它们都有很大的不同,我认为许多介绍也很难解释它们。其中一些无疑是历史原因造成的(Git的远程和远程跟踪分支机构是2008-2012年的新发明;它们在2013年中后期妥善安置)。如果您的Git版本至少是1.8.4,最好是2.0或更高版本,您可以忽略一些历史问题。(如果没有,请显示您的Git版本运行
首先,一些定义:好的。
- 远程只是一个名称,比如
origin ,在这个名称下,您的Git可以存储一些项目。最重要的一个是一个URL,命名从何处推送和获取。 一个分支是不明确的(看看我们所说的"分支"到底是什么意思?).好的。
分支名称是类似于
master 或newfeature 的名称;它包含(单个)git commit的ID。常规(本地)分支名称是更通用的Git引用的特定形式。引用有前缀:本地分支的前缀都是refs/heads/ ,所以master 实际上是refs/heads/master ,等等。好的。有关"分支"的其他含义,请参见相关问题。注意,分支名称会自动更新:在该分支上进行新的提交会导致分支名称指向新的提交。这就是树枝生长的机制。好的。
远程跟踪分支是一个引用,至少在内部是从
refs/remotes/ 开始的。这些引用还具有远程名称的限定性,因此origin 的所有远程跟踪分支都从refs/remotes/origin/ 开始。和常规的分支名称一样,git通常去掉前缀,只显示origin/master 或origin/newfeature 。好的。
接下来,对于Git或者任何分布式版本控制系统,这同样适用于Mercurial,例如,您必须偶尔记住,存在多个独立的1存储库,它们并不总是同步的。在Git中,两个存储库之间的同步发生在
远程跟踪分支有一个很大的用途:它在您自己的Git存储库中跟踪分支的位置——常规的本地分支名称,上次Git与它们的分支同步时。当你运行
一个
通常,您将使用自己的分支名称之一,在这种情况下,您可以省略
通常,如果此设置是一个快进操作的更新,或者它创建了名称,或者为此删除了名称,则会遵循礼貌的请求。不过,接收Git有机会出于任何原因拒绝。(有关详细信息,请参阅其他SO日志。)如果推送在远程服务器上创建了一个分支,那么它也应该在您的存储库中创建一个新的远程跟踪分支,因为现在远程服务器上有一个新的(本地、远程)分支,您的Git应该跟踪它。如果远程上已经存在分支,并且接受了更新,那么您的Git应该更新远程跟踪分支。好的。
推送操作可以,但默认情况下不会设置本地分支的上游。更多信息请参见链接答案。好的。
一旦分支存在于远程服务器上,您就可以使用
请注意,您可以有多个遥控器。如果您将笔记本电脑设置为工作机器的远程设备,反之亦然,则可以在这些机器在网络上彼此连接时直接在它们之间传输提交(前提是您可以通过Linux设备进行ssh或类似访问,这通常非常容易)。换句话说,您不必经过Github或其他集中的位置(尽管您仍然可以在任何方便的时候这样做)。好的。
在Git的情况下,他们是非常独立的。在Mercurial中,存储库被强制紧密地连接在一起,因为分支名称是全局的,这与Git的标记是全局的方式非常相似。好的。
其他可以"同时看到两个"的方法是
试试这个
1 | git push --set-upstream origin BRANCHNAME |