Short version: I’ve got a master branch, which people are working on and committing to. Then I’ve got a branch off of master, call it foo which people are also working on and committing to. Periodically, I want to bring over some, but not all, of the changes from foo back to master. I would like some way for the history of master to be query-able for the presence and absence of commits from foo. This appears problematic. How do I do this?
Long version: Create an example git repo like this:
cd /tmp && mkdir gitrepo && cd gitrepo/ && git init
echo "Something shared" > myFile.txt && git add myFile.txt && git commit -m "Added myFile.txt to master"
git checkout -b foo master
echo "Something else shared" > anotherFile.txt && git add anotherFile.txt && git commit -m "Added anotherFile.txt to foo"
echo "Something specific to foo" > foochange.txt && git add foochange.txt && git commit -m "Added foochange.txt to foo"
echo "Something else shared again" > yetAnotherFile.txt && git add yetAnotherFile.txt && git commit -m "Added yetAnotherFile.txt to foo"
git checkout master
echo "Something specific to master" > masterchange.txt && git add masterchange.txt && git commit -m "Added masterchange.txt to master"
echo "Specific to master" > masterchange.txt && git add masterchange.txt && git commit -m "Added masterchange.txt on master"
(All discussion from here forward assumes we’re on master)
Now we’ve got the situation where foo is two commits behind master and has three commits of it’s own. At this point I want to bring back the first and third commits from foo to master but NOT the second.
The fundamental issue is that the parent of the commit at the head of foo is the commit that I don’t want to merge, but since a commit’s parents are part of that commit’s hash there’s no way to preserve the hash of the commit at the head of foo without also creating a situation where git branch --contains foo^ is true for master.
For instance, if I did git merge foo it would merge all the commits from foo to master. After doing that I would be able to say git branch --contains foo^ and it would say that both foo and master contain that commit. I tried then doing a git revert foo^ but git branch --contains foo^ still reports that master contains foo^.
If I git cherry-pick foo foo^^ the two relevant revisions, then I have the changes from those two revisions’ diffs from foo applied in master, but git branch --contains foo^ says that only branch foo contains that commit.
What I’m trying to achieve here is some way to query the history (without manually correlating hashes stored as text in commit messages) so I can be able to see which commits have and haven’t been merged into master. As mentioned, I know of several ways to get the state of master to be equivalent to what I want (cherry-pick, merge+revert, format-patch/am, diff/patch, etc.) what I’m looking for is some way to query the history for the information I need. I get that git branch --contains will probably not ever work in the way I want it to, but if there’s some alternate way to query the history, that I haven’t thought of, I’m all ears.
Anyone have any ideas?
I think
git-cherryis the command you are looking for.This shows commits in
foothat have not (yet) been merged intomaster.From the manual: