使用git同步所有分支

时间:2014-11-26 19:16:22

标签: git github branch sync

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

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

$ git branch
* master
* v123
* test-b

我把它推到了Github。到目前为止一切都很好。

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

$ git branch
* master
* v_123

这是我的笔记本电脑中的旧版本(因为我一直在我的电脑上工作),其中存在以下差异:缺少一个分支(test-b),另一个已经重新启用命名,或等效删除并使用新名称重新创建(即:v_123现在是v123),并且许多事情可能在所有分支中都发生了变化。

我想将所有分支同步到我的笔记本电脑中并正确跟踪它们。我已经看过两个关于分支克隆/抓取的最高投票问题(How to clone all remote branches in Git?; How to fetch all git branches),现在我有点迷失了。

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

5 个答案:

答案 0 :(得分:6)

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

git fetch origin
git reset --hard origin/master
git clean -f -d

以上命令将远程仓库与本地仓库同步。执行上述命令后,您的本地仓库将类似于远程仓库的镜像。

如果您希望将更改保留为非暂存文件,请使用--soft代替--hard

  

警告:执行git clean -f -d后,所有未跟踪的文件都将消失。

Lemme知道,如果有任何问题。

答案 1 :(得分:3)

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

这是有原因的。 Git是分散的。每个存储库都包含它的完整副本。这意味着您可以从磁盘上的存储库创建完整克隆。它还意味着您可以完全脱机工作,除非您命令它同步。实际上,git的制作方式迫使你几乎完全脱机工作,不计算你推或取的时刻。另一方面,如果没有明确说明,你就可以完全控制,没有任何反应。

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

现在,如果你想跟踪一个远程分支,那么只需在拉后检查它。它将从上一个同步版本创建它,并应该设置一切。如果要设置在远程跟踪的非发布本地分支,请使用带有git push标志的-u。它会将分支的上游设置为推送目标。

编辑:

所以你的目标是一次用一个命令更新所有本地跟踪的分支?不是那些<remote>/<branch>,而是你的本地分支机构,没有调用每一个分支,现在我做对了吗?

不幸的是,单独使用git是不可能的。但是有一个延伸就是这样做的。来自项目描述

  

git-up - 获取并重新绑定所有本地跟踪的远程分支

您可以在http://aanandprasad.com/git-up/

找到它

当您使用它时,使用命令git up,它将存储您当前的更改,获取所有遥控器,然后将所有跟踪的分支重新绑定到已跟踪的远程和解除更改的状态。我相信这是你想要的同步方式。

答案 2 :(得分:3)

我有一个类似的问题:

  • 我想一次同步所有本地跟踪分支
  • 我希望此操作安全。换句话说,如果发生局部修改或分支分散,请警告并不要触及历史记录(并且不要篡改未提交的修改)

在大量寻找了一个简单的解决方案之后,我最终基于一系列git别名(要添加到.gitconfig文件中的代码),得到了自己的解决方案(不是那么简单):{{3 }}

⚠这是新鲜的代码,尚未经过严格测试。

用法:git sync


一些解释:

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

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

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"

→这些将验证工作目录中没有待处理的更改。

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

→这需要2个参数(本地分支和远程分支),它将签出本地分支并将其与远程分支合并。它使用--ff-only来避免创建提交合并⇒如果分支与本地分支不同,它将发出“致命错误:无法快速前进,中止”。 STDERR上显示消息。

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

→检索当前已签出的分支的名称。最后将用于将工作目录恢复为初始状态。

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"

→这是主要部分。让我们将其分为几部分:

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

→→如果工作目录中有待处理的工作,则中止该命令。

current=$(git current-branch)

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

git fetch --all

→→同步所有远程站点(--all)上的远程分支。

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

→→遍历每个本地跟踪分支。

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命令。

git checkout "$current"

→→将工作目录恢复为其初始状态。

答案 3 :(得分:2)

我想你想:

git fetch --all -Pp

其中: git fetch 从另一个(远程)存储库下载对象和引用

--all 获取所有遥控器。

-P 删除遥控器上不再存在的任何远程跟踪引用。

-p 删除远程上不再存在的所有本地标签。

更多用途git fetch --help

答案 4 :(得分:0)

这是我写的一个脚本,它可以在不进行任何结账的情况下获取并快进所有分支(因此它更快并且不会影响您当前的工作树。

https://stackoverflow.com/a/24451300/965176