Git push error '[remote rejected] master -> master (branch is currently checked out)'

前端 未结 30 2174
半阙折子戏
半阙折子戏 2020-11-22 00:07

Yesterday, I posted a question on how to clone a Git repository from one of my machines to another, How can I \'git clone\' from another machine?.

I am now

相关标签:
30条回答
  • 2020-11-22 00:29

    I just had the same error while I began learning Git. Some of the other answers are clearly not for someone new to Git!

    (I am going to use non technical terms to get the idea across.) Anyway, what is happening is that you have two repositories, one is the original you first made, and the other the work one you just made.

    Right now you are in your work repository and are using the "master" branch. But you also happen to be "logged in" in your original repository to the same "master" branch. Now since you're "logged in" in the original, Git fears you might mess up because you might be working on the original and screw things up. So you need to return to the original repository and do a "git checkout someotherbranch", and now you can push with no problems.

    I hope this helps.

    0 讨论(0)
  • 2020-11-22 00:31

    I had to re-run git --init in an existing bare repository, and this had created a .git directory inside the bare repository tree - I realized that after typing git status there. I deleted that and everything was fine again :)

    (All these answers are great, but in my case it was something completely different (as far as I can see), as described.)

    0 讨论(0)
  • 2020-11-22 00:31

    With Git, two regular (non-bare) repositories can't push/pull files back and forth directly. There must be an intermediary bare repository. Apparently, it's sort of like a married couple who have a kid, and the couple is getting divorced. The parents won't talk to each other, but they will communicate through the kid.

    So, you have one repository, you clone this repository to a bare repository, and then you clone that to a third. The first and the third can exchange information via the second repository, the bare one. I guess this makes sense, as you wouldn't want someone able to check stuff into your repository without your consent, as that could cause merge conflicts & the like.

    So, here's an example:

    On PC, in ~/workspace

    git init
    echo "line 1" > afile.txt
    git add .
    git commit -m ‘initial import’
    git clone --bare . ../remote-repository.git
    git remote add origin ../remote-repository.git
    git push --set-upstream origin master
    

    On laptop, in ~/workspace (do not do git init, etc.)

    git clone //LJZ-DELLPC/remote-repository.git/ .
    

    // Then make various commits, and push them:

    echo "line 2" > afile.txt
    git add afile.txt
    git commit -m 'added line 2'
    git push    
    

    Then back on PC, in ~/workspace

    git pull
    

    // Then make various commits, and push them:

    git push
    

    On laptop git pull

    and so forth..

    Here's an absolute concrete example all on one machine, copied straight from the command window, so that we'll know that no steps were left out, that it really did work, etc:

    lylez@LJZ-DELLPC ~
    $ cd gitdir
    /home/lylez/gitdir
    
    lylez@LJZ-DELLPC ~/gitdir
    $ ls
    
    lylez@LJZ-DELLPC ~/gitdir
    $ mkdir repo1
    
    lylez@LJZ-DELLPC ~/gitdir
    $ cd repo1
    /home/lylez/gitdir/repo1
    
    lylez@LJZ-DELLPC ~/gitdir/repo1
    $ git init
    Initialized empty Git repository in /home/lylez/gitdir/repo1/.git/
    
    lylez@LJZ-DELLPC ~/gitdir/repo1
    $ echo "line 1" > afile.txt
    
    lylez@LJZ-DELLPC ~/gitdir/repo1
    $ git add afile.txt
    
    lylez@LJZ-DELLPC ~/gitdir/repo1
    $ git commit -m 'initial import'
    [master (root-commit) f407e12] initial import
     1 file changed, 1 insertion(+)
     create mode 100644 afile.txt
    
    lylez@LJZ-DELLPC ~/gitdir/repo1
    $ git clone --bar . ../repo1-bare-clone
    Cloning into bare repository '../repo1-bare-clone'...
    done.
    
    lylez@LJZ-DELLPC ~/gitdir/repo1
    $ git remote add origin ../repo1-bare-clone
    
    lylez@LJZ-DELLPC ~/gitdir/repo1
    $ git push --set-upstream origin master
    Branch master set up to track remote branch master from origin.
    Everything up-to-date
    
    lylez@LJZ-DELLPC ~/gitdir/repo1
    $ cd ..
    
    lylez@LJZ-DELLPC ~/gitdir
    $ ls
    repo1  repo1-bare-clone
    
    lylez@LJZ-DELLPC ~/gitdir
    $ mkdir repo1-remote
    
    lylez@LJZ-DELLPC ~/gitdir
    $ cd repo1-remote
    /home/lylez/gitdir/repo1-remote
    
    lylez@LJZ-DELLPC ~/gitdir/repo1-remote
    $ git clone ../repo1-bare-clone .
    Cloning into '.'...
    done.
    
    lylez@LJZ-DELLPC ~/gitdir/repo1-remote
    $ ls
    afile.txt
    
    lylez@LJZ-DELLPC ~/gitdir/repo1-remote
    $ cat afile.txt
    line 1
    
    lylez@LJZ-DELLPC ~/gitdir/repo1-remote
    $ echo "line 2" >> afile.txt
    
    lylez@LJZ-DELLPC ~/gitdir/repo1-remote
    $ git add afile.txt
    
    lylez@LJZ-DELLPC ~/gitdir/repo1-remote
    $ git commit -m 'added line 2'
    [master 5ad31e0] added line 2
     1 file changed, 1 insertion(+)
    
    lylez@LJZ-DELLPC ~/gitdir/repo1-remote
    $ git push
    Counting objects: 3, done.
    Writing objects: 100% (3/3), 260 bytes | 0 bytes/s, done.
    Total 3 (delta 0), reused 0 (delta 0)
    To /home/lylez/gitdir/repo1-remote/../repo1-bare-clone
       f407e12..5ad31e0  master -> master
    
    lylez@LJZ-DELLPC ~/gitdir/repo1-remote
    $ cd ../repo1
    
    lylez@LJZ-DELLPC ~/gitdir/repo1
    $ ls
    afile.txt
    
    lylez@LJZ-DELLPC ~/gitdir/repo1
    $ cat afile.txt
    line 1
    
    lylez@LJZ-DELLPC ~/gitdir/repo1
    $ git pull
    remote: Counting objects: 3, done.
    remote: Total 3 (delta 0), reused 0 (delta 0)
    Unpacking objects: 100% (3/3), done.
    From ../repo1-bare-clone
       f407e12..5ad31e0  master     -> origin/master
    Updating f407e12..5ad31e0
    Fast-forward
     afile.txt | 1 +
     1 file changed, 1 insertion(+)
    
    lylez@LJZ-DELLPC ~/gitdir/repo1
    $ cat afile.txt
    line 1
    line 2
    
    lylez@LJZ-DELLPC ~/gitdir/repo1
    $ echo "line 3" >> afile.txt
    
    lylez@LJZ-DELLPC ~/gitdir/repo1
    $ git add afile.txt
    
    lylez@LJZ-DELLPC ~/gitdir/repo1
    $ git commit -m 'added line 3'
    [master 3fa569e] added line 3
     1 file changed, 1 insertion(+)
    
    lylez@LJZ-DELLPC ~/gitdir/repo1
    $ git push
    Counting objects: 3, done.
    Writing objects: 100% (3/3), 265 bytes | 0 bytes/s, done.
    Total 3 (delta 0), reused 0 (delta 0)
    To ../repo1-bare-clone
       5ad31e0..3fa569e  master -> master
    
    lylez@LJZ-DELLPC ~/gitdir/repo1
    $ cd ../repo1-remote/
    
    lylez@LJZ-DELLPC ~/gitdir/repo1-remote
    $ ls
    afile.txt
    
    lylez@LJZ-DELLPC ~/gitdir/repo1-remote
    $ cat afile.txt
    line 1
    line 2
    
    lylez@LJZ-DELLPC ~/gitdir/repo1-remote
    $ git pull
    remote: Counting objects: 3, done.
    remote: Total 3 (delta 0), reused 0 (delta 0)
    Unpacking objects: 100% (3/3), done.
    From /home/lylez/gitdir/repo1-remote/../repo1-bare-clone
       5ad31e0..3fa569e  master     -> origin/master
    Updating 5ad31e0..3fa569e
    Fast-forward
     afile.txt | 1 +
     1 file changed, 1 insertion(+)
    
    lylez@LJZ-DELLPC ~/gitdir/repo1-remote
    $ cat afile.txt
    line 1
    line 2
    line 3
    
    lylez@LJZ-DELLPC ~/gitdir/repo1-remote
    $ git --version
    git version 2.1.1
    
    lylez@LJZ-DELLPC ~/gitdir/repo1-remote
    
    0 讨论(0)
  • 2020-11-22 00:32

    You should only be pushing to a bare repository. A bare repository is a repository that has no checked out branches. If you were to cd to a bare repository directory, you'd only see the contents of a .git directory.

    0 讨论(0)
  • 2020-11-22 00:32

    Here is one test you can do to see how the bare server stuff work:

    Imagine you have a workstation and a server with live site hosted on it, and you want to update this site from time to time (this also applies to a situation where two developers are sending their work back and forth through a bare middleman).

    Initialization

    Create some directory on your local computer and cd into it, then execute these commands:

    # initialization
    git init --bare server/.git
    git clone server content
    git clone server local
    
    1. First you create a bare server directory (notice the .git at the end). This directory will serve as a container for your repository files only.
    2. Then clone your server repository to a newly created content directory. This is your live/production directory which will be served by your server software.
    3. The first two directories resides on your server, the third one is a local directory on your workstation.

    Workflow

    Now here is the basic workflow:

    1. Enter the local directory, create some files and commit them. Finally push them to the server:

      # create crazy stuff
      git commit -av
      git push origin master
      
    2. Now enter the content directory and update the server's content:

      git pull
      
    3. Repeat 1-2. Here content may be another developer that can push to the server too, and local as you may pull from him.

    0 讨论(0)
  • 2020-11-22 00:34

    The error message describes what has happened. More modern versions of Git refuse to update a branch via a push if that branch is checked out.

    The easiest way to work between two non-bare repositories is either to

    1. always update the repositories by pull (or fetch and merge) or, if you have to,

    2. by pushing to a separate branch (an import branch) and then merging that branch into the master branch on the remote machine.

    The reason for this restriction is that the push operation operates only on the remote Git repository, it doesn't have access to the index and working tree. So, if allowed, a push on the checked-out branch would change the HEAD to be inconsistent with the index and working tree on the remote repository.

    This would make it very easy to accidentally commit a change that undoes all of the pushed changes and also makes it very difficult to distinguish between any local changes that have not been committed and differences between the new HEAD, the index and the working tree that have been caused by push moving HEAD.

    0 讨论(0)
提交回复
热议问题