当前位置:  开发笔记 > 开发工具 > 正文

git pull --force的行为

如何解决《gitpull--force的行为》经验,为你挑选了1个好方法。

我的本地master分支比origin / master提前两个提交

我想保留这两个提交,并将本地主机与源同步。总的来说,这些命令将达到什么目的?

git checkout -b "branch-to-save-my-two-commits"
git pull origin master --force

torek.. 5

为了从主题行到其余问题:

git pull只需运行,git fetch然后再执行第二个Git命令即可。第二个命令默认为,git merge但可以配置为git rebase。因此,知道什么git pull会做,你应该阅读的git pull手册页,看看传递哪些选项,git fetch并且被改为传递给第二个命令,然后根据需要读取其他相应手册页。

这就是git pull手册页关于-f/的内容--force

-f--force
       当git fetch:refspec一起使用时,除非它获取的远程分支是的后代,否则它拒绝更新本地分支。此选项将覆盖该检查。

该文档不是那么好,因为它在没有定义引用规范的情况下进行讨论。但是您没有使用完整的refspec,因此答案是--force最终被完全忽略了。

git checkout -b "branch-to-save-my-two-commits"

假设它不会出错,它会创建一个新分支名称,指向当前(HEAD)提交。它没有做任何其他事情,因此索引/暂存区从现在起就保持不变,而工作树从现在起就保持不变。没有创建新的提交,但是您当前的分支已更改。 git rev-parse HEAD产生与以前相同的提交ID,但是git symbolic-ref HEAD产生新创建的分支的名称。

git pull origin master --force

如上所述,由于refspec(master)不具有完整:格式,因此该--force标志无效。和以前一样,我们将假定所有操作均已完成且没有错误。

因此,获取步骤就可以记录远程命名的URL抓取origin,带来过任何提交他们 master是不是已经在你的仓库。他们master的分支提示提交ID FETCH_HEAD照常放置在您的Git 文件中,如果您的Git版本是1.8.4或更高版本,您的Git也会更新您的origin/master远程跟踪分支。

你之后git fetch成功完成,您的Git无论运行git merge还是git rebase取决于你之前的命令进行配置。如果未使用任何此类配置命令,则默认为running git merge。对于此答案,我将假定您尚未配置它运行git rebase

尽管to的实际参数git merge有些复杂(pull代码使用剩余的数据,FETCH_HEAD而不是直接使用remote-tracking分支),但效果至少在Git 1.8.4及更高版本中与运行时基本相同:

git merge origin/master

也就是说,合并到当前分支(您刚刚用自己创建的分支)中,git checkout -b现在由just-updated标识的提交origin/master。Git将在HEAD和之间找到合并基础origin/master

如果此合并基础与相同的提交origin/master,则Git根本不执行任何操作(除了打印一条没有任何内容可合并的消息外)。(可能是这种情况;请参阅下文。)

否则,如果此合并库本身不是与相同的提交HEAD,则Git将继续进行常规合并。首先,它将计算两个差异:merge-base至HEAD和merge-base至origin/master。然后,它将组合这些差异以产生所有文件的单个“我们的更改及其更改”版本,并使用结果树在当前分支上进行新的合并提交。(这是另一种可能的情况;请参见下文。)

如果该合并的基础一样的承诺HEAD,但就是不一样犯的origin/master,Git会做一个快进伪合并:所以它指向的提示,将移动当前分支标签提交的origin/master,并检查提交了进入索引和工作树。(根据您的设置,这不太可能;请参阅下文。)

(请注意,如果索引或工作树在a git merge或开始时是脏的git pull,则操作本身将失败。因此,如果git checkout -b留下脏索引或工作树,则不会发生合并。)

您想做什么

我的本地master分支比origin / master提前两个提交。

如果是这种情况,并且您在master运行时处于打开状态git checkout -b branch-to-save-my-two-commits,那么我们可以像这样绘制新分支后的提交图片段:

...--o--o        <-- origin/master
         \
          o--o   <-- HEAD->branch-to-save-my-two-commits, master

git fetch然后,该步骤将不执行任何操作-我假设当您说您master是两次提交时origin/master,您的意思是您还检查了另一个 Git,即位于的Git origin没有新的提交。(如果确实带来了新的提交,则他们将修改此图,并在第一行添加更多的提交。)

给定fetch什么都不做,我们然后可以说出该merge步骤的作用:HEAD指向比origin/master; 晚的提交。合并基础是的技巧origin/master; 合并只是说您是最新的,什么也不做。这使您保持与以前相同的状态。

fetch但是,如果带来了一些新的承诺,我们将获得更多类似的东西。假设它仅带来一次提交:

...--o--*---o    <-- origin/master
         \
          A--B   <-- HEAD->branch-to-save-my-two-commits, master

这一次,合并的基础是相同的承诺像以前一样,我已经标记为*这个时间,但origin/master指向提交,所以东西合并。Git会尝试从合并的diff *到尖OF- origin/master从diff文件*HEAD。假设成功,Git将进行包含此合并的新提交,并指向新提交origin/master和先前提交HEAD

...--o--*---o   <-- origin/master
         \   \
          A   o  <-- HEAD->branch-to-save-my-two-commits
           \ /
            B   <-- master

我还标有两个“被保留”提交A,并B在这里,这样可以更明显发生了什么:我们移动B向下绘制只是让我们能继续保持一条线master指向它,即使HEADbranch-to-save-my-two-commits已转移到一点到新的合并提交。

我想保留这两个提交,并将本地主机与源同步。

在这种情况下,您运行的是:1

git checkout -b newbranch
git fetch origin
git branch -f master origin/master

与前面一样,第一个命令创建一个指向当前提交的新分支,并将您置于新分支上(这样您就不再位于branch上master)。

第二个命令将更新您的local 分支origin/master和任何其他origin/*远程跟踪分支,作为几乎免费的奖励。(获取所有内容只需要一点额外的时间,但是现在获取它们所花的时间少于以后获取任何其他此类东西所花费的时间,因此您最好现在就执行。)

最后一条命令强行将您master指向刚刚更新的origin/master。这将是不安全的有我们不只是取得了新的分支指向当前提交(再次,我假设这里master指着当我们开始这整个过程)。


1您还可以使用其他几种形式,包括您正在考虑/被指示使用的形式:

git checkout -b newbranch
git fetch --force origin master:master

请注意,这使用git fetch,而不是git pull。我对git pull命令了解的最好建议是:不要使用它。这是为了方便,但实际上并不是很方便。



1> torek..:

为了从主题行到其余问题:

git pull只需运行,git fetch然后再执行第二个Git命令即可。第二个命令默认为,git merge但可以配置为git rebase。因此,知道什么git pull会做,你应该阅读的git pull手册页,看看传递哪些选项,git fetch并且被改为传递给第二个命令,然后根据需要读取其他相应手册页。

这就是git pull手册页关于-f/的内容--force

-f--force
       当git fetch:refspec一起使用时,除非它获取的远程分支是的后代,否则它拒绝更新本地分支。此选项将覆盖该检查。

该文档不是那么好,因为它在没有定义引用规范的情况下进行讨论。但是您没有使用完整的refspec,因此答案是--force最终被完全忽略了。

git checkout -b "branch-to-save-my-two-commits"

假设它不会出错,它会创建一个新分支名称,指向当前(HEAD)提交。它没有做任何其他事情,因此索引/暂存区从现在起就保持不变,而工作树从现在起就保持不变。没有创建新的提交,但是您当前的分支已更改。 git rev-parse HEAD产生与以前相同的提交ID,但是git symbolic-ref HEAD产生新创建的分支的名称。

git pull origin master --force

如上所述,由于refspec(master)不具有完整:格式,因此该--force标志无效。和以前一样,我们将假定所有操作均已完成且没有错误。

因此,获取步骤就可以记录远程命名的URL抓取origin,带来过任何提交他们 master是不是已经在你的仓库。他们master的分支提示提交ID FETCH_HEAD照常放置在您的Git 文件中,如果您的Git版本是1.8.4或更高版本,您的Git也会更新您的origin/master远程跟踪分支。

你之后git fetch成功完成,您的Git无论运行git merge还是git rebase取决于你之前的命令进行配置。如果未使用任何此类配置命令,则默认为running git merge。对于此答案,我将假定您尚未配置它运行git rebase

尽管to的实际参数git merge有些复杂(pull代码使用剩余的数据,FETCH_HEAD而不是直接使用remote-tracking分支),但效果至少在Git 1.8.4及更高版本中与运行时基本相同:

git merge origin/master

也就是说,合并到当前分支(您刚刚用自己创建的分支)中,git checkout -b现在由just-updated标识的提交origin/master。Git将在HEAD和之间找到合并基础origin/master

如果此合并基础与相同的提交origin/master,则Git根本不执行任何操作(除了打印一条没有任何内容可合并的消息外)。(可能是这种情况;请参阅下文。)

否则,如果此合并库本身不是与相同的提交HEAD,则Git将继续进行常规合并。首先,它将计算两个差异:merge-base至HEAD和merge-base至origin/master。然后,它将组合这些差异以产生所有文件的单个“我们的更改及其更改”版本,并使用结果树在当前分支上进行新的合并提交。(这是另一种可能的情况;请参见下文。)

如果该合并的基础一样的承诺HEAD,但就是不一样犯的origin/master,Git会做一个快进伪合并:所以它指向的提示,将移动当前分支标签提交的origin/master,并检查提交了进入索引和工作树。(根据您的设置,这不太可能;请参阅下文。)

(请注意,如果索引或工作树在a git merge或开始时是脏的git pull,则操作本身将失败。因此,如果git checkout -b留下脏索引或工作树,则不会发生合并。)

您想做什么

我的本地master分支比origin / master提前两个提交。

如果是这种情况,并且您在master运行时处于打开状态git checkout -b branch-to-save-my-two-commits,那么我们可以像这样绘制新分支后的提交图片段:

...--o--o        <-- origin/master
         \
          o--o   <-- HEAD->branch-to-save-my-two-commits, master

git fetch然后,该步骤将不执行任何操作-我假设当您说您master是两次提交时origin/master,您的意思是您还检查了另一个 Git,即位于的Git origin没有新的提交。(如果确实带来了新的提交,则他们将修改此图,并在第一行添加更多的提交。)

给定fetch什么都不做,我们然后可以说出该merge步骤的作用:HEAD指向比origin/master; 晚的提交。合并基础是的技巧origin/master; 合并只是说您是最新的,什么也不做。这使您保持与以前相同的状态。

fetch但是,如果带来了一些新的承诺,我们将获得更多类似的东西。假设它仅带来一次提交:

...--o--*---o    <-- origin/master
         \
          A--B   <-- HEAD->branch-to-save-my-two-commits, master

这一次,合并的基础是相同的承诺像以前一样,我已经标记为*这个时间,但origin/master指向提交,所以东西合并。Git会尝试从合并的diff *到尖OF- origin/master从diff文件*HEAD。假设成功,Git将进行包含此合并的新提交,并指向新提交origin/master和先前提交HEAD

...--o--*---o   <-- origin/master
         \   \
          A   o  <-- HEAD->branch-to-save-my-two-commits
           \ /
            B   <-- master

我还标有两个“被保留”提交A,并B在这里,这样可以更明显发生了什么:我们移动B向下绘制只是让我们能继续保持一条线master指向它,即使HEADbranch-to-save-my-two-commits已转移到一点到新的合并提交。

我想保留这两个提交,并将本地主机与源同步。

在这种情况下,您运行的是:1

git checkout -b newbranch
git fetch origin
git branch -f master origin/master

与前面一样,第一个命令创建一个指向当前提交的新分支,并将您置于新分支上(这样您就不再位于branch上master)。

第二个命令将更新您的local 分支origin/master和任何其他origin/*远程跟踪分支,作为几乎免费的奖励。(获取所有内容只需要一点额外的时间,但是现在获取它们所花的时间少于以后获取任何其他此类东西所花费的时间,因此您最好现在就执行。)

最后一条命令强行将您master指向刚刚更新的origin/master。这将是不安全的有我们不只是取得了新的分支指向当前提交(再次,我假设这里master指着当我们开始这整个过程)。


1您还可以使用其他几种形式,包括您正在考虑/被指示使用的形式:

git checkout -b newbranch
git fetch --force origin master:master

请注意,这使用git fetch,而不是git pull。我对git pull命令了解的最好建议是:不要使用它。这是为了方便,但实际上并不是很方便。

推荐阅读
放ch养奶牛
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有