我在一个有两个分支a和B的项目上工作。我通常在分支a上工作,并合并分支B中的内容。对于合并,我通常会这样做:

git merge origin/branchB

但是,我也希望保留分支B的本地副本,因为我可能会偶尔检查分支,而不必首先与分支a合并。为此,我会:

git checkout branchB
git pull
git checkout branchA

有没有一种方法可以在一个命令中完成上述操作,而不必来回切换分支?我应该使用gitupdate-ref吗?怎样


当前回答

我在这个问题上遗漏了一些东西,如果你没有打算去做的话,为什么你需要去当地的分行结账?在您的示例中,您只想在保留分支A的同时更新本地分支B?

我最初假设您这样做是为了获取origin/branchB,您已经可以使用gitfetch来获取,所以这个答案确实基于此。在您需要对branchB进行操作之前,不需要拉动它,并且当您需要从origin/branchB合并时,始终可以获取origin。

如果您想跟踪branchB在某个时间点的位置,可以从最新获取的origin/branchB创建一个标记或另一个分支。

因此,您需要从原点/分支B进行合并:

git fetch
git merge origin/branchB

下次你需要在分支B上工作时:

git checkout branchB
git pull

此时,您将获得更新的本地副本。虽然有一些方法可以在不结账的情况下完成,但这很少有用,而且在某些情况下可能不安全。对此已有答案。

详细答案:

gitpull执行fetch+merge。这与下面的两个命令大致相同,其中<remote>通常是原点(默认),远程跟踪分支以<remote’/开头,后跟远程分支名称:

git fetch [<remote>]
git merge @{u}

@{u}符号是为当前分支配置的远程跟踪分支。如果branchB跟踪origin/branchB,那么来自branchB的@{u}与键入origin/bbranchB相同(请参阅git-rev-parse-help获取更多信息)。

由于您已经与origin/branchB合并,所以只缺少gitfetch(可以从任何分支运行)来更新远程跟踪分支。

不过请注意,如果在拉入本地分支B时创建了任何合并,那么您应该在从分支B拉入之后将分支B合并到分支a中(并最终将更改推回到origin/branchB,但只要它们快速前进,它们将保持不变)。

请记住,在您切换到本地分支并进行实际拉取之前,不会更新本地分支B,但是,只要没有向该分支添加本地提交,它就将保持到远程分支的快速前进。

其他回答

您可以克隆回购并在新回购中进行合并。在同一个文件系统上,这将硬链接而不是复制大部分数据。最后将结果拉入原始回购。

在您的情况下,您可以使用

git fetch origin branchB:branchB

它可以满足您的需要(假设合并是快速进行的)。如果由于需要非快速合并而无法更新分支,那么这将安全地失败,并显示一条消息。

这种形式的获取也有一些更有用的选项:

git fetch <remote> <sourceBranch>:<destinationBranch>

请注意,<remote>可以是本地存储库,<sourceBranch>可以是跟踪分支。因此,您可以在不访问网络的情况下更新本地分支,即使它未检出。

目前,我的上游服务器访问是通过一个缓慢的VPN,所以我定期连接,gitfetch更新所有远程设备,然后断开连接。如果远程主机发生了变化,我可以

git fetch . remotes/origin/master:master

即使我目前有其他分支机构结账,也能安全地让我的本地主管了解最新情况。无需网络访问。

对于许多GitFlow用户来说,最有用的命令是:

git fetch origin master:master --update-head-ok
git fetch origin dev:dev --update-head-ok

--update-headok标志允许在dev或master分支上使用相同的命令。

gitconfig中一个方便的别名:

[alias]
    f=!git fetch origin master:master --update-head-ok && git fetch origin dev:dev --update-head-ok

我为每天在项目中遇到的类似用例编写了一个shell函数。这基本上是一个快捷方式,可以让本地分支机构在打开PR之前保持与公共分支机构的最新状态,如开发等。

即使你不想使用结账,也要发布这个,以防其他人不介意这种限制。

glmh(“git pull and merge here”)将自动签出分支B,拉取最新的分支,重新签出分支A,并合并分支B。

不需要保留branchA的本地副本,但可以通过在签出branchB之前添加一个步骤来轻松修改。类似于。。。

git branch ${branchA}-no-branchB ${branchA}

对于简单的快进合并,这将跳到提交消息提示符。

对于非快速合并,这将使分支处于冲突解决状态(您可能需要进行干预)。

要进行设置,请添加到.bashrc或.zshrc等:

glmh() {
    branchB=$1
    [ $# -eq 0 ] && { branchB="develop" }
    branchA="$(git branch | grep '*' | sed 's/* //g')"
    git checkout ${branchB} && git pull
    git checkout ${branchA} && git merge ${branchB} 
}

用法:

# No argument given, will assume "develop"
> glmh

# Pass an argument to pull and merge a specific branch
> glmh your-other-branch

注意:这不足以将分支名称以外的参数传递给gitmerge

输入git前向合并:

无需签出目标,git forward merge<source><destination>将源合并到目标分支。

https://github.com/schuyler1d/git-forward-merge

仅适用于自动合并,如果存在冲突,则需要使用常规合并。