简体   繁体   中英

Git pull from remote bare repository

When I try to pull from a bare remote repository, git returns Already up-to-date .

As far as I understand, 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 (working tree of which has been properly configured) and merge them with the local ones overwriting changes?

If the local repository has been changed and those changes are committed, pushing of course works - pulling, on the other hand, does not. 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.

What am I doing wrong?

Edit , providing more information about what I would like to do.

I do have a local repository containing two files, foo.c and foo.exe , and a bare remote repository configured with a post-receive hook to place all the pushed files into a working tree.

After issuing git push remote master , I can see both foo.c and foo.exe on the working tree directory. If any of the two files are modified on the local repository, git add . and git commit -m "commit" would track the modified files and a subsequent git push remote master would update the files on the server.

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?

UPDATED BASED ON EDITS TO QUESTION

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

So I understand this to mean that you initialized the repo as --bare and then added a worktree (updating configuration to allow receipt of pushes that update the checked-out branch) so that pushes would effectively deploy your executable.

So you originally said

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.

and later added

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?

So the problem here is what it means to say something was "added to the remote repository".

Every repo (bare or otherwise) works the same. You think of the server repo as a remote because it's configured as such in your clone, but on the server, it's just a local repo that happens to be set up to react to pushes in a certain way.

So you know that if you put a file in your local worktree, but you don't add and commit it, it won't get shared with other repos. The same is true on the server. Putting foo.h on the server just means there's an untracked file in the worktree. (And you want to be careful with having untracked changes on the server; they may cause confusion on future push attempts.)

The push and fetch operations share refs and objects (commits and their dependencies) between databases. These operations don't care what's on the "sending side's" work tree. Other than possibly safeguards to avoid clobbering files, they also don't care much about what's on the "receiving side's" work tree.

In short: yes, on the server you would have to add and commit the file, creating a new commit on the branch, before a pull on the workstation would get anything.


The part of my original answer that isn't wrapped into the above continues from here:

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

More precisely, pull does a fetch and a 'merge', and you're asking shouldn't fetch bring in the files from the remote for the merge . And the answer is: only if they've changed since your previous fetch / pull . The message "Already up-to-date" means that there are no changes on the remote side, beyond those you've already fetch ed, so there's nothing new to merge with. Consider:

The remote contains some commits

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 fetch ed C in the first place).

git fetch/push do not operate on files. They operate on commits. There is a bunch of commits on remote (it doesn't matter if it's bare or not). If you changed some files locally and made a commit, there is a difference between your local repository and a remote one.

In your case you already have locally all commits available on remote, so there is nothing to fetch. That's why up-to-date message.

If you run git status in such situation, you will however get an information, that you have some changes in local repository not being shared to the remote one:

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

When you publish you changes as suggested, both repositories - local and remote - will have the same commits (assuming no one else is modifying the remote one) so, again, pull wont fetch anything, ss those changes are already available locally.

However, the situation would be different, if you have some commits on the remote repository, but not on the local one.

git fetch will fetch those commits, but it won't modify the files in your workspace. To modify the files you need to manually move to the new commit. For example by running git merge command - it will either merge freshly fetched changes to the local branch and change active commit to the one of the tip of local branch. It's worth to note that merge only merges changes not available yet on your current branch. So, if you have some commit in the past and run git merge old_commit_id , nothing would happened.

git pull works like git fetch + git merge for current branch. So, if there are commits on remote, they would be fetched. Then if for current branch there are changes from remote branch, but not yet on current branch, they will be merged.

It is worth to play with gitg or gitk tool to visualise the graph of commits and branch labels to better understand what's going on inside.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM