News for hackers. Stuff that matters.
Re:Git 2.19.0 released by andy_ppp on Wednesday September 12, 2018 @10:16AM (#17968989)
Slightly off topic but just thought I'd say, my favourite git shortcut is: "git checkout -" which toggles between the current and the previous branch just like cd - does with directories.

What is your favourite git shortcut or feature!?

Re:Git 2.19.0 released by asdkhadsj on Wednesday September 12, 2018 @11:01AM (#17969456)
My favorite should be hooks. They're not exactly a shortcut, but they allow you to write logic to prevent yourself from doing dumb things.

Namely, I have two I need to write. One preventing master pushing, as sometimes I forget which branch I'm on if I'm all over the place. And two, preventing committing past a `wip` commit message. Arguably I shouldn't be using wip commit messages, but I prefer being able to have a "stash" per branch, of sorts. If I stashed it, I fear namespace clobbering as well as forgetting I even had a wip.

Re:Git 2.19.0 released by indosauros on Wednesday September 12, 2018 @03:33PM (#17972322)
I do the exact same thing. I find WIP stash-per-branch very useful when I'm context switching often between feature branches. I've got two aliases set up for this -- `git wip` and `git popwip`:

  $ git config --global alias.wip
  !git add --all && git commit -am 'wip'

  $ git config --global alias.popwip
  !git log -1 --pretty=%B | grep -q '^wip$' && git reset HEAD^ || echo 'HEAD is not a wip commit'
Re:Git 2.19.0 released by asdkhadsj on Wednesday September 12, 2018 @03:50PM (#17972501)
To extend this, I might make my CLI show `foo-branch (wip)` if the most recent commit is a wip. Your alias idea is golden though, definitely using this. Thank you!
Re:Git 2.19.0 released by vorpalhex on Wednesday September 12, 2018 @01:59PM (#17971307)
As long as your work is in a private branch, you can go back and squash those WIP commits into a single descriptive commit.
Re:Git 2.19.0 released by epicide on Wednesday September 12, 2018 @10:50AM (#17969330)
"git checkout -" is even better if you alias "checkout" to "co" since it just becomes "git co -".

Stash has to be my favorite (especially with "-u" AKA "include untracked").

I'm generally very comfortable doing even advanced stuff in git, but still get paranoid about some things. Especially when I'm trying to troubleshoot something for someone else.

Being able to stash away current changes in a place that is separate from any particular branch is invaluable.

I often show stash to people that make a habit of copying their entire project directory before doing something they aren't sure about (backups aren't inherently a bad idea, but that's why you push early and often).

Re:Git 2.19.0 released by napsterbr on Wednesday September 12, 2018 @12:10PM (#17970204)
> "git checkout -" is even better if you alias "checkout" to "co" since it just becomes "git co -".

And even better if you alias `git` to `g`!

Re:Git 2.19.0 released by jacobsenscott on Wednesday September 12, 2018 @12:53PM (#17970704)
Just go all out - alias g-='git checkout -'
Re:Git 2.19.0 released by epicide on Wednesday September 12, 2018 @02:40PM (#17971718)
Aliasing 'gg' to that would actually be pretty good. Unless you really need git gui.
Re:Git 2.19.0 released by pellucide on Wednesday September 12, 2018 @02:49PM (#17971814)
alias gb='git checkokut -'

gb for go back.

Re:Git 2.19.0 released by captn3m0 on Wednesday September 12, 2018 @03:06PM (#17972014)
Is there any good way to keep track of stashes? I keep stashing stuff that I forget about and end up rewriting 2 weeks later.
Re:Git 2.19.0 released by nimrody on Wednesday September 12, 2018 @03:20PM (#17972166)
Yes. Use a local branch. They are cheap to create. You can name the branch and, of course, write a descriptive commit message.

Stashes are for quick save and restore. Branches are way more powerful.

Re:Git 2.19.0 released by ramses0 on Wednesday September 12, 2018 @04:12PM (#17972729)
Hard agree here. Better to make "git my-stash working-on-foo" alias which makes a separate branch. Stashes have become an anti-pattern for me after having too many fail to reapply or drift out of date.
Re:Git 2.19.0 released by emmelaich on Wednesday September 12, 2018 @07:05PM (#17974316)
I have some aliases sl (stash list) and pop/drop for git stash pop/drop.

Also make a habit of saving your stashes with a meaningful label.

But yeah, like others suggest -- use branches.

Re:Git 2.19.0 released by ishwarn on Wednesday September 12, 2018 @06:51PM (#17974235)
I've made it a habit to `git stash list` and `git stash show -p stash@{2}` when I want to inspect the stashed changes.
Re:Git 2.19.0 released by hasperdi on Thursday September 13, 2018 @05:22AM (#17977188)
Git worktree changed my life. I can quickly switch branches and work on multiple branches at the same time.
Re:Git 2.19.0 released by kahlonel on Wednesday September 12, 2018 @11:31AM (#17969770)
As a developer who often needs to revert other developers' screwups (and sometimes my own): "git show COMMIT_ID -- somefile | git apply -R"
Re:Git 2.19.0 released by maccam94 on Wednesday September 12, 2018 @01:26PM (#17971014)
Isn't that the same as `git revert $commit` ?
Re:Git 2.19.0 released by schrodinger on Wednesday September 12, 2018 @02:14PM (#17971462)
I’m guessing that it’s different in that it only reverts one file, not the entire commit.
Re:Git 2.19.0 released by Lord_Zero on Wednesday September 12, 2018 @11:37AM (#17969835)
Git noob here, what does this do? I have read the docs on apply but I don't really understand patches. It sounds like you bundle a bunch of commits and allow someone to use them. But in that case, wuldnt you just push a branch and then the person who needs it can pull and merge it or rebase onto it or cherry pick it?
Re:Git 2.19.0 released by NateEag on Wednesday September 12, 2018 @11:42AM (#17969884)
It undoes the change made to `somefile` in `COMMIT_ID`.

Details: `git show <COMMIT_ID>` gives you the patch identified by COMMIT_ID. Appending ` -- somefile` narrows that patch down to only include the specified path.

The `-R` option to `git apply` tells it to apply the patch in reverse.

Thus, "undo the changes in `somefile` from this commit".

Re:Git 2.19.0 released by asymmetric on Wednesday September 12, 2018 @11:12AM (#17969559)
Another one: `git worktree add <path> <commit>`, which allows you to checkout another working tree at <commit> under the directory <path>.
Re:Git 2.19.0 released by jancsika on Wednesday September 12, 2018 @12:35PM (#17970498)
Whoa! I didn't know `cd -` did that. Thanks.
Re:Git 2.19.0 released by oconnor663 on Wednesday September 12, 2018 @01:29PM (#17971044)
I alias the command `git log origin/master.. --oneline`. (You could also do `git log @{upstream}.. --oneline` if you're diligent about configuring upstream branches.) That shows you how many commits you have locally that you haven't pushed yet. I use them compulsively, almost as frequently as I use `git status`.
Re:Git 2.19.0 released by glandium on Wednesday September 12, 2018 @08:55PM (#17975009)
I find `git show-branch --topics origin/master` (optionally adding branches) to be more useful.
Re:Git 2.19.0 released by JoshTriplett on Wednesday September 12, 2018 @01:52PM (#17971225)
What do you alias it to?

(Also, I tend to use just `git log origin..` rather than spelling out `origin/master`.)

Re:Git 2.19.0 released by jwilk on Wednesday September 12, 2018 @03:32PM (#17972315)
> I tend to use just `git log origin..` rather than spelling out `origin/master`

Doesn't work for me:

  $ git log origin..
  fatal: ambiguous argument 'origin..': unknown revision or path not in the working tree.
  Use '--' to separate paths from revisions, like this:
  'git <command> [<revision>...] -- [<file>...]'

  $ git log origin.. --
  fatal: bad revision 'origin..'
Re:Git 2.19.0 released by oconnor663 on Wednesday September 12, 2018 @04:18PM (#17972791)
Maybe it will work if you do `git branch --set-upstream-to=origin/master` first? But yeah, this config issue is why I don't use @{upstream} much.
Re:Git 2.19.0 released by oconnor663 on Wednesday September 12, 2018 @02:01PM (#17971332)
Personally "gout", which I now realize is a disease :p
Re:Git 2.19.0 released by jwilk on Wednesday September 12, 2018 @03:33PM (#17972323)
For me it's "git outgoing".
Re:Git 2.19.0 released by jolmg on Wednesday September 12, 2018 @05:41PM (#17973681)
Even shorter: `git log @{u}..`
Re:Git 2.19.0 released by saidajigumi on Wednesday September 12, 2018 @12:10PM (#17970205)
In a script called `git-first-push`, on your path:

    #!/bin/zsh

    git push -u ${1:-origin} HEAD:"$(git symbolic-ref -q HEAD | sed -e 's|^refs/heads/||')"

This means "push the current branch to origin (or the first argument, if specified) to a branch of the same name, when this hasn't been done before. Set origin (or the first arg) as the upstream of the local branch". Formally invoked as `git first-push [remote]`, I just alias it to `git fp`.

EDIT: I've forgotten offhand whether there are actual zsh-isms here. It's probably bash compatible, but I always have zsh installed by the time this script lands on a system.

Re:Git 2.19.0 released by phamilton on Wednesday September 12, 2018 @12:31PM (#17970441)
how is this different from:

    git push -u origin head

?
Re:Git 2.19.0 released by saidajigumi on Wednesday September 12, 2018 @01:51PM (#17971214)
Good point; I'd missed that someone taught git a smarter "spelling" for this task. IIRC, `git push -u origin HEAD` didn't used to automatically create a branch of the same name on that remote -- the explicit colon notion was required. I've had this little script around for a long time...
Re:Git 2.19.0 released by majewsky on Thursday September 13, 2018 @02:50PM (#17981275)
I just do

  git push -u
which does what I want since I set

  git config --global push.default=current
Re:Git 2.19.0 released by bpeebles on Wednesday September 12, 2018 @10:23AM (#17969051)
A simple one, but learning that -p works for checkout as well as add.
Re:Git 2.19.0 released by jolmg on Wednesday September 12, 2018 @02:36PM (#17971671)
as well as reset and stash, too.
Re:Git 2.19.0 released by jgalentine007 on Wednesday September 12, 2018 @09:58PM (#17975321)
Have made thousands of commits, TIL. Thanks! I like git smudge and clean for keeping secrets out of files, I created a small utility to automate the process and make it easy to do multiple regex substitutions. Here it is, if it helps anyone: https://www.npmjs.com/package/no-secrets
Re:Git 2.19.0 released by Waterluvian on Wednesday September 12, 2018 @11:54AM (#17970049)
I had to add this feature with a third party script but I love `git open` for opening the current repo webpage in my browser.
Re:Git 2.19.0 released by jwilk on Wednesday September 12, 2018 @03:37PM (#17972366)
Where can we get this third party script?
Re:Git 2.19.0 released by Waterluvian on Wednesday September 12, 2018 @07:17PM (#17974402)
Re:Git 2.19.0 released by cakes on Wednesday September 12, 2018 @12:20PM (#17970302)
the '-C' option to let me do git operations without being in that directory is vastly helpful when I go to script against a variety of git repositories (--git-dir is pretty nice too, I just don't often have a use for it)
Re:Git 2.19.0 released by tialaramex on Wednesday September 12, 2018 @01:15PM (#17970909)
"git bisect" is my overall favourite feature, I think it's illustrative of the same widely applicable phenomenon as git itself. Lots of people would know in principle that this idea - binary search for a change introduced at some unknown previous point - is a good way to approach the problem, many of them could implement such a thing, but for whatever particular problem it may never seem like it's quite worth the effort to do so. But, by expending this effort just once (as "git bisect") our culture gets the reap the benefit essentially forever.

But if you use git around me the thing I'll keep talking about is force with lease (as seen in e.g. "git push --force-with-lease"). I believe this is a specific implementation of an idea with much broader possibilities that we should see in a LOT more places.

The central idea of force-with-lease is that when I'm telling a machine that I understand all the circumstances and nevertheless I wish to proceed anyway, I should need to tell the machine what these circumstances are that I'm claiming to understand. For example I know the current state of the tree is rel-4.2.6-20180911 and I'm confident that we want to smash that, and put rel-4.2.6-20180912 there, even though that rewrites history. Then the machine can check automatically that those _are_ the circumstances and refuse to override if not.

In git the reason to have this feature is that it prevents the situation where I think rel-4.2.6-20180911 is in the branch, I'm sure I want rel-4.2.6-20180912 there, so I force that, but unfortunately while I was deciding to do that somebody else landed rel-4.2.7-20180912 and so I've ruined everything by forcefully reverting their change.

The broader idea is very widely applicable. In Puppet for example, somebody can tell the system to stop updating node-04 because "Barry found a problem with XYZ on this node, check with Barry before re-enabling". And if you try to update node-04 it will recite that blurb and refuse. But, you can force enable node-04 without reading the blurb, and worse, if meanwhile another engineer changes it to "Figured out XYZ. Definitely don't re-enable Puppet without talking to me, Sarah" you won't even know that happened, your override will take effect anyway even though you'd no chance to know you should call Sarah.

Even in non-IT systems I think this approach has great merits. Consider a railway signal system. Most of the system isn't the "signals" (which are mostly boringly simple and reliable colored lamps) but the sensors verifying that the state of the system is consistent and safe. Humans are often authorised to overrule this system in small ways when things go wrong. A sensor says it isn't sure if the motorised points at a junction are closed, so the system refuses to move signals from "Danger" for that junction. The human signaller is authorised to tell human train drivers to ignore this Danger signal and proceed, albeit it "at caution, obeying all other signals". But wouldn't it be better if the system required the humans to acknowledge specifically that they've understood the problem is that the sensor says these points aren't locked? Now the driver is thinking about the points, which might not be locked, rather than just vaguely knowing something, somewhere, is busted. Guess who is going to take a proper look at those points before driving over them now! And when the next train arrives, and the signaller tries to let it through, if in fact NOW the problem is that the points are fine but the axle counter says the previous train never left, the signaller would need to diagnose and accept this situation, not just wave through another train assuming it's the same fault because it has the same symptom (signal at danger).

Re:Git 2.19.0 released by gcb0 on Wednesday September 12, 2018 @02:19PM (#17971515)
I alias checkout to cd, so it is natural to use 'git cd -'
Re:Git 2.19.0 released by emmelaich on Wednesday September 12, 2018 @07:03PM (#17974297)
Wow nice, only yesterday I was thinking I wanted exactly that.
Re:Git 2.19.0 released by masklinn on Wednesday September 12, 2018 @11:24AM (#17969688)
> What is your favourite git shortcut or feature!?

Revsets. Oh wait, git doesn't have revsets it has the ungodly pile of shit that is gitrevisions(7)

Re:Git 2.19.0 released by jolmg on Wednesday September 12, 2018 @02:43PM (#17971735)
Didn't downvote, but this comment would have been better without the attitute. Something like: "what I wish it had were revsets" or "changing the topic a little, I hate that git doesn't have revsets". Anyway, what are revsets?
Re:Git 2.19.0 released by masklinn on Wednesday September 12, 2018 @03:11PM (#17972069)
> Anyway, what are revsets?

Reifying revisions as sets and applying set combinations and predicates to these revision sets: https://www.mercurial-scm.org/repo/hg/help/revsets

It makes for flexible, reliable and readable revisions specifications.