News for hackers. Stuff that matters.
Re:Better Git configuration by scrollaway on Wednesday April 05, 2017 @08:53PM (#14047062)
I want to also recommend the following:

git config --global stash.showPatch true: A recent addition to git which defaults the -p flag to `git stash show`; meaning `git stash show` shows the diff from that stash (should really be default...)

git config --global rebase.autostash true: will automatically stash and unstash the working directory before and after rebases. This makes it possible to rebase with changes in the repo.

git config --global log.decorate full: Always decorate `git log`

Re:Better Git configuration by masklinn on Thursday April 06, 2017 @06:10AM (#14049276)
Other settings I appreciate:

    rebase.autoSquash true
When committing you can specify --squash=<commit> or --fixup=<commit>, `git rebase -i --autosquash` will then automatically move and mark the relevant commits in your rebase queue. Setting autosquash into your config enables it by default for all interactive rebases.

    user.useConfigOnly true
that's really convenient when you routinely use multiple identities on the same machine (e.g. personal and work): by default if you haven't configured an identity locally git will fallback to global, and then to guessing based on your current user and machine.

useConfigOnly mandates an explicit configuration, then you can just remove any global user or email, and git will require the correct configuration of any local repository before allowing commits.

    alias.original "!git show $(cat .git/rebase-apply/original-commit)"
when performing a rebase (interactive or not) it can be difficult to remember what the original intent of a specific commit is when it's mixed with conflict markers. This shows the original commit being rebased.

    alias.git "!git"
I regularly type "git", go do something else, remember what I wanted to do and type "git <command><return>". This makes "git git git git show" work instead of barfing.

Finally

    merge.tool <yourtool>
Will automatically use the specified tool when invoking "git mergetool", if you like external utilities to perform merges or conflict resolution (e.g. emerge, kdiff3, araxis, vimdiff3, meld, etc… the list of builtin tool support is accessible via "git mergetool --tool-help")
Re:Better Git configuration by collinmanderson on Friday April 07, 2017 @10:15AM (#14059777)
I just use `git show stash` rather than `git stash show`.
Re:Better Git configuration by gsylvie on Wednesday April 05, 2017 @09:36PM (#14047241)
This has saved me:

    git config  --global pull.ff only
I can always override an individual pull invocation with either "git pull --rebase" or "git pull --no-ff", making it a conscious choice when a fast-forward pull is not possible.
Re:Better Git configuration by ninkendo on Thursday April 06, 2017 @10:45AM (#14050949)
Oh wow, this must be a recent feature, I remember looking for a way to configure `--ff-only` by default a few years ago and it didn't seem possible. I ended up making a git alias of `git puff` which calls pull with the `--ff-only` flag.
Re:Better Git configuration by gsylvie on Thursday April 06, 2017 @12:53PM (#14052300)
Looks like it showed up with commit b814da891e, and has been around since Git v2.0.0.

The online docs mention it in Git v2.1.0: https://git-scm.com/docs/git-config/2.1.0

Re:Better Git configuration by gsylvie on Thursday April 06, 2017 @01:09AM (#14048076)
p.s. If you set this config, and a fast-forward pull is not possible, here is what git does:

    $ git pull
    fatal: Not possible to fast-forward, aborting.
Re:Better Git configuration by ymse on Wednesday April 05, 2017 @08:37PM (#14046988)
Oddly, the author recommends signing commits, yet uses only fast-forward merges. Little do they know that signed commits necessarily can not be resolved as fast-forwards in a merge situation, since that would require changing the signatures!

Rebasing is the answer, but that will of course re-sign every commit with your key. In a shared repository, I prefer creating "useless" merge commits to changing other peoples signatures.

Re:Better Git configuration by scottnonnenberg on Wednesday April 05, 2017 @08:43PM (#14047021)
My local configuration doesn't need to be ready to create merge commits because those happen on GitHub/GitLab/etc. When I rebase, it's my own pull request on top of a more recent master - the signer remains me.
Re:Better Git configuration by rlpb on Thursday April 06, 2017 @09:32AM (#14050308)
Perhaps I misunderstand you, but a fast forward merge isn't really a merge (there is no merge commit) and by definition doesn't change any commits. So it doesn’t require changing any commits, and therefore no signatures need changing either.

Is there some other part of a workflow that you're inferring here that will need changing commits?

Re:Better Git configuration by growse on Thursday April 06, 2017 @04:08PM (#14054132)
If you have a feature branch with multiple commits signed by multiple people, does rebasing that not invalidate the signatures (changes the parent and thus every hash)?
Re:Better Git configuration by rlpb on Friday April 07, 2017 @08:25AM (#14059045)
I see. The rebasing you mention is part the implied workflow I was missing. I see it now. Yes - if the rule is that merge commits to master are not permitted (ie. all commits must be rebased onto master first), then of course one person cannot rebase someone else's signed commits without losing those signatures. Thanks.

Theoretically one could devise a tool which allows each contributor to re-sign (in the correct order), but I'm not aware that any such thing exists, and it'd probably be too impractical anyway.

Re:Better Git configuration by dilap on Thursday April 06, 2017 @01:28PM (#14052633)
Here's one: Use:

    git push --force-with-lease
Instead of

    git push -f
(Obviously ideally you'd never do either, but sometimes life happens.)

The advantage of the former over the latter is that it won't push if you haven't already seen the ref you're overwriting. It avoids the race condition of accidentally "push -f"ing over a commit you haven't seen.

(Why this isn't the default, I have no idea.)

Re:Better Git configuration by scrollaway on Thursday April 06, 2017 @03:13PM (#14053633)
Yes, force-with-lease is really useful. I set it up as an alias of git fpush, and have never used push --force since.
Re:Better Git configuration by aeontech on Thursday April 06, 2017 @01:24AM (#14048150)
I really like diff-so-fancy [1] highlighter as a pager and to review diffs. Previously discussed here on HN here: [2]

[1]: https://github.com/so-fancy/diff-so-fancy

[2]: https://news.ycombinator.com/item?id=11057421

Re:Better Git configuration by mi100hael on Wednesday April 05, 2017 @07:22PM (#14046601)
Some good tips in here. I also like to add the following alias to give me a more condensed log with graph & tags:

    hist = log --pretty=format:\"%C(yellow)%h%C(reset) %C(green)%ad%C(reset) %C(red)|%C(reset) %s %C(bold blue)[%an]%C(reset)%C(yellow)%d%C(reset)\" --graph --date=short
Re:Better Git configuration by pavel_lishin on Wednesday April 05, 2017 @07:38PM (#14046692)
I have a similar one:

    lg2 = log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen%cn%Creset %Cblue(%cr)%Creset' --abbrev-commit --date=relative
Shows dates at the end, in a relative format (2 days ago, 29 hours ago, etc) and the tags/branches before the commit message.
Re:Better Git configuration by nichochar on Wednesday April 05, 2017 @08:01PM (#14046826)
So do I! lg = log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit
Re:Better Git configuration by pavel_lishin on Wednesday April 05, 2017 @09:05PM (#14047120)
Date before author? Blasphemeeeeeeee†!

† http://oglaf.com/assorted-fruits/ (sfw)

Re:Better Git configuration by dilap on Thursday April 06, 2017 @10:48AM (#14050977)
I will never understand why people hate merge commits. It's an accurate history of what happened, and can be useful in tracking down bugs.
Re:Better Git configuration by bluehawk on Thursday April 06, 2017 @12:41PM (#14052171)
It's a trade off. In my opinion when using rebase you don't lose history or make it inaccurate. A bug would still be introduced by the commit that made it, so tracking down bugs with bisect or other tools works the same. The main advantage is that your history is much cleaner.
Re:Better Git configuration by chrisan on Thursday April 06, 2017 @07:56AM (#14049742)
One thing I like to do is alter the coloring as an aide for `git status` which is giving "changed" a yellow as an intermediary color

    [color "status"]
            added = green
            changed = yellow bold
            untracked = red bold
Re:Better Git configuration by jph on Wednesday April 05, 2017 @08:48PM (#14047034)
Many git alias ideas: https://github.com/gitalias

Improvements and pull requests are welcome.

Re:Better Git configuration by ereyes01 on Thursday April 06, 2017 @03:35AM (#14048655)
I'm a long time vim user and my brain is wired to reach for the keyboard shortcuts in vimdiff to jump from diff to diff. Also, I really love diffing entire trees in one vim session using the DirDiff plugin (https://github.com/will133/vim-dirdiff).

Here's how I wire it into my .gitconfig, which gets me the alias "git dirdiff":

  [difftool "default-difftool"]
    cmd = gvim -f '+next' '+execute \"DirDiff\" argv(0) argv(1)' $LOCAL $REMOTE

  [difftool]
    prompt = false

  [alias]
    difftool --dir-diff
... I like to use gvim to open new windows separate from my terminal, but if you prefer you can just use plain vim in there as well.

Also, if using vim for viewing diffs, you might want to hack vim's config as well to make it look good. I like to (effectively) disable folding of lines with no diffs so I can still read the whole file- I use the shortcuts ]c (next diff) and [c (previous diff) to jump around diffs. I also like to disable editing in diff mode.

Here's my diff-related .vimrc hackage:

  if &diff
  	set lines=60 columns=184
  	set foldminlines=99999
  	set nomodifiable
  	set nowrite
  endif
Re:Better Git configuration by jwilk on Thursday April 06, 2017 @05:54AM (#14049212)
The last section should be:

  [alias]
    dirdiff = difftool --dir-diff
Re:Better Git configuration by ereyes01 on Thursday April 06, 2017 @04:14PM (#14054171)
Copy/paste fail... Thanks for catching
Re:Better Git configuration by gitaarik on Thursday April 06, 2017 @08:40AM (#14049961)
I have a dedicated Git tmux tab for every repo I'm working on, in that tab I use a git shell. Initiated by this bash function:

    # A nice shell prompt for inside git repostories
    # Shows a short status of the repository in the prompt
    # Adds an alias `g=git` and makes autocomplete work
    gitprompt() {

        __color_bold_blue='\[$(tput bold)\]\[$(tput setaf 4)\]'
        __color_white='\[$(tput sgr0)\]'

        export GIT_PS1_SHOWDIRTYSTATE=true;
        export GIT_PS1_SHOWSTASHSTATE=true;
        export GIT_PS1_SHOWUNTRACKEDFILES=true;
        export GIT_PS1_SHOWUPSTREAM="auto";
        export GIT_PS1_SHOWCOLORHINTS=true;
        . /usr/lib/git-core/git-sh-prompt;

        local ps1_start="$__color_bold_blue\w"
        local ps1_end="$__color_bold_blue \\$ $__color_white"
        local git_string=" (%s$__color_bold_blue)"

        export PROMPT_COMMAND="__git_ps1 \"$ps1_start\" \"$ps1_end\" \"$git_string\""

        # Short alias for git stuff
        alias g=git

        # Make autocomplete also work fo the `g` alias
        eval $(complete -p git | sed 's/git$/g/g')

    }
So I have this in my `.bashrc` and when I want my bash to get a handy Git prompt I type `gitprompt`.

You do need the file `git-sh-prompt` which should come with git, for me it's located in `/usr/lib/git-core/git-sh-prompt`. It's also available here:

https://github.com/git/git/blob/master/contrib/completion/gi...

Re:Better Git configuration by hiphipjorge on Wednesday April 05, 2017 @09:44PM (#14047280)
I'm going through my gitconfig and I'm realizing there's ALL THESE really nice shortcut I literally never use.
Re:Better Git configuration by Cthulhu_ on Thursday April 06, 2017 @07:40AM (#14049653)
Same, it's hard to break one's finger memory when you're used to e.g. typing `--force --no-verify` in full all the time. Although imo those should always be typed out in full.
Re:Better Git configuration by AlexCoventry on Thursday April 06, 2017 @09:16AM (#14050188)
Seems like most of these enhancements have matching features in emacs's magit, which also offers many others.

Which is not to dismiss these: Using magit involves its own cognitive load.

Re:Better Git configuration by r0muald on Thursday April 06, 2017 @12:49AM (#14047986)
> I will never accidentally create a merge commit

What is the big deal about creating a merge commit? It that because you only merge in `origin` (wherever that lives)?

Re:Better Git configuration by mikekchar on Thursday April 06, 2017 @01:15AM (#14048109)
This really depends on your style of using git. If you are rebasing (or otherwise changing history), merge commits can come back to bite you. You've got to make sure that you are dealing with the correct side of the branch. One side will have the history you need, while the other side may not. This can lead to serious weirdness like git reverting changes without telling you.

If you are not changing history, then merge commit cause no harm at all. You've got to be a bit careful about reverts and again choosing the correct side of the history, though.

IMHO, the rebasing style is great when you are working with a group that understands how git is working under the hood. As long as they don't do anything to break stuff, then it's very nice. If you are working with a team which a bit more laissez fair, then merge commits are generally safer -- just make sure to tell then never to change history (rebase, force push, etc).

If you mix the two, you will be spending the odd afternoon piecing your git repository's history together by hand. It is seriously not fun.

Re:Better Git configuration by scottnonnenberg on Thursday April 06, 2017 @01:02AM (#14048038)
Yep, as I mention down-thread, merges only happen at GitHub/GitLab/etc.

The two mistaken scenarios I run into the most are:

1. `git pull` when I'm not in the right branch, which will want to do a merge.

2. When I have commit access on the master branch, and I do a `git merge branch` when that branch hasn't been properly rebased on master. My preference is no merge commit here, so I like that Git can catch this.

Re:Better Git configuration by mikegerwitz on Thursday April 06, 2017 @09:54AM (#14050487)
This references my Git Horror Story article from 2012. Which is fine, but note that git has evolved a lot since then, and you should also seek out some of its more modern conveniences (this thread's article mentions a number of them). I've been telling myself I'll update this article for the past few years. I'll get to it eventually.

As an alternative to git's aliases: if you're sick of typing `git' all the time, feel free to adapt this little script to suit your needs (allowing you to type e.g. `a' instead of `git add' and such, with tab completion):

  https://gitlab.com/mikegerwitz/git-shortmaps
Re:Better Git configuration by teekert on Thursday April 06, 2017 @03:23AM (#14048614)
I'm a git noob. I realy mis an option to simply backup my current work situation to Git and work further on it on another machine, or simply later with the knowledge that everything is safe on the server. Currently I have a big list of commits called "Backup" which I always push immediately. It's ugly. Is there a way to save to the git server your current situation with bothering others working on the project with your commits?

Maybe this is simply not what Git is made for and I should use Git from my NextCloud folder to have my data safe on a server?

Re:Better Git configuration by cytzol on Thursday April 06, 2017 @04:05AM (#14048785)
What you could do is commit half-finished work with the name “Backup”, and then commit --amend over the top of it once that piece of work has completed. This ensures your for-sync-only commits won’t get in the way of the other commits.

However, I recommend you use a separate tool for backups and syncing than the tool you use for version control. For example, you could use Rsync to push the files -- both the .git folder and your source code files -- to a remote server, and then pull them down on another computer. Not only will you only be committing for actual commits, but you can also save the state of your repository and continue working on it later; you could stage certain files and not commit them, sync your .git folder to another machine, then have those same files staged but not committed.

Re:Better Git configuration by markild on Thursday April 06, 2017 @03:36AM (#14048663)
Sounds like you want to work on a separate branch. Also sounds like you'd want to rebase onto the correct branch when done, so that you can reorganize commits
Re:Better Git configuration by teekert on Thursday April 06, 2017 @03:41AM (#14048686)
I do work on my own branches indeed. But something like "git sync" would be nice, no commits, no mess for your collaborators or in your Git history, just my current work, safe on the server, to be synced elsewhere without formally committing anything so that commits can be real improvements that require a commit message. Git sync would be the equivalent of hitting ctrl-S working on a doc in a Dropbox folder. You hit ctrl-S, boom it's safe on the server. I'd setup git sync to sync regularly and allow you to go back in time, or if you want, completely back to the last formal commit.

Git feels so local and thus vulnerable to theft, breakage, power outages etc.

Re:Better Git configuration by sangnoir on Thursday April 06, 2017 @04:18AM (#14048831)
> I do work on my own branches indeed. But something like "git sync" would be nice, no commits, no mess for your collaborators or in your Git history, just my current work, safe on the server, to be synced elsewhere without formally committing anything so that commits can be real improvements that require a commit message.

You seem to be hung-up on commits or have an inexplicable aversion (IMO) to committing to a private, expendable branch. Git made branching cheap and easy by design - you can go crazy on your private 'backup' branches without having to add detailed commit messages. When you are happy, you can rebase or squash merge into the 'real' branch with proper commit messages and delete the backup branch. This will not create a mess for collaborators or your Git history (after you've deleted the ephemeral branches).

As a matter of fact, you could create an alias for 'git sync' that does the above in the background, if you find the individual steps too tedious to manually type in.

Re:Better Git configuration by lomnakkus on Thursday April 06, 2017 @03:54AM (#14048744)
I do basically what the parent suggested for all my git work, i.e. it's my workflow. Call your branches wip-* to signal that you'll be using it haphazardly, don't bother doing "clean" commits while working (just commit stuff whenever you feel like it or when you might want to backtrack an experimental change, use the message "wip" or whatever). Push to branch whenever you want a "backup", e.g. when moving to a different machine.

When done, clean up the history[1], push to a different "real" branch for review. Delete wip-* branch.

Unless people have actively checked out your branch locally they shouldn't have any "mess" on their end. (They'll have a remote branch listed by "git branch -r", but all of those can be cleaned up periodically with a "git prune ...".)

I haven't heard any complaints so far. (I've been doing it this way for 4+ years, I think.)

[1] I usually find that it's easier to split/clean up after the feature is almost completely done and ready for review. When I'm "in the zone" I don't want to have to suddenly switch to the "cleaning up history" mode.

Re:Better Git configuration by kuahyeow on Thursday April 06, 2017 @03:54AM (#14048743)
The workflow is entirely up to you and your collaborators. "commit" does not have be literally a commitment. Try branching on your branches so that you have the freedom to experiment.
Re:Better Git configuration by selckin on Thursday April 06, 2017 @03:44AM (#14048704)
You could push to a private git repo or server, that way you don't bother anyone, and then when you're in a clean state push to the origin
Re:Better Git configuration by petepete on Thursday April 06, 2017 @04:00AM (#14048769)
This is the best method in my opinion. Back up simply by

    git push backup my-new-branch
Re:Better Git configuration by llimllib on Wednesday April 05, 2017 @10:15PM (#14047398)
Don't set fsckobjects=true. There are normal repositories that have broken trees which will not download if you have it set. Yes it is irritating and I would rather turn it on, but I had to turn it off after several repos failed for me.

Git doesn't check validity of commit hashes by default: https://groups.google.com/forum/#!topic/binary-transparency/...

Re:Better Git configuration by peff on Wednesday April 05, 2017 @10:52PM (#14047549)
I'm not sure what you mean by this last sentence. But Git always computes the SHA1 of incoming objects (that's how it knows that the SHA1 is; the other side doesn't send it). And it likewise confirms that it has every object which is referenced by the newly fetched history.

The fsckObjects settings are entirely separate from the SHA. They are about syntactic and semantic rules in the objects themselves (e.g., well-formatted committer name/dates, tree filenames that don't contain "/", etc).

Re:Better Git configuration by scottnonnenberg on Wednesday April 05, 2017 @10:17PM (#14047405)
Wouldn't it make sense to turn that off per-project when you encounter it?
Re:Better Git configuration by llimllib on Wednesday April 05, 2017 @10:21PM (#14047418)
That wasn't a hassle I was willing to deal with, I guess at least know that you're going to be doing that if you enable it.

IIRC, the jquery repo was an example of one with a bad object hash.

Re:Better Git configuration by astrostl on Thursday April 06, 2017 @09:58AM (#14050516)
When I want/need to customize this much, I tend to think poorly of the tool.
Re:Better Git configuration by Ajedi32 on Thursday April 06, 2017 @10:09AM (#14050615)
I'm guessing you don't like Vim or EMACS then? Or the command line in general?

Most of the development tools I use on a regular basis tend to be extremely customizable, and I regard that as a Good Thing.

Re:Better Git configuration by nulagrithom on Thursday April 06, 2017 @10:37AM (#14050868)
To each their own. Sure my coworkers complain about this or that annoyance in WebStorm or whatever that they can't customize or fix, but then they never lost the better half of a day to ~/.vimrc so...

I can see it both ways. I'll choose customization, but I wouldn't fault someone for expecting a good out-of-box setup.

Re:Better Git configuration by astrostl on Thursday April 06, 2017 @11:12AM (#14051225)
I'm a fan of being customizable. I'm not a fan of practically needing customizations.

My main editors are Vim and VS Code, both of which I find perfectly usable OOTB.

Re:Better Git configuration by deadbunny on Thursday April 06, 2017 @11:33AM (#14051474)
4 aliases and 5 settings (2 require other software, gpg signing and difftool)? I tune more things in my browser.
Re:Better Git configuration by cat199 on Thursday April 06, 2017 @11:01AM (#14051105)
Just need to read the manual better:

https://git-man-page-generator.lokaltog.net/

Re:Better Git configuration by partycoder on Thursday April 06, 2017 @02:00AM (#14048287)
There are some good tips there, like using GPG. I am definitively going to get that set up for my project.

Now, I always merge with no fast-forward because it creates a commit for the merge that you can revert.

    git merge --no-ff
Then, I always pull with rebase... That will apply your changes on top of the remote ones. It may lead to conflicts but it leads to a log with less branches.

    git pull --rebase
The merge/diff tool I use is p4diff, which comes with P4V (Perforce visual client) and is free.

To explore the git log, I use tig. https://github.com/jonas/tig

It is a curses interface to git. Screenshot: https://atlassianblog.wpengine.com/wp-content/uploads/tig-2....

Re:Better Git configuration by pstadler on Thursday April 06, 2017 @03:40AM (#14048683)
Shameless plug. I published a little guide some months ago, on how to use GPG with keybase.io to sign commits.

Link: https://github.com/pstadler/keybase-gpg-github

Discussion on HN: https://news.ycombinator.com/item?id=12289481

Re:Better Git configuration by floatboth on Thursday April 06, 2017 @06:34AM (#14049370)
I have a ridiculous "vim style" alias setup: https://github.com/myfreeweb/dotfiles/blob/4eb052cc54f9edcc8...

So I can just e.g. type "g ws" to tell [g]it to give me the [w]orking tree [s]tatus. Seeing people actually type "git status" is just painful.

Re:Better Git configuration by mrkgnao on Thursday April 06, 2017 @08:34AM (#14049934)
That's impressive. Together with (neo)vim as $GIT_EDITOR I can see that being really nice to use.

Now you could decide to systematize the "grammar" of your shortcuts somehow, and, well... it's definitely an idea people have had before. ;)

https://magit.vc/screenshots/popup-diff.png

Not an Emacs fanboy, by any means: I use Spacemacs. Magit is objectively excellent, though.

Re:Better Git configuration by shandor on Thursday April 06, 2017 @06:56AM (#14049446)
Me too, though I have them setup on shell rather than .gitconfig. Saves that one space after 'g' :)

The ones I find myself using most are 'gru' for git remote update, and 'gka' for "gitk --all -500 &". (The -500 is there to prevent my laptop dying when I run gitk with --all on the Linux kernel repo without second thought...)

Re:Better Git configuration by hyperpallium on Thursday April 06, 2017 @02:05AM (#14048307)
How can I make git diff default to --color-words, instead of:

  [alias]
    wdiff = "diff --color-words"
Re:Better Git configuration by dotancohen on Thursday April 06, 2017 @07:14AM (#14049533)
That would most likely be:

  $ git config color.diff always
Re:Better Git configuration by turboladen on Thursday April 06, 2017 @05:27PM (#14054794)
oh-my-zsh has some great git aliases too (scroll down 1/3 of the page): https://github.com/robbyrussell/oh-my-zsh/wiki/Cheatsheet
Re:Better Git configuration by rajathagasthya on Wednesday April 05, 2017 @08:17PM (#14046890)
Nice post. I didn't know about the followTags = true until now and I'm using it in my .gitconfig.
Re:Better Git configuration by papag on Thursday April 06, 2017 @07:56PM (#14055821)
Nice to hear from a fellow mustang!