我们有一个公共(public)仓库,每个人都在 push 。我们有时想要 pull 和推送单个文件,而不需要 pull 整个远程文件并推送整个 merge 的本地文件。我知道推送必须是快进,我们可以只快进单个文件吗?
这可能吗?如果不是,为什么(有意为之?)?
最佳答案
首先,您误用了 Git 术语。 ref 或 reference 只是一个名称,例如 refs/heads/master
(分支名称 master 的全名)
)或refs/tags/v1.2
(标签的全名v1.2
)。
下一步:git push
不会推送文件。 git Push
发送的内容是:
- 根据需要提交和/或带注释的标签以及所有其他必需的对象;
- 一系列引用更新请求(默认)或命令 (
--force
)。
由接收服务器决定是否遵守这些请求或命令。更新分支名称(refs/heads/
命名空间内的引用)的请求的默认设置是当且仅当它是快进操作时服从礼貌请求,并服从任何命令(任何强制更新)。 文件在这里完全不相关。当且仅当新提交哈希 ID 以旧提交哈希 ID 作为祖先时,分支名称更新才是快进操作。1
要推送单个引用,只需执行以下操作:
git push <remote> <local-name>:<remote-name>
要推送多个,只需执行以下操作:
git push <remote> <l1>:<r1> <l2>:<r2> ... <ln>:<rn>
(在 git push 中省略冒号后的名称意味着其他 Git 应该使用与您在本地 Git 中使用的名称相同的名称。)
任何提交附带的文件都是提交快照中的文件。由于您只能推送提交(不能推送文件),因此无法推送文件。
(当然,您可以使用 Git 之外的其他方式将文件发送到服务器,并让服务器就地更新文件。但在这种情况下,无需询问完全使用 Git!)
1Git 维护着一个定向A循环G提交图或 DAG(事实上所有提交)对象,但提交是这里感兴趣的)。推送的结果是 DAG 的更改。如果更改是纯粹的添加,则不会丢失任何提交。根据定义,这样的更新是快进的,因此是允许的。如果更改导致某些提交无法从更新的引用中访问,则根据定义,该更改是非快进的,因此默认情况下会拒绝礼貌请求更新。
非快进更新是否实际上丢失提交取决于这些提交是否可以通过其他外部名称访问。这更难计算——并非不可能,只是通过查看正在更新的一个引用并不能立即明显看出。因此默认要求快进更新的设计原则。
关于Git 只推送一个文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51308289/