I have to create some code review from unmerged branches.
In finding solutions, let's not go to local-branch context problem as this will run on a server; there will be just the origin remote, I will always run a git fetch origin command before other commands, and when we talk about branches, we will refer to origin/branch-name.
If the setup were simple and each branch that originated from master continued on its own way, we could just run:
git rev-list origin/branch-name --not origin/master --no-merges
for each unmerged branch and add the resulting commits to each review per branch.
The problem arises when there are merges between 2-3 branches and work is continued on some of them. As I said, for each branch I want to create code reviews programmatic and I don't want to include a commit in multiple reviews.
Mainly the problems reduce on finding the original branch for each commit.
Or to put it simpler... finding all unmerged commits grouped by the branch they most probably were created on.
Let's focus on a simple example:
* b4 - branch2's head
* | a4 - branch1's head
| * b3
* | merge branch2 into branch1
* |\ | m3 - master's head
| * \| a3
| | |
| | * b2
| * | merge master into branch1
* /| | m2
|/ | * merge branch1 into branch2
| * /| a2
| |/ |
| | * b1
| | /
| |/
| /|
|/ |
| * a1
* / m1
|/
|
* start
and what I want to obtain is:
The best solution I found so far is to run:
git show-branch --topo-order --topics origin/master origin/branch1 origin/branch2
and parse the result:
* [master] m3
! [branch1] a4
! [branch2] b4
---
+ [branch2] b4
+ [branch2^] b3
+ [branch1] a4
++ [branch2~2] b2
-- [branch2~3] Merge branch 'branch1' into branch2
++ [branch2~4] b1
+ [branch1~2] a3
+ [branch1~4] a2
++ [branch1~5] a1
*++ [branch2~5] m1
Output interpretation is like this:
For point 3. the commit name resolution is starting with a branch name and, from what I see, this branch corresponds to the branch that commits were created on, probably by promoting path reaching by first-parent.
As I'm not interested in merge commits, I'll ignore them.
I'll then parse each branch-path-commit to obtain their hash with rev-parse.
How can I handle this situation?
On GitHub.com, you can access your project history by selecting the commit button from the code tab on your project. Locally, you can use git log . The git log command enables you to display a list of all of the commits on your current branch. By default, the git log command presents a lot of information all at once.
To confirm, you can run git branch . The branch that you are on will be the one with a * next to it. Git checkout might fail with an error message, e.g. if it would overwrite modified files. Git branch should show you the current branch and git log master allows you to view commit logs without changing the branch.
There is no information about who created any branch in git. Period. So short answer is No, there is none.
git-unmerged is a tool that helps you find commits that have not been merged into an upstream branch like master or origin/master. It displays useful information in color to make it easy to identify the missing commits. To make it easier on us, it provides a brief overview, a legend, and a breakdown of each branch.
The repository could be cloned with --mirror
which creates a bare repository that can be used as a mirror of the original repository and can be updated with git remote update --prune
after which all the tags should be deleted for this feature.
I implement it this way:
1. get a list of branches not merged into master
git branch --no-merged master
2. for each branch get a list of revisions on that branch and not in master branch
git rev-list branch1 --not master --no-merges
If the list is empty, remove the branch from the list of branches
3. for each revision, determine the original branch with
git name-rev --name-only revisionHash1
and match regex for ^([^\~\^]*)([\~\^].*)?$
. The first pattern is the branch name, the second is the relative path to the branch.
If the branch name found is not equal to the initial branch, remove revision from the list.
At the end I obtained a list of branches and for each of them a list of commits.
After some more bash research, it can be done all in one line with:
git rev-list --all --not master --no-merges | xargs -L1 git name-rev | grep -oE '[0-9a-f]{40}\s[^\~\^]*'
The result is an output in the form
hash branch
which can be read, parsed, ordered, group or whatever.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With