Git push only one file

帅比萌擦擦* 提交于 2019-12-11 02:34:49

问题


We have a public repo where everybody pushes. We sometimes want to pull&push a single file without pulling the whole remote and pushing the whole merged local. I know a push must be a fast-forward, can we just fast-forward a single file?

Is this possible? If not, why (by design?)?


回答1:


First, you're misusing Git terminology. A ref or reference is simply a name, such as refs/heads/master (the full name of the branch-name master) or refs/tags/v1.2 (the full name of the tag v1.2).

Next: git push does not push files. What git push sends are:

  • commits and/or annotated tags, and all other required objects as needed;
  • a sequence of reference update requests (the default) or commands (--force).

It's up to the receiving server to decide whether to obey these requests or commands. The default for a request to update a branch name—a reference within the refs/heads/ namespace—is to obey a polite request if and only if it is a fast-forward operation, and to obey any command (any forced update). Files are completely irrelevant here. A branch name update is a fast-forward operation if and only if the new commit hash ID has the old commit hash ID as an ancestor.1

To push a single reference, just do that:

git push <remote> <local-name>:<remote-name>

To push more than one, just do that:

git push <remote> <l1>:<r1> <l2>:<r2> ... <ln>:<rn>

(Omitting a name after the colon in git push means that the other Git should use the same name that you are using in your local Git.)

The files that come along with any commit are those in the commit's snapshot. Since you can only push commits (not files), it's not possible to push a file.

(You could, of course, use something other than Git to send a file to a server, and have the server update the file in place. But in this case there's no need to ask about Git at all!)


1Git maintains a Directed Acyclic Graph or DAG of commits (and in fact all objects, but commits are the ones of interest here). The result of a push is a change to the DAG. If the change is a pure addition, no commits will be lost. Such an update is by definition a fast-forward and hence allowed. If the change results in some commits becoming unreachable from the updated reference, the change is by definition a non-fast-forward and hence polite-request updates are refused by default.

Whether a non-fast-forward update actually loses commits depends on whether those commits are reachable via some other external name. That is harder to compute—not impossible, just not immediately obvious by looking at the one reference being updated. Hence the design principle of requiring fast-forward updates by default.

In short, Git is really doing graph theory.



来源:https://stackoverflow.com/questions/51308289/git-push-only-one-file

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!