Git 从远程裸仓库拉取

Git pull from remote bare repository

当我尝试从裸远程存储库 pull 时,git returns Already up-to-date.

据我了解,如果本地存储库有一些更改,并且我提交它们从而推进 HEAD,不应该 pull 从裸远程存储库中获取不同的文件(已正确配置的工作树)并将它们与本地的合并以覆盖更改?

如果本地存储库已更改并且已提交这些更改,则推送当然有效 - 另一方面,拉取则无效。如果远程存储库更改并且我从中 pullfetch --allclone,我要么得到相同的 up-to-date 消息,要么收到旧的 files/previously 推送文件。

我做错了什么?

编辑,提供更多关于我想做什么的信息。

我有一个包含两个文件的本地存储库,foo.cfoo.exe,以及一个配置了 post-receive 挂钩的裸远程存储库,用于将所有推送的文件放入一棵工作树。

发出git push remote master后,我可以在工作树目录中看到foo.cfoo.exe。如果在本地存储库中修改了两个文件中的任何一个,git add .git commit -m "commit" 将跟踪修改后的文件,随后的 git push remote master 将更新服务器上的文件。

如果在服务器上添加了 foo.h,无论如何,我尝试 git fetch remote master,git 说本地分支是最新的并且没有合并(这用本地文件替换获取的提交文件,是吗?)是必需的。怎么会这样?我需要先在远程存储库上提交更改吗?

根据对问题的编辑更新

...from the bare remote repository (working tree of which has been properly configured)...

所以我理解这意味着你将 repo 初始化为 --bare 然后添加了一个 worktree (更新配置以允许接收更新签出分支的推送)以便推送将有效地部署您的可执行文件。

原来你说的是

If the remote repository changes and I pull, fetch --all or clone from it, I either get the same up-to-date message or the old files/previously pushed files.

后加

If a foo.h is added on the server, anyhow, and I try to git fetch remote master, git says the local branch is up-to-date and no merging (which replaces the fetched commit files with the local ones, yes?) is required. How come is that so? Do I need to first commit the changes on the remote repository?

所以这里的问题是“添加到远程存储库”是什么意思。

每个回购协议(裸或其他)都一样。您认为服务器存储库是远程的,因为它在您的克隆中是这样配置的,但在服务器上,它只是一个本地存储库,恰好设置为以某种方式对推送做出反应。

所以你知道如果你把一个文件放在你的本地工作树中,但你不添加和提交它,它就不会与其他存储库共享。在服务器上也是如此。将 foo.h 放在服务器上只意味着工作树中有一个未跟踪的文件。 (并且您要小心服务器上的未跟踪更改;它们可能会在未来的推送尝试中造成混淆。)

pushfetch 操作在数据库之间共享引用和对象(提交及其依赖项)。这些操作不关心“发送端”的工作树上有什么。除了可能避免破坏文件的安全措施外,他们也不太关心“接收方”工作树上的内容。

简而言之:是的,在服务器上您必须添加并提交文件,在分支上创建一个新的提交,然后在工作站上拉取任何东西。


我的原始答案中没有包含在上面的部分从这里继续:

if the local repository has some changes, and I commit them thus advancing the HEAD, shouldn't pull fetch the different files from the bare remote repository

更准确地说,pull 做了一个 fetch 和一个 'merge',你问的是不应该 fetch 从远程导入文件merge。答案是:只有在您之前 fetch/pull 之后它们发生了变化。消息“已经是最新的”意味着远程端没有任何变化,除了你已经 fetched 的那些,所以没有新的东西可以合并。考虑:

远程包含一些提交

A --- B --- C <--(master)

You clone the repo, or fetch into an existing clone, and so now you have the same; then you do some work and commit it

A --- B --- C <--(origin/master)
             \
              D <--(master)

Now you pull, and that causes a fetch. But fetch doesn't directly download files - it downloads commits. You already have all the commits that are in the origin, so there's nothing to download; which is fine, because the histories of the files (as they appear in origin) have already been accounted for (from when you fetched C in the first place).

git fetch/push 不对文件进行操作。他们对提交进行操作。远程上有一堆提交(裸露与否无关紧要)。如果您在本地更改了一些文件并进行了提交,则您的本地存储库和远程存储库之间存在差异。

在您的情况下,您已经在本地拥有远程可用的所有提交,因此无需获取任何内容。这就是 最新 消息的原因。

如果你 运行 git status 在这种情况下,你会得到一条信息,你在本地存储库中有一些更改没有共享到远程存储库:

On branch master
Your branch is ahead of 'origin/master' by 1 commit.
  (use "git push" to publish your local commits)

nothing to commit, working directory clean

当您按照建议发布您的更改时,两个存储库 - 本地和远程 - 将有相同的提交(假设没有其他人正在修改远程的)所以,再一次,拉不会获取任何东西,ss 这些更改已经本地可用。

但是,如果您在远程存储库上有一些提交,但在本地存储库上没有,情况会有所不同。

git fetch 将获取这些提交,但不会修改您工作区中的文件。要修改您需要手动移动到新提交的文件。例如,通过 运行ning git merge 命令 - 它会将新获取的更改合并到本地分支并将活动提交更改为本地分支的尖端之一。值得注意的是 merge 仅合并当前分支上尚不可用的更改。所以,如果你过去有一些提交并且 运行 git merge old_commit_id,什么都不会发生。

git pull 对当前分支的作用类似于 git fetch + git merge。因此,如果远程有提交,它们将被提取。然后如果对于当前分支有来自远程分支的更改,但还没有在当前分支上,它们将被合并。

值得使用 gitggitk 工具来可视化提交和分支标签的图形,以更好地了解内部发生的事情。