【问题标题】:How do I configure Git to automatically pull from origin on branch change?如何将 Git 配置为在分支更改时自动从原点提取?
【发布时间】:2018-07-27 13:44:36
【问题描述】:

当我切换分支时,如果本地是干净的并且落后于其原始对应物,我希望始终从原始提取最新更改。本地分支是其远程分支的跟踪分支,并且 fetch 按预期工作。

  • 可以将 Git 配置为自动执行此操作吗?

  • 是否有适用于所有分支的存储库范围的设置? (我们的分支经常被创建和删除,因为公司政策是每个任务一个分支,在审查时被 PR 并合并)


编辑:

就上下文而言,我使用 Visual Studio 2017 和主要的用户界面来执行 Git 命令。让 Git 保持最新是没有问题的。我需要使用命令行执行一些 Git 命令,例如重命名分支或隐藏 repo 设置。

当我说“本地是干净的”时,是的,它指的是来自 git status 的工作树,并且在没有传出提交或本地修改文件的 VS 中。 VS 有一个非常漂亮的 UI,可以实时显示这些信息。

(我们的分支机构经常被创建和删除,因为公司政策是 每个任务一个分支,在审查时被 PR 和合并)

这应该是一种不经意的表达方式:“我真的不想为每个分支都设置这个设置或挂钩”,但解释是:

我们创建自己的本地分支,从主分支中分离出来来完成任务。在 VS 中,这是“从...创建本地分支”,它使用所需名称执行分支的检出。 在引擎盖下,我确信这相当于git checkout -b fillcatnip masterfillcatnip 是一个未跟踪的本地分支,直到推送到远程,但它将作为新分支 fillcatnip 而不是原始 master 推送。此时,它成为一个跟踪分支,并且可以在任务完成时向其提供一个拉取请求 (PR) 以合并回master。 但是,如果master 在 PR 可以完成之前继续前进并发生冲突,则在解决冲突之前无法合并分支。发生这种情况时,我可能已经开始了另一项任务。因此,如果我保存我当前正在进行的任务(提交和推送、存储等),然后切换回冲突的分支,我想要该分支的远程副本而不是我自己的本地副本,因为有人可能已经推送在等待合并时对其进行更改。

【问题讨论】:

    标签: git branch git-pull


    【解决方案1】:

    这两个问题的答案是“不完全”和“否”,但也有“通常没有必要”,而事实上,问题本身并没有多大意义。第一个也是最大的问题在于“如果本地是干净的”这句话——这究竟是什么意思?

    如果“干净”是指git status 报告的内容:

    On branch master
    Your branch is up-to-date with 'origin/master'.
    
    nothing to commit, working tree clean
    

    那么“干净”指的是工作树,有时可能指的是索引,与彼此和/或HEAD提交相比。

    除非您使用git worktree add 创建辅助工作树,否则任何给定的 Git 存储库都只有 一个 工作树(和一个相应的索引)。 (如果您确实使用git worktree add,每个添加的工作树都在其自己的单独分支上。这实际上可能是您真正想要的答案,在这里。)

    我们还要注意,像masterfeature 这样的分支name 表示一个特定的提交,Git 将其称为该分支的tip 提交。 “分支”一词还有其他含义:参见What exactly do we mean by "branch"? 但是当您签出一个分支时,这意味着您也签出了一个特定的commit。该提交的内容填充索引和工作树。

    切换分支或“分离的 HEAD”的命令是 git checkout。它通过写入索引和工作树来完成分支切换(或 HEAD 分离),以实现从之前签出的提交到您将签出的提交的切换现在。如果工作树在git checkout之前是干净的,这总是可能的,并且工作树在git checkout 之后之后也是干净的。 p>

    如果工作树在git checkout 之前干净,则有时(但并非总是)仍然可以切换分支:请参阅Checkout another branch when there are uncommitted changes on the current branch。在这种情况下,工作树通常也会在git checkout 切换分支之后不干净。不干净是因为签出在切换分支时不必更新与您在运行git checkout <em>branchname</em> 之前签出的提交不匹配的文件的索引和工作树条目。

    检查工作树是否干净

    除了上面的内容,请注意 git-sh-setup,一个可用于其他 Git 脚本的脚本,包括 a function named require_clean_work_tree。您可以检查此代码,或者直接使用它来确定工作树是否干净。

    您可以将它与phd's answer about using a post-checkout hook 结合起来进行检查,如果合适,运行git mergegit fetch &amp;&amp; git merge。 (我建议完全避免git pull:像这样把它分解成两个独立的步骤。之后你的生活会更快乐。)

    为什么我怀疑你根本不需要这个

    (我们的分支经常被创建和删除,因为公司政策是每个任务一个分支,在审查时被 PR 和合并)

    作为一般规则,如果您不打算在命名分支上工作(在其上进行新提交),则不应首先创建它。没有创建它,您也不必担心更新它。

    例如,假设您有一个存储库,其中有一个名为origin 的远程服务器,并且在origin 上,有用于各种任务的分支。您想偶尔检查 origin/task/feedkittens,但处理(单个)任务task/fillcatnip

    在这种情况下,要检查事物,请继续使用“分离 HEAD”模式:

    git checkout origin/task/feedkittens
    

    处理事情,请使用git checkout创建 task/fillcatnip 来自 origin/task/fillcatnip

    git checkout task/fillcatnip
    

    这是因为git checkout 会在您要求它检查一个不存在 的分支时,搜索另一个名称相同的origin/ 分支。如果是这样,它将创建本地分支,使得分支提示提交与远程跟踪名称的提交相同。同时,它会将本地分支设置为track(将其作为上游)远程跟踪名称。

    通过创建本地分支名称,您现在可以创建新提交。这些将使本地分支

    通过避免创建task/feedkittens,您只需运行git fetchgit checkout origin/task/feedkittens 即可查看最新信息。您将处于“分离 HEAD”模式,因此现在创建 new 提交通常不是一个好主意,但这意味着无需在本地分支周围拖动。

    当在origin 上删除名为task/feedkittens 的分支时,您可以通过设置在git fetch 期间自动删除您自己的远程跟踪名称:

    git config fetch.prune true
    

    只要您git checkout 某个其他提交或名称,您就不会在不再有名称的origin/task/feedkittens 提交上被分离-HEAD。

    如果您想同时处理(如“添加提交”)多个不同的分支,请考虑使用git worktree add,只要您的 Git 版本至少为 2.5。每个添加的工作树都有自己的私有索引,但所有添加的工作树共享单个底层存储库。如果您的 Git 太旧,请考虑为您要同时处理的每个分支制作单独的克隆。

    【讨论】:

    • 嗨 torek,为了清楚起见,我已经对问题进行了编辑。感谢您的详细回答和建议
    • 啊哈。 VS 可能会阻止您使用 git worktree add,但通常这将是 建议的方式。
    【解决方案2】:

    你需要一个git hook——在你的情况下它是post-checkout hook。在你调用git pull的钩子中。

    类似这样的:

    #!/bin/sh
    
    prev_HEAD="$1"
    new_HEAD="$2"
    new_branch="$3"
    
    if [ "$new_branch" = 1 ]; then
        git pull origin "$new_HEAD"
    fi
    
    exit 0
    

    【讨论】:

    猜你喜欢
    • 2013-10-17
    • 2012-10-31
    • 2022-07-21
    • 2021-06-11
    • 1970-01-01
    • 2013-06-01
    • 2015-11-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多