If you need to quickly create a PR of the changes between two branches, GitHub is the quickest and most pragmatic choice. Here’s why.
As part of my work as documentation lead at ownCloud I have to ensure that the documentation reflects — as much as possible — the various ownCloud releases.
To do that, we keep the documentation in a git repository on GitHub and work with it as follows:
- master is the source of all truth, containing all of the latest changes.
- Each change is made on a feature branch forked from master and merged back to master, when discussed and approved.
- For every ownCloud release there’s an equivalent branch. For example: “stable8” contains the documentation for ownCloud version 8 and so on.
However, that way of working has the potential for feature branches merged to master to not be merged to an applicable, “stable”, branch.
And so it was recently with the latest version branch, “stable10”; a number of PRs had been merged to master, but were missing from “stable10”.
Given that, I then needed to find out which ones.
To do that, my first thought was to find out which feature branches merged to master had not yet been merged to “stable10”; that way, I could merge changes in logical batches.
I thought I’d be able to get a list of them, then merge them one by one.
Whether that’s the right approach or not I’m not sure.
But it made sense.
The trouble is, my knowledge of git isn’t at the advanced level.
I experimented with git log, branch, cherry, reflog, and name-rev, trying to find a way to build the relevant branch list, seeming to get ever closer, but never quite getting there.
GitHub to the Rescue
After hitting a, proverbial, brick wall, I thought I’d try and find further information via GitHub that could help aid in my search.
While there, I saw the “Compare” link, and was intrigued; maybe this would be a simpler solution.
Clicking it, it showed me (as you can see in the image below) that there were no changes in master that weren’t already in “stable10”, go figure.
But, by switching the comparison around it showed me 131 commits across 226 files in master that weren’t in “stable10”.
It also offered to create a pull request based on those changes.
Given that I felt I was starting to waste time looking for something that I didn’t know how to solve, I went with creating the PR.
For what it’s worth, I think that I could have done this manually, using the following commands.
#!/bin/bash
HEAD=( git rev-parse HEAD )
FROM_BRANCH=master
TO_BRANCH=stable10
# Find the merge commits on the FROM branch that aren’t on the TO branch
BRANCH_DIFF=( git log --cherry-pick --format="%h" --merges --left-only $FROM_BRANCH...$TO_BRANCH )
#COMMIT_RANGE=( $BRANCH_DIFF | (head -n1 && tail -n1) | xargs -n 2 | awk '{ print $2"~1 "$1 }' )
# Find the starting commit
COMMIT_FROM=( $BRANCH_DIFF | tail -n1 )
# Find the ending commit
COMMIT_TO=( $BRANCH_DIFF | head -n1 )
TEMP_BRANCH_NAME=temporary_branch
# Create a temporary branch to manage the changes
git checkout -b $TEMP_BRANCH_NAME
# Copy the merge commits from one branch to the other
git rebase --onto $HEAD $COMMIT_FROM~1 $COMMIT_TO
# Replaying them
git rebase HEAD $TEMP_BRANCH_NAME
# Push the branch
ggpush
# Start the creation of a PR of the current branch into stable10
# You can find the backport command at https://gist.github.com/PVince81/f58f6dfd6cf54c4a6ba9322187873180
git-backport $TO_BRANCH
But I’d then still have to create a PR, which I could have done using a couple of mouse clicks on GitHub anyway.
So I did it directly on GitHub, as it seemed like the most pragmatic approach.
Is it the Right Solution?
While not my intended original solution, doing so did solve the need that I had, helping me ensure all the changes in master could be merged into “stable10”.
This was an unexpected way of solving the challenge that I faced; but a solution all the same.
But while I’m happy that it solves my initial problem, I’m not sure that it’s the right solution to use, at least not over the longer term.
What’s more, I’m not honestly sure if it’s possible to get a list of branches from a list of commits, or if doing so is the most efficient solution.
Furthermore, I’m questioning the approach that we’re currently using at ownCloud.
From a logical, efficiency perspective, is it the right approach to take?
Or should the latest build of the documentation always come from master with only previous releases being built from specific “stable” branches (or tags)?
I’m thinking that this approach has the advantage that new feature branches will be automatically added to the current release.
Given that there’s no need to specifically additionally merge them, then there’s no possibility that they can be overlooked.
Conclusion
Am I wrong?
Am I overthinking the whole thing?
Or am I right?
Is there a way of building a list of branches from a list of commits?
I’d love to know what you think.
Join the discussion
comments powered by Disqus