How to copy commits from one Git repo to another?
Is there a way I have get the commits into new repo (this time the first commit is the LICENSE file) and still keep the commit meta info?
Yes, by adding a remote and cherry-picking the commits on top of your first commit.
# add the old repo as a remote repository
git remote add oldrepo https://github.com/path/to/oldrepo
# get the old repo commits
git remote update
# examine the whole tree
git log --all --oneline --graph --decorate
# copy (cherry-pick) the commits from the old repo into your new local one
git cherry-pick sha-of-commit-one
git cherry-pick sha-of-commit-two
git cherry-pick sha-of-commit-three
# check your local repo is correct
git log
# send your new tree (repo state) to github
git push origin master
# remove the now-unneeded reference to oldrepo
git remote remove oldrepo
The rest of this answer is if you still want to add the LICENSE to your previous repo.
Yes. You can place your LICENSE commit as the first commit by rebasing.
Rebasing is gits way of rearranging commit order while keeping all the commit authors and commit dates intact.
When working on a shared repo, it's generally discouraged unless your entire team is git-fluent. For those that aren't, they can just clone a fresh copy of the repository.
Here's how you get your LICENSE commit as the first commit.
1. Update and rebase your local copy
Check out your project and place the LICENSE file in a commit ON TOP of your current 3 commit stack.
#create LICENSE file, edit, add content, save
git add LICENSE
git commit -m 'Initial commit'
Then do an interactive rebase on the master branch to REARRANGE the commits.
git rebase -i --root
It will open an editor. Move the bottom line (your "Initial commit" commit, the most recent commit) to the top of the file. Then save and quit the editor.
As soon as you exit the editor, git will write the commits in the order you just specified.
You now have your local copy of the repository updated. do:
git log
to verify.
2. Force push your new repo state to github
Now that your copy is updated, you have to force push it to github.
git push -f origin master
This will tell github to move the master branch to its new location.
You should only force push in rare occasions like this where everybody working with it is aware of the pending change, else it will confuse your collaborators.
3. Synchronize collaborators to github
Lastly, all the collaborators will have to synchronize to this repository.
First they must have clean repositories as the following command can be destructive if there are unsaved changes.
# make sure there are no unsaved changes
git status
# pull the latest version from github
git fetch
# move their master branch pointer to the one you published to github.
git reset --hard origin/master
That's it. Everybody should be in sync now.
How to copy commits from one branch to another?
You should really have a workflow that lets you do this all by merging:
- x - x - x (v2) - x - x - x (v2.1)
\
x - x - x (wss)
So all you have to do is git checkout v2.1
and git merge wss
. If for some reason you really can't do this, and you can't use git rebase to move your wss branch to the right place, the command to grab a single commit from somewhere and apply it elsewhere is git cherry-pick. Just check out the branch you want to apply it on, and run git cherry-pick <SHA of commit to cherry-pick>
.
Some of the ways rebase might save you:
If your history looks like this:
- x - x - x (v2) - x - x - x (v2.1)
\
x - x - x (v2-only) - x - x - x (wss)
You could use git rebase --onto v2 v2-only wss
to move wss directly onto v2:
- x - x - x (v2) - x - x - x (v2.1)
|\
| x - x - x (v2-only)
\
x - x - x (wss)
Then you can merge! If you really, really, really can't get to the point where you can merge, you can still use rebase to effectively do several cherry-picks at once:
# wss-starting-point is the SHA1/branch immediately before the first commit to rebase
git branch wss-to-rebase wss
git rebase --onto v2.1 wss-starting-point wss-to-rebase
git checkout v2.1
git merge wss-to-rebase
Note: the reason that it takes some extra work in order to do this is that it's creating duplicate commits in your repository. This isn't really a good thing - the whole point of easy branching and merging is to be able to do everything by making commit(s) one place and merging them into wherever they're needed. Duplicate commits mean an intent never to merge those two branches (if you decide you want to later, you'll get conflicts).
How can I copy commits from one branch to another?
Yes cherry-pick
is what you want here. If the commits are consecutive:
git checkout branch2
git cherry-pick <commit-1-id>..<commit-4-id>
Otherwise you will have to specify them individually:
git cherry-pick <commit-1-id> <commit-2-id> <commit-3-id> <commit-4-id>
Commit specific commit of another project
It's there a way to commit on my repository a commit made by another user on another repository? Or i need to make this file to file by hand?
You will need to use cherry-pick
Follow these steps:
# add the 2 remotes to your repository
git remote add <origin2> <url>
# "Grab" the content of all the branches
git fetch --all --prune
# Checkout the destination branch
git checkout <branch>
# "Apply" the change
git cherry-pick <SHA1->
git: Apply changes introduced by commit in one repo to another repo
As a hack, you can try modifying recipe for comparing commits in two different repositories on GitTips page, i.e.:
GIT_ALTERNATE_OBJECT_DIRECTORIES=../repo/.git/objects \
git cherry-pick $(git --git-dir=../repo/.git rev-parse --verify <commit>)
where ../repo
is path to the other repository.
With modern Git you can use multiple revisions and revision ranges with cherry-pick.
The $(git --git-dir=../repo/.git rev-parse --verify <commit>)
is here to translate <commit>
(for example HEAD
, or v0.2
, or master~2
, which are values in the second repository you copy from) into SHA-1 identifier of commit. If you know SHA-1 of a change you want to pick, it is not necessary.
NOTE however that Git can skip copying objects from source repository, as it doesn't know that the alternate object repository is only temporary, for one operation. You might need to copy objects from the second repository with:
GIT_ALTERNATE_OBJECT_DIRECTORIES=../repo/.git/objects git repack -a -d -f
This puts those objects borrowed from second repository in original repository storage
Not tested.
A not so hacky solution is to follow knittl answer:
- Go to second repository you want to copy commits from, and generate patches from commits you want with
git format-patch
- Optionally, copy patches (0001-* etc.) to your repository
- Use
git am --3way
to apply patches
Related Topics
How to Find Which Position a Word Is in a String
How to Calculate Time For an Asm Delay Loop on X86 Linux
How to Include All Objects of an Archive in a Shared Object
Understanding User File Ownership in Docker: How to Avoid Changing Permissions of Linked Volumes
How to Determine If a Process Runs Inside Lxc/Docker
Remove a Specific Character Using Awk or Sed
Assembling 32-Bit Binaries on a 64-Bit System (Gnu Toolchain)
Iterate Over a List of Files With Spaces
Deploying Yesod to Heroku, Can't Build Statically
What Is Rss and Vsz in Linux Memory Management
Finding Which Process Was Killed by Linux Oom Killer
Bash While Read Loop Extremely Slow Compared to Cat, Why
Sorting Multiple Keys With Unix Sort
Redirect Stderr/Stdout of a Process After It's Been Started, Using Command Line
How to Get Cmake to Find My Alternative Boost Installation