Verified Commit 3f2fa058 authored by doshitan's avatar doshitan
Browse files

Update git page

parent 51b920be
......@@ -9,7 +9,7 @@ theoretically I prefer something like [darcs](, I'm usually
pushed back to git. I'm hopeful for [Pijul]( to improve upon
It also has a wild and amazing birth story, and in 2016 an added twist of irony.
It also has a fun birth story, and in 2016 an added twist of irony.
just [read a bit about it]( and
......@@ -77,19 +77,23 @@ docs](
# Commit messages
The first line should be "subject" or title of the change.
The first line should be "subject" or title of the change. It should be a brief,
but clear summary of what is changing. Try to keep it close to 80 characters,
but being accurate and helpful is more important than line length.
Write in the imperative present tense, that is, as if the commit does an action.
`Enable foo` is good, `Enabled foo` or `I enabled foo` are to be avoided. A
commit didn't do something, it does something.
The summary section should provide any further clarification on the work (esp.
anything non-obvious) and particularly *why* and big-picture *what*, we can see
the *how* by looking at the code.
The next lines are the summary section and should provide any further
clarification on the work (esp. anything non-obvious) and particularly *why* and
big-picture *what*, we can see the *how* and specifics by looking at the code.
Many others have written on this, [How to Write a Git Commit
Message]( by Chris Beams is detailed
and links to many of other big posts in this area.
and links to many of other big posts in this area. I particularly like/agree
with what the folks who make [Phabricator have to say on commit
# Rebase/rewriting history
......@@ -181,6 +185,14 @@ merge commits, that's fine just make the merge commit message useful so when
viewing the history with `--first-parent` you can easily track what is actually
happening to the codebase.
Note that when I say "feature branch" I just mean a branch the changes to
support the feature lives while being developed and reviewed. Controlling the
"feature" in production should be done with feature flags on the application,
that is, the code is merged to `master` and there is a run-time system to enable
or disable the new code for testing/validation/experimentation. The "feature
branch" is just a temporary workspace for writing code, not a deployment
Looking at the default GitHub template for merge commit messages for example,
`Merge pull request #xxx from <user>/<branch>`, isn't the worst if the branch
name is reasonable, but the information I most care about, what does this commit
......@@ -256,7 +268,10 @@ and squashed up into a linear history.
Basically regardless of if you are rebasing or merging make the history easy to
follow, to be useful for *people reading the history*.
follow, to be useful for *people reading the history*. I generally subscribe to
the [one idea is one
Versions get tagged, if fixes or features need backported, branch from
the tag, apply necessary changes and tag new release on that branch. If you
......@@ -284,15 +299,127 @@ purposes.
Your needs may be different.
Some others thoughts:
- [Phabricator - Recommendations on Branching](
- <>
- <>
- [GitFlow considered harmful](
- [Their suggested model](
# Worktrees
There are occasions when it's useful to have two separate checkouts backed by
the same repository, say when you have to support an old version of an
application, possibly many years old, with a radically different file structure.
Or possibly your test suite takes a long time to run, you can kick it off on a
codebase in a separate worktree while continuing work on a different on in the
mean time. Similar for compiling a big thing.
Or you just need to switch between some branches a bunch and are tired of
worrying about stashing changes every time you switch.
This is supported by git with
[worktrees]( This allows you checkout
more than one branch from a single git repository.
You can of course do this by cloning the repo multiple times (or copying `.git/`
to a new dir, same thing), which is fine, but this has a couple downsides. One,
it multiples the amount of disk space taken, for large repos this could be an
issue. Two, it adds another layer to manage, you now need to pull updates for
each of the clones, which is inconvenient.
When you have one repo and you just want branches checked-out simultaneously,
worktrees are what you want.
# Repo archives
Some times it's useful to have a snapshot of your repo (or a part of the repo)
at a certain commit, for sharing or just as an artifact to store somewhere.
[git archive]( is your friend. It will
package up the repo in a zip or tarball, respecting your gitignore and such.
Make an archive for your version `v0.1.0`:
git archive -o v0.1.0.tar.gz v0.1.0
You can also limit it to just certain paths:
git archive -o v0.1.0.tar.gz v0.1.0 assets/
See more examples in the docs linked above.
You can also use it to *retrieve* an archive from a remote repo, if you don't
need the history, just the files at a certain commit. For example, say you just
want the code for version `v1.2.3` from a remote repo:
git archive --remote=<repo address> v1.2.3
GitHub also provides a URL you can hit for an archive of the repo in the format
For example:
You can replace the `.tar.gz` with `.zip` if you want a zip over a tarball. The
link for this is also provided in the GitHub UI under the "Clone or download"
# gitignore
So any repo or directory in a repo can have a `.gitignore` file and git
will, uh, ignore the files that match the patterns. "Project" ignores.
You can also have a global ignore file set to have really common stuff ignored
in all your projects. By default this is `~/.config/git/ignore`, but the
location can be overridden by the `core.excludesFile` configuration value (mine
uses `~/.gitignore`). These of course are not shared with the project.
"Personal" ignores.
You can also have "Personal Project" ignores by specifying patterns in
`.git/info/exclude` in a project (that's the `info/exclude` file the projects
`.git` directory). These are applied to the project, but not committed to the
repo and so not shared with others who check it out. When you have some files
laying around in a repo that you don't want/need to share (maybe personal notes
or todos for the project, your scratch space, some hacky scripts, etc.), but
also don't want showing up as untracked constantly, you can put them there.
# Checkout file from other branch
Sometimes you need to checkout current state of file from different branch.
It's just:
git checkout <branch> -- <file path>
# Misc. Stuff
- <>
- [Knowledge is Power: Getting out of trouble by understanding Git by Steve
Smith ]( (basic intro)
- When you need to nuke things:
- (very opinionated use of git)
- <> (very opinionated use of git)
- When you need to nuke things: <>
- When you need to fix things: <>
- <>
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment