Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Tips for Intermediate Git Users (andyjeffries.co.uk)
132 points by pmoriarty on Jan 12, 2015 | hide | past | favorite | 35 comments


This looks like a set of notes that are mostly correct but encourage bad practices. I think it's because they author doesn't understand git and doesn't know what they are doing.

>A lightweight tag is simply a named pointer to a commit. You can always change it to point to another commit.

Umm, you can do this, but in general you should never rename tags. Occasionally a developer will tell me the tag they pushed is incorrect and I'll agree to remove it only if they promise not to re-create it. If you read the man page on git-tag it's clear why you should avoid doing this.

>A lovely little tip – don’t forget that branch names aren’t limited to a-z and 0-9. It can be quite nice to use / and . in names for fake namespacing

If you use '/' is branch names you can create path conflicts. I've seen it happen and it took me a day to debug and figure out. There is some code checking for path conflicts in the git source but it's not invoked via all code paths that create branches. I recommend against using slashes in branch names unless you know what you are doing.


"I think it's because they author doesn't understand git and doesn't know what they are doing."

Thanks for your kind comment...

I would like to point out that this article is over 4 years old (hence my knowledge will have increased since then) and it was also basically my notes on our training with Scott Chacon of GitHub. I'm sure you wouldn't consider him to not "know what [he is] doing". Maybe it reflected best practices at the time the training was delivered and the article was written.

Anyway, I appreciate it's resurgence in popularity...


>If you use '/' is branch names you can create path conflicts. I've seen it happen and it took me a day to debug and figure out. There is some code checking for path conflicts in the git source but it's not invoked via all code paths that create branches. I recommend against using slashes in branch names unless you know what you are doing.

Can you elaborate on this? What you said doesn't make much sense. If having a slash in the branch name creates path conflicts, that means slashes are treated specially, right? How exactly does someone 'know what they are doing' to be able to use them?


Yeah. For example:

  $ git branch fireos
  $ git branch fireos/feature-branch
  error: unable to create directory for .git/refs/heads/fireos/feature-branch
  fatal: Failed to lock ref for update: No such file or directory
This happens because creating 'fireos' branch stores the sha1 in file .git/refs/heads/fireos. But if you later want to create branch 'fireos/feature-branch', git needs to store the sha1 in .git/refs/heads/fireos/feature-branch. This is impossible because 'fireos' is a file and cannot be a directory. Path conflict.


It gets even uglier when you don't discover those conflicts until a pull or push.


It can be solved with a right branch naming policy. E.g. where I work we usually name branches like "wp/BTS-number/1" for first attempt to do the BTS-number task, "wp/BTS-number/2" when we somehow need to try another approach or rebase or squash history, "wp/BTS-number/3" for next attempt and so on.

But its a global policy so "wp" and "wp/BTS-number" will always be a folder, and conflicts should never happen.


I really like to use '/' to create folders. Git (X) has a nice GUI for this naming convention.


> Umm, you can do this, but in general you should never rename tags. Occasionally a developer will tell me the tag they pushed is incorrect and I'll agree to remove it only if they promise not to re-create it. If you read the man page on git-tag it's clear why you should avoid doing this.

I'll take your word for it, but the git man pages are notoriously unreadable. They might be useful for a git guru, but for someone that is learning the commands they are downright harmful.


On the git-tag help page, there is a section "On Re-tagging" [0]. It looks quite readable to me.

[0] https://www.kernel.org/pub/software/scm/git/docs/git-tag.htm...


> I'll take your word for it, but the git man pages are notoriously unreadable. They might be useful for a git guru, but for someone that is learning the commands they are downright harmful.

Can you elaborate? I'm definitely not a git guru and I always read the man pages, and I find them quite readable. It's also the first place I learn best practices from.


Sure. I think this is largely a matter of preferences in pedagogy, but when I'm looking to learn something, I like to have heavily annotated examples that get progressively more complex.

Listing every option with a description, to me, is not as useful as seeing it in practice.


We use slashes at our company as a manner of course, and we've had no issues. We name all our features as `feature/i18n` and our bug fixes as `hotfix/ie-promises`.

Of course, we might have issues if we named a branch `feature` or `hotfix`, but that's never been an issue for us.


> If you use '/' is branch names you can create path conflicts.

You could say the same thing about filesystems though. Not sure this is an issue.


It's a gotcha for anybody, like me, that expects a branch name to be 'just' a string.


Yea, perhaps it's worth being explicit about it in the documentation, if it's not already mentioned.


The master tip: have a detailed written policy on git usage, on what goes into which branch, on git commit message format, and make really, really sure everyone understands it before they start anything.

No tips will help if the history is crap.


Is there some kind of git plug in/linter that will check for commit style before accepting a commit? Basically, linting the commit messages.


At my current gig we use a set of git hooks, and the pre-commit hook enforces the git comment style, which performs integration with bugtracking/timetracking. We wrote our own and it's just a couple of regexes tied to a couple of warnings.

Look in any git project's .git/hooks/ directory for some sample scripts.


a pre-commit git hook?

An example for jquery style commits is https://www.npmjs.com/package/commitplease


I've seen a project where the lead guy wrote two scripts he called "git-rebase-merge" and "git-lock". Imagine when you have the ability to lock and rebase merge commits. This leads to an endless stream of errors and head scratching.


> No tips will help if the history is crap.

So there should actually be a history of histories :) Perhaps something for the git team to pick up...



I replied to an individual comment, but I would just like to comment generally too - this article is 4 years old and if I wrote the article now there would have been more advanced information.

At the time beginners in git weren't doing much of this stuff, so they were tips for people who had used git daily, but this stuff wasn't common knowledge being done by all developers.

If anyone has anything they'd like to see in an advanced article, let me know and maybe I'll consider writing a "Tips for becoming an Advanced Git User" :-)


Just to add some value to this post: http://ndpsoftware.com/git-cheatsheet.html This is a tremendous help for those folks who have not yet reached intermediate level.


Thanks! I'm intermediate in some parts of git and not on others, but since I'm a visual learner this layout really helps me see how the different commands relate to each other.


It looks like this is a list to get to you intermediate level in git, as opposed to tips for already intermediate git users .

I would have liked to see some points about git-bisect, hooks, etc.


Agreed. I was expecting more substance in the hooks department, diffs, or other things off the beaten path. This just seems like a list of the basic git commands.


I find this hardly informative. Those users who consider themselves intermediate already know all this stuff. When I clicked the link I thought I will see about interactive rebasing, advanced stashing and stuff like that. There are other things which are already mentioned by others but the tag handling advice is horrible. Tags are meant to be immutable milestones. Never change them and please don't encourage people to do so.


I've found in practice that using "stash" is a very effective way to ensure you'll spend lots of time in the future looking for a lost branch. I don't like stash anymore.

I like the idea of aliasing the command unstage, but once "reset HEAD" is in the muscle memory its kinda stuck.

Is git-flow still cool? Or is it so popular its just assumed to be in use as a standard, thus well beneath the level of an "intermediate" users guide? If you don't use "the" git flow repo, at least as a branch naming strategy and overall usage strategy it's worked pretty well for me.


These aliases (from ~/.gitconfig) proved to be invaluable countless times, I hope someone will find them useful:

    [alias]
        logo = log --oneline --graph --all --decorate
	logg = log --graph --all --decorate
	logt = log --date-order --graph --tags --simplify-by-decoration --pretty=format:'%ai %h %C(Yellow)%d%Creset'
	ignored = ls-files --others -i --exclude-standard
Explanation:

    logo, logg - improved logs
    logt - log just tagged commits
    ignored - lists ignored files


Am I the only guy who would rather focus on his code?

These days I stash my source in zip files.


Here is a more useful tip:

http://pastebin.com/RP9ZdZY5


That's nothing but aliases.


A tip for intermediate and professional users to avoid headaches: http://subversion.apache.org/


I am in a cafe and was sipping my coffee when I read your comment. Now people are looking at me laugh my ass off, with half the coffee spilled on the keyboard.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: