git: updating the current branch

2019-07-14 09:19发布

There are 2 git repositories, A and B

On both there is only a master branch, and both are locally checked out and being worked on.

I am pushing into B's master branch from A and I receive this message:

warning: updating the current branch
warning: Updating the currently checked out branch may cause confusion,
warning: as the index and work tree do not reflect changes that are in HEAD.
warning: As a result, you may see the changes you just pushed into it
warning: reverted when you run 'git diff' over there, and you may want
warning: to run 'git reset --hard' before starting to work to recover.
warning: 
warning: You can set 'receive.denyCurrentBranch' configuration variable to
warning: 'refuse' in the remote repository to forbid pushing into its
warning: current branch.
warning: To allow pushing into the current branch, you can set it to 'ignore';
warning: but this is not recommended unless you arranged to update its work
warning: tree to match what you pushed in some other way.
warning: 
warning: To squelch this message, you can set it to 'warn'.
warning: 
warning: Note that the default will change in a future version of git
warning: to refuse updating the current branch unless you have the
warning: configuration variable set to either 'ignore' or 'warn'.

If I work on B's checked out master branch, how can I update it, so I see A's changes?

What if there are also changes in the local checkout of master on B already that are not commited?

Note: I do not really understand git's message above. Does "cause confusion" mean, it is bad and can lead to data loss? Or does it just mean it is a situation that is not easy to handle, but I can as usually trust that all my changes are kept somehow and I will be able to solve conflicts if necessary. What does "see the changes reverted" stand for? Does it mena some changes are lost?

For me as a foreigner this language is not very clear.

Edit: I just added a file on A and pushed it to B. On B I receive the status that the file is deleted.

What would be a simple workflow to handle the situation?

4条回答
放荡不羁爱自由
2楼-- · 2019-07-14 09:51

machineB has somebranch checked out, and you're pushing changes to somebranch from machineA to machineB, without updating machineB working-copy or index. The tree that's checked out on machineB will still be at a point before all of the changes you pushed.

Now if you go over to machineB and make changes and commit without doing a git reset --hard first, those changes will form a new commit that doesn't include all of the changes you did on machineA and somebranch will diverge. If instead of committing you did a git diff somebranch the diff should show all of the changes you did on machineA being undone on machineB because your checkout isn't at the head of the branch.

查看更多
何必那么认真
3楼-- · 2019-07-14 09:54

You get the error message because you push into a non-bare repository; see the Git FAQ for some details. The short solution is: Don't push into an git repository with a working directory; but use an bare repository as intermediary.

When you push into a branch, git updates the branch to reflect the new state of the branch. What it does not update are the index and the working directory (because you might have changes there and you would not be able to resolve conflicts anyway, from remote).

In your example, this means the following:

  • Initially, A and B have the same master branch
  • You add a file F in A's master branch, commit this change and push it to B's master branch
  • Now, B's master branch (which is checked out at the moment) contains F. But as git didn't touch B's working directory, F does not exist there
  • Hence, in B, git reports the file F as deleted: It is present in the HEAD commit, but not in the working directory.

As to your question about data-loss: You do not lose any data with this push. But, if you had any changes in your working directory, it might be hard to identify them, as git diff now shows the diff against the new state of branch. So, some of the changes are real changes, some of the changes are only displayed because the checkout was never updated to the current version

查看更多
疯言疯语
4楼-- · 2019-07-14 09:55

I think the problem is your remote repository 'A' is also working in the master branch. If you push new changes in the same branch, git will get confused. You have 2 options:

  • Re-create the A repository as 'bare': git init --bare

  • Checkout another branch in A (git checkout another_branch) and then try to push again from B

查看更多
ゆ 、 Hurt°
5楼-- · 2019-07-14 10:04

The kind of confusion that can be caused is like this: suppose you add lots of files in a commit on A's master and push that to B's master. Then if you change into the working tree of repository B and run git status it will say that all of those files you've just added have been deleted. Of course, they haven't been deleted - you've just updated the current branch and the working tree while the index haven't been touched. I think that counts as confusing for many people! (This is also what the message means by "see the changes reverted" - from git status it looks as if you've reverted the commits you've just pushed, just because the working tree and index is behind the branch now.)

In this case, if you're sure that git status in B was clean before you pushed into your master branch, you can reset the working tree and the index to match the new position of the branch with git reset --hard.

If you had uncommitted or unstaged changes in B, however, this suddenly gets doubly confusing, since those real changes will be difficult to tell from the "changes" that resulted from the push - disentangling those may be very difficult.

So, if you understand what's going on, and you're happy to deal with that situation, it's OK. Personally, I almost always try to avoid it by one of:

  • Pulling from A to B instead
  • Pushing to a bare repository from A, and then pulling from B
  • Pushing directly to another ref in B from A, as explained in this git FAQ entry, and the merging from that ref

I'd guess that one of the first two is what you want.

查看更多
登录 后发表回答