Skip to content

Instantly share code, notes, and snippets.

@indiesquidge
Last active May 1, 2020 11:16
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save indiesquidge/8dfd18bd34b9e782ed48 to your computer and use it in GitHub Desktop.
Save indiesquidge/8dfd18bd34b9e782ed48 to your computer and use it in GitHub Desktop.
Manual Git Flow for a Feature Branch from the CLI

Manual Git Flow for a Feature Branch from the CLI

Brief Context

Back in 2010, Vincent Driessen wrote a post called A successful Git branching model. Besides being extremely well drafted and clear in it's intention, the post goes into great detail about Git branching strategies and release management. The model that Vincent (sobriquet "nvie") came up with was popularized as git-flow.

Since then, nvie has published a set of Git extensions to provide high-level repository operations for his branching model used on the CLI via an executable named, unsurprisingly, git-flow. It creates abstractions for the creation and completion and publication of everything he talks about in the blog post, namely, feature, release, and hotfix branches. You can read a full list of the command line arguments for git-flow here. While this extension does create a nice abstraction to the principles of Git flow, the DSL may stifle some people's ability to handle a complicated situation which may require basic git commands.

Thankfully, git-flow does not interfere with vanilla git to accomplish the same thing, which is what we're going to talk about here.

Intro

This post is aimed at explaining how to work on a feature branch within this company. For release and feature branches, please consult the blog post mentioned above, as it does a fantastic job of explaining their purpose and implementation, which we are following as it is laid out in the post.

May branch from: develop Must merge back into: develop Branch naming convention: feature/GLOB-<JIRA-ticket-number>

Feature branches will make up the large majority of what developers work on. They are also the most understood branch type, and are used to develop new features for a future release.

So you're about to start on your new feature. Most likely this is associated to a JIRA ticket for a bug or story. For this example, let's say that ticket is GLOB-1234.

NOTE: If you have any unsaved local changes you'd like to move to the feature branch at this time, you can prepend the following steps with a stash of your local changes by running git stash

git checkout develop Switched to branch "develop" git pull origin develop Pulled changes from remote branch "develop" git checkout -b feature/GLOB-1234 Switched to a new branch "feature/GLOB-1234"

NOTE: If you had stashed your changes before executing the list of commands above, you can now properly bring those back into existence with git stash pop.

Work on your feature, make your commits. The convention is to prepend your commit message(s) with the JIRA ticket number for the feature you are working on.

git commit -m "GLOB-1234 - <commit message here>"

Then you need to do a few things before creating your pull request.

Firstly, try to squash your commits down to a reasonable number. This number may vary depending on the needs of the team, but for a feature it would be advisable to have no more than two commits; a bug really shouldn't be more than a single commit.

You want to make sure you are up to date with the current develop branch. Since you started work on your feature, other bug fixes and features from other developers may have been merged back into develop that you do not have locally.

git checkout develop Switched to branch "develop" git pull origin develop Pulled changes from remote branch "develop"

Now that your local develop mirrors the remote develop, you will want to rebase your feature changes on top of develop. This will create a cleaner, more linear history.

git checkout feature/GLOB-1234 Switched to branch "feature/GLOB-1234" git rebase develop First, rewinding head to replay your work on top of it... Applying: added staged command

You can condense the above two commands into a one-liner if you'd like: git rebase develop feature/GLOB-1234

If you happen to run into merge conflicts when rebasing, it will "pause" the rebase at that point in history until you clean up the conflicting changes. After you have examined and fixed the files that had conflicting code, you can add that file(s) back into the ("paused") rebase and tell Git to continue rebasing.

git add <some-file-that-had-conflicts> git rebase --continue

This cleanup may take multiple continuation steps depending on how many conflicts there are and how many commits are being rebased on top of.

NOTE: I am assuming that our release and hotfix branches work as they are described in the git-flow blog post, which uses normal git commands itself. If we are tweaking the process for release or hotfix branches, please explain in which ways our management is different by either leaving a comment in this file or editing it yourself.


Creating a Pull Request

hub

nvie's post is remote agnostic: Git flow can be used regardless of the team's choice of remote storage. Our team uses GitHub to manage this.

Since Git and GitHub are bffs, GitHub has developed hub, a command line tool that wraps git in order to extend it with extra features and commands that make working with GitHub easier. We will be using this throughout the tutorial.

To install hub on OS X:

brew install hub

Follow hub's installation page if you are running on another platform.

Some people advocate for making hub and git aliases in your terminal. I would advise against this. While I am a huge proponent of using GitHub for all your Git remote storage needs, aliasing it creates an unnecessary bind between the two commands. It also gives git more power than it normally has, which can get you into trouble if you don't use it carefully or forget you've aliased it. In some sense, it's like traversing around your shell as root, negating the requirement to prepend sudo when running high-level or dangerous commands. Since hub is a wrapper around git, you could just use hub if you really wanted to stick with only one executable.

hub adds a lot of shiny new features and extensions to normal git commands, from cloning and forking remote GitHub repositories to creating pull requests to browsing the repository on the web to creating a remote repository; for a complete list of documentation just run man hub. For the purposes of this tutorial, We are only going to run through the creation of a pull request and browsing it on the web.

Pull Request and Browse

hub pull request - This is the most popular reason for people downloading hub. It allows you to create a GitHub pull request directly from the command line.

It comes with some flag options that we want to take advantage of since we are following the Git flow model, namely, we should be creating our pull requests against develop instead of master. To accomplish this we can use the -b flag, which stands for BASE. We can also open up the browser upon our creation of the pull request with -o or --browse. In its entirety, our command would look something like this.

hub pull-request -b develop -o

The default head of the pull request is the current branch. You can specify a different head with the -h flag and then passing in the branch you would like to use as head.

You can also use the -m flag which is similar to the git -m flag in that it allows you to include a title for your pull request from the command line.

hub pull-request -b develop -o -m "<PR title here>"

Without the -m flag, a text editor will open in which title and body of the pull request can be entered in the same manner as git commit message. By default, Git uses whatever you've set as your default text editor ($VISUAL or $EDITOR) or else falls back to the vi editor to create and edit your commit and tag messages. To change that default to something else, you can use the core.editor setting:

git config --global core.editor atom

Whichever implementation of hub pull-request you choose, the end result will be the same. You will have created a new pull request against develop (-b develop), with a PR title (-m "<PR title here>"), and opened that pull request in the browser (-o).

Conclusion

This may seem like a lot of overhead to create a feature and get it merged, but understanding the commands being used in DSLs like git-flow is a very useful skill to have.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment