git push origin --delete $(git branch --merged origin/master -r | grep -v master | grep origin | cut -d/ -f2-)
EDIT: And another thing. Turn all your Git aliases into shell aliases (e.g. "git status" is aliased to "git st" is aliased to just "st" on my system) with this one weird trick! https://github.com/majewsky/devenv/blob/2c4252d37597617a493f...
You can get around it doing the following:
_completion_loader git # manually load git completion functions
__git_complete g _git
alias ga='git add'
__git_complete ga _git_add
git branch --merged origin/master -r | grep -v master | grep origin | cut -d/ -f2-
fatal: remote part of refspec is not a valid name in :MARKET-446
However, not on board with the hate for rebase. If it's your feature branch and you aren't sharing it with others, I'd much rather get a cleaned up PR than one filled with junk commits because the author was afraid to rebase.
But in general I liked the article. It's under-appreciated how helpful a good commit log is.
Sometimes commit message deserves to be moderately long, like a paragraph or more. If one did not reference a code review or issue tracker link, for example, the need would likely be common. Even with an issue tracker there's value in capturing a few sentences of detail and sometimes more in the commit.
By capitalizing the commit message, it is natural to extend it from a single sentence phrase to a paragraph with an introductory sentence. I think of commit messages as analogous to JavaDoc where the first sentence or first line is taken as the subject, or like a document with a heading. It would be silly for short commit messages not to use capitalization while long do. A capitalized message works as a short description of the intro to a paragraph. Generally. once you're writing more than a single standalone sentence, capitalize. In a permanent medium where it can be either one, also capitalize.
A capitalized sentence or sentence fragment works in many contexts, like within a document or email. It would be annoying to convert going back and forth. Lastly, commit messages can sometimes act as names or proper nouns, and capitalization reinforces that role. Capitalization looks better as project or item headers in an issue tracker, and so to the extent that commits follow items, it's nice to consistently capitalize.
Capitalize commit messages because when Git tools generate commit messages, they generate capitalized ones. (Be consistent.)
I grok not capitalizing IM or IRC or other chat conversations, though I do if I start writing messages longer than a sentence. For everything but IM, capitalization constitutes the norm and good professional style.
This rationale might not be entirely satisfying, because why does English have capitalization to begin with? That's a linguistic question I don't know the answer to. However, I do know that the norms that lead to sentence capitalization also apply to commit messages and code documentation Not capitalizing them feels like refusing to capitalize any other writing: a potential distraction from the content.
foo: Add utf8 support
# If applied, this commit will...
# Explain why this change is being made
# Provide links to any relevant tickets, articles or other resources
In particular, it looks like this:
I like it because I find that adhering to this style lets me have a nice seat of easy to read commits which explain their purpose and scope clearly.
Also, it lets me use a tool like `clog-cli`  to generate pretty changelogs  automatically!
The only nitpick I have with this style is the fact that they recommend not capitalizing the first letter of the subject line. This means that, for example, in emails or when creating a PR, I have to capitalize the summary so that it looks correct. Minor, but annoying.
No: it's supposed to be written in imperative form. For those of us who are not linguists, it's easiest to explain this as a continuation of that phrase. However, it isn't a continuation. It stands on its own.
I can't recall where now, but I remember reading (and agreeing with) an article which proposed a slightly different format - describe what the commit did. "Fixes the js typo on the foo page".
Grammatically, I prefer this method as well, since the commit has already been applied, so it's not "going" to do anything; it's already been done.
Of course, the only difference is in the tense of the leading verb, so it's probably one of those "potato" thing.
Ain't English fun?
If it's telling me what to do, that doesn't make any sense either, since the work's already been done; the results of doing that work is the commit.
I guess it could be considered to be an abstraction of what request initiated the change, but what value does that provide when going back through git logs (when compared to a past or present verb tense that describes the changes)?
Squashing a merge commit is a perfect way to reintroduce old code back into master.
Squashing onto a merge commit is great way to lose changes. It's been a while since I have tried this, but creating a didactic repo if fairly easy. Create a repo with two feature branches, a file on each of master and the feature branches, merge featureA to featureB, make some changes or delete a file, `commit --amend` on the merge, and merge featureB to master. Then use `git cat-file` to look at those commits and commit trees. I've seen mysterious things such as simple as unreported changes to files mysteriously being deleted from the repo.
lg = log --all --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr)%C(bold blue)<%an>%Creset' --abbrev-commit
lg2 = log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold cyan)%aD%C(reset) %C(bold green)(%ar)%C(reset)%C(bold yellow)%d%C(reset)%n'' %C(white)%s%C(reset) %C(dim white)- %an%C(reset)' --all
lg = log --graph --decorate --pretty=oneline --abbrev-commit
And it makes sense to learn the basics in its native form and then learn the useful trinkets that are added on top - then your initial learning is restricted to the core so you are learning that which is transferable to all Git front-ends rather than learning specific to a particular GUI.
The way advanced users tend to work in my limited experience (I'm am very much not an advanced user) is to use the command line for the basic day-to-day working and then the GUI tools when anything more complicated (large and/or partial merges) is required.
Also, GUI tools almost always expect you to use the mouse, which I prefer to avoid.
But I do often use Emacs Magit which gives me most of the benefits you mention over the CLI.
git commit --fixup=<commitref>
git rebase -i --autosquash HEAD~5
git checkout -
(Of course, parsing text is a joy with Emacs/Lisp and a PITA in Go).
( ͡° ͜ʖ ͡°)
How do you guys feel about these in git commit messages?
If I see a commit that's just "¯\_(ツ)_/¯", I will force-push over it, don't you even think about it.
ll = log --graph --oneline --decorate --date=short --all --pretty=format:'%ad %h %Cgreen%an %Cred%d %Creset%s'
* 2016-04-11 86f68c3 Ivan Savov (HEAD, origin/bugfix/math_valign, bugfix/math_valign) Better solution to
| * 2016-01-20 df77345 Ivan Savov (origin/miniref, miniref) Customizations necessary for no BS math render
* 2016-04-07 364619f Michael Hartl (upstream/stable, upstream/master, origin/master, origin/HEAD, master) Change to bigger line height for EPUB/MOBI
* 2016-04-07 92952da Michael Hartl Bump version
* 2016-04-07 6a56c24 Michael Hartl Merge pull request #152 from jackkinsella/patch-2
| * 2016-03-23 216d410 Jack Kinsella softcover check compatible with brew
* | 2016-04-07 d792d4b Michael Hartl Merge branch 'minireference-feature/math_valign'
| * \ 2016-04-07 5fa560e Michael Hartl Merge branch 'feature/math_valign' of https://github.com/minireference/softcover into minireference-feature/math_valign
| |\ \
| | |/
| | * 2016-01-31 77a4e5e Ivan Savov (origin/feature/math_valign, feature/math_valign) Set veritcal-align for better looking inline math
* | | 2016-04-07 a369139 Michael Hartl Update README
* | 2016-03-21 0e94095 Michael Hartl Bump version number
* | 2016-03-21 a5fbc82 Michael Hartl Reuse menu headings in MOBI ToC
* | 2016-03-21 fadd558 Michael Hartl Merge branch 'master' of https://github.com/softcover/softcover
| * 2016-03-16 60dc7c9 Nick Merwin (tag: v1.2.5) added exercise generator for course chapters
* | 2016-03-12 fe2f844 Michael Hartl Lower the EPUB/MOBI line height
* 2016-03-10 bba610b Michael Hartl Make anal changes
* 2016-03-10 c9bad17 Michael Hartl (tag: v1.2.4) Bump version number
* 2016-03-10 8edf40a Michael Hartl Add symbols for euros and pounds
Imagine a scenario for a large team (think kernel). Chat logs of a team developing some feature look something like:
A: Ok, I have finished with issue1, check out commit abcd1
B: Hm, does not work for me. Looks like race condition in foo.c, fixed in abce2. Going to sleep.
C: You broke init_foo(), reverted in qwer3
A: Ok, modified init_bar() works on my machine, check dvor4
Yet release branch contains all those commits squashed into abcd1. Now person B (or anyone else) has no idea whether which versions of init_foo() and init_bar() work on their machine and what to fix.
We sometimes tend to forget (and tools like github/gitlab help with that) that not only git, but the whole workflow might be distributed and changing history in one place might desync it with other places. I think that unless all that history is absolutely unnecessary, e.g. done by a single developer, is extremely well tested, contains loads of "oops" commits, history should not be messed with. That's why all the warnings: git cannot manage all the references to history
A pre-commit hook probably works fine if your tests run in a few seconds. But in one of my projects, tests run for 10+ minutes and I want to get a test run on debug and release builds with a few different compiler versions. That's about 50 minutes of CPU time (but embarassingly parallelizable, although I typically don't do that). I don't want to have to wait for this to happen before every commit (not all of which even require testing, e.g. README commits).
Via travis I then run a full matrix.
git diff --name-only | uniq | xargs $EDITOR
and this one to open files with conflicts
git diff --name-only --diff-filter=U | uniq | xargs $EDITOR
git diff --stat
git add $(git diff --name-only)
git add -u
I rather use Git Extensions on windows and on mac Git Kraken. For beginners I think it would be better to use GUI tools.
Another reason why I advice learning the command line interface first is that it is the most versatile, so it's helpful to be able to fall back to it when necessary. Every GUI tool I've seen so far lacks a feature or two.
git checkout somefile
git rm -f somefile
I can also recommend these two aliases I have in my gitconfig:
unstage = reset HEAD --
undo = reset --soft HEAD^
git rm <file> to delete something you've added accidentally
(set -e; git rev-list --reverse upstream.. | while read r; do git checkout -q $r && make check; done)
In 2009 or so, I was using git-svn on the KDE SVN. I was preparing a major refactoring of Kolf in a local branch (about 60 commits with 10000 lines changed), and pushed it to the SVN once I was satisfied with it.
Unfortunately, the 20th-or-so commit failed because a SVN pre-commit hook rejected it (there were some DOS line-endings in a source file that I imported). At that time, git-svn was (AFAIR) already prepared to handle a failing SVN pre-commit hook on the first commit (e.g. when authorization is missing or stuff like that), but not somewhere in the middle.
The end result was that my working copy, my index, and my master branch was completely trashed. And I didn't have a backup... Luckily, the tip commit of my feature branch had not yet been packed, so a clever grep on .git/objects found it, and I could recover my pre-push state.
Since then, reflog has always been enabled on my systems. Luckily, I haven't needed it since.