关于github:用git同步所有分支

Sync all branches with git

我从两个主要位置推代码:我在家的电脑和我在工作的笔记本电脑。我用Github存储我的回购。

这是一个场景:我在一个我已经工作了一段时间的存储库(在我的电脑和笔记本电脑中)上在我的电脑上做了一些工作,并以以下分支结束:

1
2
3
4
$ git branch
* master
* v123
* test-b

我把它推到了Github。到现在为止,一直都还不错。

现在我在我的笔记本上,这就是我在尝试拉任何东西之前看到的:

1
2
3
$ git branch
* master
* v_123

这是我在笔记本电脑上的旧版回购协议(因为我在电脑上工作过),不同之处在于:一个分支丢失(test-b),另一个分支被重新命名,或同等地删除并重新创建了一个新名称(即:v_123现在是v123),并且许多事情可能在所有分支中都发生了变化。

我想将我所有的分支同步到我的笔记本电脑上,并正确地跟踪它们。我看过两个投票最多的关于分支克隆/获取的问题(如何在Git中克隆所有远程分支)?我现在有点迷路了。

是否有一些易于使用的git sync-branch --all命令可以用来将我的笔记本电脑与GitHub中最新的回购状态同步?


不确定,这就是你所期望的。

1
2
3
git fetch origin
git reset --hard origin/master
git clean -f -d

上述命令将使远程回购与本地回购同步。执行上述命令后,您的本地repo将类似于远程repo的镜像。

如果要将更改保留为未分页的文件,请使用--soft而不是--hard

WARNING: All your untracked files will be gone when you do git clean -f -d.

我知道,如果有问题的话。


我也有类似的问题:

  • 我想一次同步所有本地跟踪分支
  • 我希望这次手术安全。换句话说,在局部修改或分支分叉的情况下,警告并不要触摸历史记录(也不要篡改未提交的修改)。

在大量搜索简单的解决方案后,我最终得到了自己的(不是那么简单的)解决方案,基于一系列git别名(要添加到.gitconfig文件的代码):https://gist.github.com/arnauldvm/dcec7ee043c25dce30dbae1b576f1102

?这是新的代码,还没有经过如此严格的测试。

用法:git sync

一些解释:

1
tracking ="!f() { git for-each-ref --format '%(refname:short):%(upstream:short)' 'refs/heads' | egrep -v ':$'; }; f"

→这将检索所有本地跟踪分支和相应的远程分支,以冒号分隔。

1
2
3
is-clean-workdir ="!f() { git diff --stat --exit-code || { echo "Workdir dirty"; exit 1; }; }; f"
is-clean-index ="!f() { git diff --stat --cached --exit-code || { echo "Index dirty"; exit 2; }; }; f"
is-clean ="!f() { git is-clean-workdir && git is-clean-index; }; f"

→这些将验证WorkDir中没有挂起的更改。

1
co-merge ="!f() { local="$1"; remote="$2"; git checkout "$local"; git merge --ff-only "$remote"; }; f"

→这需要2个参数(本地分支和远程分支),它将签出本地分支并将其与远程分支合并。它使用--ff-only来避免创建提交合并?如果转移本地分支,它将在stderr上发出"致命:无法快进,正在中止"消息。

1
current-branch = rev-parse --abbrev-ref HEAD

→检索当前签出的分支的名称。将用于在结束时将workdir恢复到初始状态。

1
sync ="!f() { git is-clean || { echo Aborting sync.; exit 1; }; current=$(git current-branch); git fetch --all; git tracking | while IFS=: read local remote; do echo "Merging $local with $remote"; git co-merge "$local" "$remote"; done 3>&1 1>&2 2>&3 | egrep -i --color 'fatal|$' 3>&1 1>&2 2>&3; git checkout "$current"; }; f"

这是主要部分。让我们把它分成几个部分:

1
git is-clean || { echo Aborting sync.; exit 1; }

→如果WorkDir中有挂起的工作,则中止该命令。

1
current=$(git current-branch)

→存储当前签出的分支的名称。

1
git fetch --all

→同步来自所有远程的远程分支(--all)。

1
git tracking | while IFS=: read local remote; do ...

→迭代每个本地跟踪分支。

1
3>&1 1>&2 2>&3 | egrep -i --color 'fatal|$' 3>&1 1>&2 2>&3

→突出显示错误(包含"致命"关键字)。"3>1 1>2 2>3"神奇公式交换stdout和stderr,必须能够将stderr传输到egrep命令。

1
git checkout"$current"

→将workdir恢复到初始状态。


在尝试提取任何内容之前,您无法看到在远程上所做的任何更改。您必须先从远程获取。

这是有原因的。Git是分散的。每个存储库都包含它的完整副本。这意味着您可以从磁盘上的存储库创建完整的克隆。这也意味着你可以完全离线工作,除非你命令它同步。实际上,Git的制作方式迫使您几乎完全离线工作,而不计算您推或获取的时间。另一方面,你拥有完全的控制权,没有你明确地说出来,什么都不会发生。

怎么做?这就是git pull存在的原因。它执行两个操作。首先,它从远程获取所有分支(相当于git fetch)。它们保存为/,默认不在分支列表中(用-a覆盖)。然后,它将当前活动的分支与跟踪的分支合并。

现在,如果您想要跟踪一个远程分支,那么只需在拉后签出它。它将从上次同步的版本创建它,并应设置所有内容。如果要在远程上设置跟踪的非发布本地分支,请使用git push-u标志。它将为分支设置上游作为推送目标。

编辑:

所以您的目标是用一个命令一次性更新所有本地跟踪的分支?不是那些/的,而是你们当地的分支机构,不需要每一个都打电话,现在我明白了吗?

不幸的是,单用Git是不可能的。但是有一个扩展可以做到这一点。来自项目描述

git-up - fetch and rebase all locally-tracked remote branches

你可以在这里找到它http://aanandprasad.com/git-up/

当您使用它时,使用命令git up,它将存储您当前的更改,获取所有远程设备,然后将所有跟踪的分支从跟踪的远程设备重置为状态,并取消清除更改。我相信这是你想要的同步方式。