使用 git 同步所有分支

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27157166/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 02:42:06  来源:igfitidea点击:

Sync all branches with git

gitgithubbranchsync

提问by Gabriel

I push code from two main locations: my PC at home and my laptop at work. I use Github to store my repos.

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

This is the scenario: I did some work in my PC on a repository I've been working on for some time (both in my PC and in my laptop), and ended with the following branches:

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

$ git branch
* master
* v123
* test-b

which I pushed to Github. So far so good.

我推送到 Github。到现在为止还挺好。

Now I'm on my laptop and this is what I see before attempting to pull anything:

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

$ git branch
* master
* v_123

This is an old version of my repo in my laptop (since I've been working in my PC) where the differences are: a branch is missing (test-b), another one has been re-named, or equivalently deleted and re-created with a new name (ie: v_123is now v123), and lots of things have changed possibly in all branches.

这是我的笔记本电脑中的旧版本存储库(因为我一直在我的 PC 上工作),其中的区别在于:缺少一个分支 ( test-b),另一个分支已被重命名,或者等效地删除并重新创建一个新名称(即:v_123is now v123),并且所有分支中的很多事情都可能发生了变化。

I want to sync all my branchesinto my laptop and have them correctly tracked. I've looked at two of the most up-voted questions regarding branch cloning/fetching (How to clone all remote branches in Git?; How to fetch all git branches) and right now I'm a bit lost.

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

Is there some easy to use git sync-branch --allcommand that can be used to sync my laptop with the latest state of the repo in Github?

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

回答by Breen ho

Not sure, this is what you expect.

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

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

The above commands will synchronize the remote repo with the local repo. After the above command execution, your local repo will be like the mirror image of your remote repo.

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

If you want to retain the changes as unstaged files, use --softinstead of --hard.

如果要将更改保留为未暂存文件,请使用--soft代替--hard

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

警告:当你这样做时,所有未跟踪的文件都将消失git clean -f -d

Lemme know, if any questions.

让我知道,如果有任何问题。

回答by Arnauld VM

I had a similar issue:

我有一个类似的问题:

  • I want to sync all my local tracking branches at once
  • I want this operation to be safe. In other words, in case of local modifications or diverging branches, warn and don't touch the history (and do not tamper with uncommitted modifications)
  • 我想一次同步我所有的本地跟踪分支
  • 我希望这个操作是安全的。换句话说,如果发生本地修改或分支分支,警告不要触摸历史(不要篡改未提交的修改)

After searching a lot for a simple solution, I ended up with my own (not so simple) solution, based on a series of git aliases (code to be added to the .gitconfigfile): https://gist.github.com/arnauldvm/dcec7ee043c25dce30dbae1b576f2102

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

? This is fresh code, not yet so heavily tested.

? 这是新代码,尚未经过严格测试。

Usage: git sync

用法: git sync



Some explanations:

一些解释:

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

→ This will retrieve all local tracking branches and the corresponding remote branch, colon separated.

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

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"

→ These will verify that there are no pending changes in the workdir.

→ 这些将验证工作目录中没有挂起的更改。

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

→ This takes 2 arguments (a local branch and a remote branch), it will checkout the local branch and merge it with the remote branch. It uses --ff-onlyto avoid creating commit merges ? In case of diverging local branch, it will issue a "fatal: Not possible to fast-forward, aborting." message on STDERR.

→ 这需要 2 个参数(一个本地分支和一个远程分支),它将检出本地分支并将其与远程分支合并。它用于--ff-only避免创建提交合并?如果发生分支本地分支,它会发出“致命:无法快进,中止”。STDERR 上的消息。

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

→ Retrieve name of the branch currently checked out. Will be used to put the workdir back in its initial state, at the end.

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

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"

→ That's the main part. Let's split this into parts:

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

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

→→ Aborts the command if there is pending work in the workdir.

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

current=$(git current-branch)

→→ Stores the name of the branch currently checked-out.

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

git fetch --all

→→ Sync remote branches from all remotes (--all).

→→ 同步所有遥控器的远程分支 ( --all)。

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

→→ Iterates over each local tracking branch.

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

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

→→ Highlights errors (containing the 'fatal' keyword). The "3>&1 1>&2 2>&3" magical formula exchanges STDOUT and STDERR, it is necessary to be able to pipe STDERR to the egrep command.

→→ 突出显示错误(包含“致命”关键字)。“3>&1 1>&2 2>&3”神奇公式交换STDOUT和STDERR,需要能够通过管道将STDERR传递给egrep命令。

git checkout "$current"

→→ Restore the workdir to its initial state.

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

回答by Wikiii122

You cannot see any changes made on remote before attempting to pull anything. You must fetch from remote first.

在尝试拉任何东西之前,您看不到远程所做的任何更改。您必须先从远程获取。

There is a reason for this. Git is decentralized. Every repository contains it's full copy. It means that you may create a full clone from repository on your disk. And it also means that you can be working entirely offline, unless you command it to sync. Actually, the way git is made forces you to work almost entirely offline, not counting moments you push or fetch. On the other hand, you have full control and nothing happens without you explicitly saying so.

有一个原因。Git 是去中心化的。每个存储库都包含它的完整副本。这意味着您可以从磁盘上的存储库创建完整克隆。这也意味着你可以完全离线工作,除非你命令它同步。实际上,git 的制作方式迫使您几乎完全离线工作,不计算您推送或获取的时间。另一方面,您拥有完全的控制权,如果您不明确说明,则不会发生任何事情。

How to do it? That's why git pullexists. It performs two operations. First, it fetches all branches from remote (equivalent to git fetch). They are saved as <remote>/<branch>and not listed on branch list by default (override with -a). Then, it merges currently active branch with it's tracked branch.

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

Now, if you want to have a remote branch tracked, then simply checkout it after pull. It will create it from last synced version and should set everything up. If you want to set nonpublished local branch tracked on remote, use git pushwith -uflag. It will set upstream for the branch as push target.

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

EDIT:

编辑:

So your goal is to update all local tracked branches at once, with one command? Not those <remote>/<branch>, but your local branches, without calling pull on every single one of them, now I get it right?

所以你的目标是用一个命令一次更新所有本地跟踪的分支?不是那些<remote>/<branch>,而是您当地的分支机构,无需调用其中的每一个,现在我明白了吗?

Unfortunately, it's impossible to do with git alone. But there is an extension that does exactly that. From project description

不幸的是,单独使用 git 是不可能的。但是有一个扩展可以做到这一点。从项目描述

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

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

You can find it here http://aanandprasad.com/git-up/

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

When you use it, with command git up, it will stash your current changes, fetch all remotes, then rebase all tracked branches to state from tracked remote and unstash changes. I believe this is the way of synchronization you want.

当您使用它时,使用 command git up,它将存储您当前的更改,获取所有遥控器,然后将所有跟踪的分支重新设置为来自跟踪的远程和取消存储更改的状态。我相信这是您想要的同步方式。