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.
git fetch
git rebase
git push
git merge
git --force push
Thanks.
Git's remote repository can be from ssh, https, and directory.
In your example,
/original/.git
have remote origin that points to github (either via ssh or https, e.g.: https://github.com/user/example.git
)/cloned_one/.git
have remote origin that points to directory (e.g.: /original/.git
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):
git push
git push origin master
git push /tmp/original master
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
:
cd /tmp/original ; git push origin master
cd /tmp/cloned_one ; git push https://github.com/username/example.git
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:
! [remote rejected] master -> master (branch is currently checked out)
issue happens, you can read: