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

git merge origin/branchB

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

git checkout branchB
git pull
git checkout branchA

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


当前回答

输入git前向合并:

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

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

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

其他回答

另一种公认的蛮力方法是重新创建分支:

git fetch remote
git branch -f localbranch remote/remotebranch

这将丢弃本地过时的分支,并重新创建一个同名分支,因此请谨慎使用。。。

不需要git签出,就可以进行任何合并,甚至是非快速合并。@grego的工作树回答是一个很好的提示。要对此进行扩展,请执行以下操作:

cd local_repo
git worktree add _master_wt master
cd _master_wt
git pull origin master:master
git merge --no-ff -m "merging workbranch" my_work_branch
cd ..
git worktree remove _master_wt

现在,您已经将本地工作分支合并到本地主分支,而无需切换签出。

只有当合并是快进时,才能执行此操作。如果不是,那么git需要签出文件,以便合并它们!

仅为快进操作:

git fetch <branch that would be pulled for branchB>
git update-ref -m "merge <commit>: Fast forward" refs/heads/<branch> <commit>

其中<commit>是提取的commit,即您要快进的commit。这基本上就像使用gitbranch-f移动分支一样,只是它还将其记录在reflog中,就像您实际执行了合并一样。

拜托,拜托,请不要为不快速前进的事情而这样做,否则您只会将分支重置为另一个提交。(要检查,请查看gitmerge-base<branch><commit>是否给出了分支的SHA1。)

git worktree add [-f] [--detach] [--checkout] [--lock] [-b <new-branch>] <path> [<commit-ish>]

你可以尝试git worktree让两个分支并排打开,这听起来可能是你想要的,但与我在这里看到的其他一些答案非常不同。

通过这种方式,您可以在同一个git repo中有两个单独的分支进行跟踪,因此您只需获取一次即可在两个工作树中获取更新(而不必分别获取两次git clone和git pull)

Worktree将为您的代码创建一个新的工作目录,您可以在其中同时签出不同的分支,而不是在原地交换分支。

当您想要删除它时,可以使用

git worktree remove [-f] <worktree>

我在这个问题上遗漏了一些东西,如果你没有打算去做的话,为什么你需要去当地的分行结账?在您的示例中,您只想在保留分支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,但是,只要没有向该分支添加本地提交,它就将保持到远程分支的快速前进。