Recurse.se Yada yada on Software Development

13Sep/170

Get sublime help with git commit messages

  1. Use Sublime Text - my preferred text editor
  2. Configure git to use Sublime Text to edit commit messages by:
    • git config --global --replace-all core.editor "subl -w" (on macOS)
    • git config --global --replace-all core.editor "'C:/Program Files/Sublime Text 3/subl.exe' -w" (on Windows)
  3. Install the Sublime Text Package Git Commit Message Syntax which will add file type detection and syntax highlighting for files named COMMIT_EDITMSG, which is what git uses.
  4. Open the settings for that syntax;
    • Open ~/Library/Application Support/Sublime Text 3/Packages/User/commit-message.sublime-settings (on macOS), or
    • Either use git to open a commit message, or set the current syntax to Commit Message, and go to Preferences > Settings - Syntax Specific (which opens up the settings file specific to the current syntax)
  5. Add rulers for the recommended commit message lengths by adding
    "rulers":[72, 50] between the curly brackets, and save the file.

Now, when writing a commit message, these rulers will help you visually keep the first line (the commit title) around 50 characters long, and the commit body around 72 characters.

A bonus feature is that using the command Edit > Wrap > Wrap Paragraph at Ruler, will now reformat the current paragraph to wrap along the first ruler (72), which makes it really easy to keep longer commit messages nicely formatted without manual fiddling!

Filed under: git No Comments
29Jun/170

Copy commits from one git repo to another

If you have done some work in one (or more) repos, that you want to transfer into a different target repo, you can of course simply copy you work to the new repo. But what if you also would like to copy the commit history?

This can be done by using git format-patch plus git am.

We'll assume that we have two different repos; labrepo and goodrepo.

somewhere $ cd ~/repos/labrepo
labrepo $ git format-patch --root
0001-Initial-TestDataProvider.patch
0002-One-assert-per-test.patch
0003-Allow-adding-schedule-for-multiple-days.patch
...
labrepo $ cd ../goodrepo
goodrepo $ mkdir lab
goodrepo $ git am --directory=lab --whitespace=nowarn ../labrepo/*.patch
Applying: Initial TestDataProvider
Applying: One assert per test
Applying: Allow adding schedule for multiple days
...

This series of commands would transfer all your commits from labrepo into the subfolder "lab" in the goodrepo. And you'll be able to move several other repos into the goodrepo this way, without conflicts. Remember that the new commits are just copies, and will have different commit-ids than the corresponding labrepo commits.

git format-patch can of course extract just a subset of the history, such as if work continues in the labrepo, you can create patches just for those commits, and run a new git am on those patches to import them.

somewhere $ cd ~/repos/labrepo
labrepo $ git format-patch -v2 commitid-of-last-transferred-commit
v2-0001-Never-schedule-Sundays.patch
v2-0002-Increase-test-coverage.patch
...
labrepo $ cd ../goodrepo
goodrepo $ git am --directory=lab --whitespace=nowarn ../labrepo/v2-*.patch
Applying: Never schedule Sundays
Applying: Increase test coverage
...

The -v2 argument to git format-patch gives the resulting files a prefix, so you know which patch files belong together (or, just remove old .patch-files before exporting new ones)

Filed under: git No Comments
15Apr/170

Fork and Switch – Pointing a git workspace to a fork

So, I'm in a couple of projects where all developers have push access to a Github repository, but we'd like all developers to move over to using a pull-request based workflow to encourage code reviews. This often results in people just doing work in a branch, pushing the branch to the common repo and then doing a PR from there.

This works fine, but creates a lot of branches in the main repo. Also we've had minor incidents where people forgot to create a branch, and pushed unreviewed commits directly to the master branch. I usually recommend people to do their work in a fork - a copy of the codebase under your github account.

Now, if you go ahead and clone your fork into a new folder on your local machine, when you already had a working setup towards the original repo in another folder, you'll need to change a lot of things, paths in your IDEs and editors etc, probably download half an internet worth of NPM packages and so on, so it's much simpler IMHO to just update the "remotes" on your current repo workspace folder to look like they would if you'd cloned your fork.

This is achieved like this. Let's assume the original repo is https://github.com/megacorp/enterprisey and you already have a working setup in the folder C:\dev\megacorp\enterprisey

  • Create your fork by browsing to the https://github.com/megacorp/enterprisey repo in Github, and press the "fork" button
  • Then select your github user as the destination of the fork. This will create a fork named https://github.com/your_username/enterprisey
  • Then, in your original working folder (C:\dev\megacorp\enterprisey) run the following git commands;
git remote set-url origin https://github.com/your_username/enterprisey.git
git remote add upstream https://github.com/megacorp/enterprisey.git

That's it! The only change in workflow after that, is that you need to remember to say git pull upstream (or git fetch upstream) to get the latest stuff from the common repo (the megacorp one, that is). Now, there are ways to configure git to default pulls to upstream instead of origin, but I don't think it's an improvement.

The whole point of this will be that, now, when you do git push it'll send your stuff to your fork, instead of to the common repo, which keeps the number of branches in the common repo down, as well as minimizing the risk of pushing unwanted stuff to your common master.

Then when you want to do a PR from your fork to the common master, it'll be just as simple as before, as github already knows about your fork, and will prompt you if it notices a new branch in your fork.

Filed under: git No Comments