Search code examples
gitgithubmultiple-repositories

How do I add the contents of a github repository to another github repository?


Yesterday I created a github repository and today I found out my advisor also created a github repository. What is the best way to add my repository to his repository without massively screwing things up? I have massively screwed things up in the past so I just want to make sure. Also I may have already screwed things up by trying to follow the instructions on another StackOverflow post.

Right now it seems like I have two branches, and typing "git checkout master" gives me my files, while typing "git checkout tmp_branch" gives me his files. I'd like to add all my files to his repository and use that one from now on, and maybe delete my repository.

So far what I've tried to do is

me@server:~/rootdir$ git remote add origin https://github.com/him/his_repo.git
fatal: remote origin already exists.
me@server:~/rootdir$ git remote add his_repo https://github.com/him/his_repo.git
me@server:~/rootdir$ git push -u his_repo master
Username for 'https://github.com': [email protected]
Password for 'https://[email protected]@github.com':
To https://github.com/him/his_repo.git
 ! [rejected]        master -> master (non-fast-forward)
error: failed to push some refs to 'https://github.com/him/his_repo.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Merge the remote changes (e.g. 'git pull')
hint: before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
me@server:~/rootdir$ git pull his_repo
Username for 'https://github.com': [email protected]
Password for 'https://[email protected]@github.com':
warning: no common commits
remote: Counting objects: 13, done.
remote: Compressing objects: 100% (10/10), done.
remote: Total 13 (delta 0), reused 10 (delta 0)
Unpacking objects: 100% (13/13), done.
From https://github.com/him/his_repo
 * [new branch]      master     -> his_repo/master
You asked to pull from the remote 'his_repo', but did not specify
a branch. Because this is not the default configured remote
for your current branch, you must specify a branch on the command line.
me@server:~/rootdir$ git checkout -b tmp_branch his_repo/master
warning: unable to rmdir mysubdir: Directory not empty
Branch tmp_branch set up to track remote branch master from repo.
Switched to a new branch 'tmp_branch'
me@server:~/rootdir$ git checkout -b origin/master
Switched to a new branch 'origin/master'
me@server:~/rootdir/subdir$ git checkout -b master
fatal: A branch named 'master' already exists.
me@server:~/rootdir/subdir$ git checkout master
Checking out files: 100% (2409/2409), done.
Switched to branch 'master'
me@server:~/rootdir$ git checkout tmp_branch
warning: unable to rmdir mysubdir: Directory not empty
Switched to branch 'tmp_branch'
me@server:~/rootdir$ git mv * tmp_branch/*
fatal: destination 'tmp_branch/*' is not a directory
me@server:~/rootdir$ cd ..
me@server:~/rootdir$ git checkout master
Checking out files: 100% (2409/2409), done.
Switched to branch 'master'
me@server:~/rootdir$ git push -u tmp_branch master
fatal: 'tmp_branch' does not appear to be a git repository
fatal: The remote end hung up unexpectedly
me@server:~/rootdir$ git push -u his_repo master
Username for 'https://github.com': [email protected]
Password for 'https://[email protected]@github.com':
To https://github.com/him/his_repo.git
 ! [rejected]        master -> master (non-fast-forward)
error: failed to push some refs to 'https://github.com/him/his_repo.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Merge the remote changes (e.g. 'git pull')
hint: before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

Thanks so much :)


Solution

  • To make your advisor’s repository contain your files, and to forget about your repository:

    1. add his repository as another remote
    2. check out a new local branch that tracks his master branch
    3. make a new commit on that branch that replaces his files with yours
    4. push that branch to his remote
    5. remove your old remote from your local repository (and delete it on the remote server if you want)

    In your log of shell commands, you already got steps 1 and 4 working. Step 4 failed because you didn’t do steps 2 and 3. When you tried to push your commit history to his remote in step 4, you were on the branch of your old repository, which had completely different history. Git refused to do it because you would be overwriting all of his history with your history. To fix that, start with his history by checking out his branch, and then add a new commit to the history that replaces his files with yours.

    I haven’t memorized the exact git commands to do all of the above – I usually use a GUI – but here is what I know about each step:

    1. git remote add his_repo https://github.com/him/his_repo.git
    2. git branch branch_for_his_work his_repo/master, followed by git checkout --merge branch_for_his_work. This will switch to a branch that tracks his repo, and --merge means that instead of overwriting the files your working copy with his files, Git will start a three-way merge.
    3. To overwrite his files with yours, resolve the merge so that only your files are staged, and none of his. Then git commit ….
    4. git push …
    5. git remote remove origin, and also git remote rename his_repo origin if you want to call his remote “origin” instead of “his_repo”. Probably also git branch -M branch_for_his_work master so that “master” is your only branch, and refers to your advisor’s history.

    Steps 2 and 3 are a bit harder than they need to be because I don’t know of any flag for git checkout that means “leave the working copy exactly as it is – just change Git’s HEAD”. If there were such a flag, you could just git add -A and git commit in step 3, without having to deal with merge conflicts. Or you could copy your files out before steps 2 and put them back before step 3, which is uses more disk space, but is simpler, much like the manual solution you said you used.