After developing on AEM for quite some time, I've come to rely on git for a lot of things. Whether it's maintaining several of my own branches at once, firing off pull requests to get my stories into master, or pulling down someone else's branch to take a look at their work, git has become an indispensable part of my AEM development lifestyle. And, as a developer, I'm always looking for ways to make things easier, cleaner, or simply more efficient. While there a lot of great GUI tools for working with git (I personally recommend Sourcetree), I primarily the command line out of habit. Maybe it's the ultra-granular control this gives me over the entire experience or perhaps it's the feeling that I'm refactoring code behind The Matrix as I'm slamming away in Total Terminal. Either way, I've found some tricks that make life easier and I'd like to share some with you now.
1. Deleting all branches except the one you're on
It's a very common experience for me to have lots of branches. Most of the time it's a collection of story-specific branches that are just hanging out long after the stories have been completed and put into a release. Sourcetree and other GUI tools provide a fairly easy means to delete these branches but what if we want to do it from the command line? Here's one way:
git branch | grep -v "mybranch" | xargs git branch -D
The above line will delete all branches not named "mybranch" in one command instead of having to type them all out. The -D flag is important in that it forces the deletion of these branches and throws away any uncommitted changes. If you're really worried about potentially throwing away work, then use -d instead, in which case git will disallow deletion of branches with unmerged changes. Note also that this only deletes things locally. If you want to delete the remotes as well, I'd recommend doing that in whatever repo you're using. Alternatively, you can run git push [your remote repo name] :[the remote branch to delete]. Note the ':' prior to the remote branch name. Another key is that you should make sure you're actually on the branch you don't want to delete - in our case "mybranch". Otherwise git will complain that it can't delete a branch that you're currently working on. In our 6d development process, we use a "develop" branch as our common branch for features and reserve "master" for releases. So I will generally switch over to develop when I'm done with my stories for a sprint and nuke all the other branches locally using the aforementioned command. As a bonus, you can alias the command for ease of reference. In my local environment, I have it aliased to "gitnuke" as follows:
alias gitnuke="git branch | grep -v "develop" | xargs git branch -D"
This allows me to just type "gitnuke" while on the develop branch to take care of business.
2. Recovering stuff that's been deleted
OH NOES! I nuked all my other local branches and I now realize I actually had some work I need in one of them! I suppose I could just pull down the remote I pu... crap. I never pushed any commits for that branch. All is lost. Woe is me. False. Git conveniently stores a history of just about everything that goes down and this absolutely includes any commits. Each action performed with git has an associated SHA-1 hash used to identify it, among other things. Further, there's a handy little command we can use to browse through this history and retrieve whatever we want:
This will bring up the git history and, from here, you can step through all of the stored objects. By each object is the SHA identifying it. So in our case, we simply step through and find the correct SHA. Check this commit out by running:
git checkout [the SHA for the commit you want to recover]
Git may let you know at this point that you're in an "experimental" state and that certain things will be disabled. That's okay. Just create a new branch off this commit as follows:
git checkout -b [new branch name]
Now you have the commit you thought you lost in its own branch and you're good to go. And, before you ask, the answer is yes: this all was definitely born of the fact that I did this in my own environment. I was about halfway done with an 8 point story, without having done any pushes to the remote (bad CoE), when I got lost in peer review of others' stories and checking out pull requests in my local environment. In finishing all that up, I decided to clean things locally and, yeah. You now know the rest!