为什么 Git 只是在没有 --force 标志的情况下执行强制更新?
Why did Git just perform a forced update without the --force flag?
昨天我们在工作中遇到了一件非常奇怪的事情。我对存储库进行了一些更改,提交并调用了 git push
,就像我一直做的那样。事情是这样的:
user@host:~/path/to/repo$ git add file_a.h
user@host:~/path/to/repo$ git add file_b.h
user@host:~/path/to/repo$ git add file_c
user@host:~/path/to/repo$ git add file_d.h
user@host:~/path/to/repo$ git commit
[master a9c4595] Perform change requested by customer.
4 files changed, 4 insertions(+), 4 deletions(-)
user@host:~/path/to/repo$ git push
Enumerating objects: 17, done.
Counting objects: 100% (17/17), done.
Delta compression using up to 4 threads
Compressing objects: 100% (9/9), done.
Writing objects: 100% (9/9), 845 bytes | 845.00 KiB/s, done.
Total 9 (delta 8), reused 0 (delta 0)
To ssh://git.corp.com:port/project/repo.git
+ 38a09ed...a9c4595 master -> master (forced update)
+ 38a09ed...a9c4595 38 -> 38 (forced update)
user@host:~/path/to/repo$ git log
具体观察(forced update)
注意那里。我的同事就在我之前将更改推送到此存储库,在我使用 Git 约 7 年的时间里,每次发生这种情况时,Git 都会警告我遥控器有我不知道的更改没有,并要求我先拉再推。 为什么现在没有发生这种情况? Git 而是删除了我同事在远程上的提交,并用我自己的 HEAD^
替换了它。将来我将如何预防这种情况?
其他详细信息:我们的 Git 工作流程,在与其他项目的集成方面,依赖于标签,因此我们有一个 post-commit
挂钩,如下所示:
#!/bin/bash
tag_ver="$(git describe --tags --match 0 | cut -d'-' -f2)"
git rev-list HEAD | head -n1 | xargs git tag $tag_ver
所以每次提交时,它只是将标记递增一个。
正如您在 中所说:
I might have just found the culprit. git config -l
revealed the following line: remote.origin.push=+refs/heads/*
确实是这个原因。正如 the git push
documentation 所说:
When the command line does not specify what to push with <refspec>...
arguments or --all
, --mirror
, --tags
options, the command finds the
default <refspec>
by consulting remote.*.push
configuration, and if it
is not found, honors push.default
configuration to decide what to push
(See git-config(1) for the meaning of push.default
).
出于 git push
目的,省略冒号的 refspec 有效地重复了 <src>
部分,因此您的 remote.origin.push
使 git push origin
表现得像 git push origin +refs/heads/*:refs/heads/*
.前导 +
符号设置此 refspec 的强制标志。
昨天我们在工作中遇到了一件非常奇怪的事情。我对存储库进行了一些更改,提交并调用了 git push
,就像我一直做的那样。事情是这样的:
user@host:~/path/to/repo$ git add file_a.h
user@host:~/path/to/repo$ git add file_b.h
user@host:~/path/to/repo$ git add file_c
user@host:~/path/to/repo$ git add file_d.h
user@host:~/path/to/repo$ git commit
[master a9c4595] Perform change requested by customer.
4 files changed, 4 insertions(+), 4 deletions(-)
user@host:~/path/to/repo$ git push
Enumerating objects: 17, done.
Counting objects: 100% (17/17), done.
Delta compression using up to 4 threads
Compressing objects: 100% (9/9), done.
Writing objects: 100% (9/9), 845 bytes | 845.00 KiB/s, done.
Total 9 (delta 8), reused 0 (delta 0)
To ssh://git.corp.com:port/project/repo.git
+ 38a09ed...a9c4595 master -> master (forced update)
+ 38a09ed...a9c4595 38 -> 38 (forced update)
user@host:~/path/to/repo$ git log
具体观察(forced update)
注意那里。我的同事就在我之前将更改推送到此存储库,在我使用 Git 约 7 年的时间里,每次发生这种情况时,Git 都会警告我遥控器有我不知道的更改没有,并要求我先拉再推。 为什么现在没有发生这种情况? Git 而是删除了我同事在远程上的提交,并用我自己的 HEAD^
替换了它。将来我将如何预防这种情况?
其他详细信息:我们的 Git 工作流程,在与其他项目的集成方面,依赖于标签,因此我们有一个 post-commit
挂钩,如下所示:
#!/bin/bash
tag_ver="$(git describe --tags --match 0 | cut -d'-' -f2)"
git rev-list HEAD | head -n1 | xargs git tag $tag_ver
所以每次提交时,它只是将标记递增一个。
正如您在
I might have just found the culprit.
git config -l
revealed the following line:remote.origin.push=+refs/heads/*
确实是这个原因。正如 the git push
documentation 所说:
When the command line does not specify what to push with
<refspec>...
arguments or--all
,--mirror
,--tags
options, the command finds the default<refspec>
by consultingremote.*.push
configuration, and if it is not found, honorspush.default
configuration to decide what to push (See git-config(1) for the meaning ofpush.default
).
出于 git push
目的,省略冒号的 refspec 有效地重复了 <src>
部分,因此您的 remote.origin.push
使 git push origin
表现得像 git push origin +refs/heads/*:refs/heads/*
.前导 +
符号设置此 refspec 的强制标志。