gitrepositorylocalgit-pushgit-repo

Clone from a local repository, then pushing back the changes


I have a git repository on my local system in /original/.git. Now, I have cloned this repository in /cloned_one/.git. Everything looks fine. Here, I have the same files that I have in /original which is quite nice. I create a new file and commit it. Now, my cloned repo is one commit ahead. I want to push the changes but don't know how!

It becomes more tricky because I'm a bit confused about the following command's diversities and exact use-cases. I know some of them and actually worked with them somehow but I've seen a lot of users use them in the wrong place and that's what made me confused. Not sure when to use the following commands.

Thanks.


Solution

  • Git's remote repository can be from ssh, https, and directory.

    In your example,

    This looks like some kind of linked list:

    [/cloned_one/.git] --origin--> [/original/.git] --origin--> [github]
    

    Here is an example command to reproduce such setup:

    $ cd /tmp
    $ git clone https://github.com/schacon/example.git original
    Cloning into 'original'...
    remote: Enumerating objects: 4, done.
    remote: Total 4 (delta 0), reused 0 (delta 0), pack-reused 4
    Receiving objects: 100% (4/4), 18.52 KiB | 3.70 MiB/s, done.
    $ mkdir cloned_one
    $ git clone /tmp/original cloned_one
    Cloning into 'cloned_one'...
    done.
    $ cd cloned_one/
    $ echo newfile > newfile.txt
    $ git status
    On branch master
    Your branch is up to date with 'origin/master'.
    
    Untracked files:
      (use "git add <file>..." to include in what will be committed)
            newfile.txt
    
    nothing added to commit but untracked files present (use "git add" to track)
    $ git add newfile.txt 
    $ git commit -m 'add new file'
    [master e45e780] add new file
     1 file changed, 1 insertion(+)
     create mode 100644 newfile.txt
    $ git remote -v
    origin  /tmp/original (fetch)
    origin  /tmp/original (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 tree clean
    

    Now, the cloned_one is 1 commit ahead of original

    You can push changes from cloned_one to original with (remember to cd /tmp/cloned_one first):

    Here, the syntax of pushing is to specify where you want to push (e.g.: to origin, or to /tmp/original directory), and what branch you want to push

    $ cd /tmp/cloned_one/
    $ 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 tree clean
    $ git push
    Enumerating objects: 4, done.
    Counting objects: 100% (4/4), done.
    Delta compression using up to 8 threads
    Compressing objects: 100% (2/2), done.
    Writing objects: 100% (3/3), 333 bytes | 333.00 KiB/s, done.
    Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
    remote: error: refusing to update checked out branch: refs/heads/master
    remote: error: By default, updating the current branch in a non-bare repository
    remote: is denied, because it will make the index and work tree inconsistent
    remote: with what you pushed, and will require 'git reset --hard' to match
    remote: the work tree to HEAD.
    remote: 
    remote: You can set the 'receive.denyCurrentBranch' configuration variable
    remote: to 'ignore' or 'warn' in the remote repository to allow pushing into
    remote: its current branch; however, this is not recommended unless you
    remote: arranged to update its work tree to match what you pushed in some
    remote: other way.
    remote: 
    remote: To squelch this message and still keep the default behaviour, set
    remote: 'receive.denyCurrentBranch' configuration variable to 'refuse'.
    To /tmp/original
     ! [remote rejected] master -> master (branch is currently checked out)
    error: failed to push some refs to '/tmp/original'
    

    Now it says that you have trouble pushing to /tmp/original because its not a bare repo. You can fix this by either changing /tmp/original to bare repo, or just configure it to update its worktree when being pushed to like below:

    $ cd /tmp/original/
    $ git config receive.denyCurrentBranch updateInstead
    $ cd /tmp/cloned_one/
    $ git push
    Enumerating objects: 4, done.
    Counting objects: 100% (4/4), done.
    Delta compression using up to 8 threads
    Compressing objects: 100% (2/2), done.
    Writing objects: 100% (3/3), 333 bytes | 333.00 KiB/s, done.
    Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
    To /tmp/original
       c3d5e92..e45e780  master -> master
    

    Now, if you want to push your changes back to github (the origin of /tmp/original) you can push it from /tmp/original or from /tmp/cloned_one:

    Notice that when pushing from /tmp/original, you can specify the target as origin (since the origin of /tmp/original is from github). While when pushing from /tmp/cloned_one, you have to specify the target as full URL.

    You can also change cloned_one's remote to point to github (search for git remote manual)

    Further reading: