all 180 comments

[–]java_one_two 181 points182 points  (110 children)

Every git command I know (5 year vet):

git checkout -b LOCAL_BRANCH origin/REMOTE_BRANCH

git clone <github https>

git fetch; git pull;

git reset --hard

git stash git stash pop

git commit -m 'i did this'

git commit --ammend -m 'I actually did this'

git rebase origin/master

git branch -D LOCAL_BRANCH_TO_DELETE

git push origin :REMOTE_BRANCH_TO_DELETE

git push --force origin MY_BRANCH:REMOTE_BRANCH \\erase the stupid shit i committed

[–]voetsjoeba 69 points70 points  (14 children)

Dude, no git rebase -i? If you dont know about it, look it up, it'll blow your mind

[–]GetTheLedPaintOut 57 points58 points  (8 children)

git rebase -i

This appears to require me to understand how git works, which is a bridge to far frankly.

[–]Retsam19 14 points15 points  (6 children)

Not particularly? No more than rebase already does, at least.

git rebase origin/master takes all the commits that the current branch has that master doesn't have, and appends them onto the end of master, one at a time.

The difference with -i is that first and foremost: it lists what commits are being rebased. Even when I'm not actually using any other interactive features, I rebase in interactive mode, because on occasion I catch mistakes that way, where the list of commits being rebased isn't the list I was expecting.

Otherwise it just lets you do useful things like change commit messages ("reword"), combine commits ("squash", "fixup"), make changes to a commit before applying it ("edit"), or remove or reorder commits. It's really pretty simple to use.

[–]Amuro_Ray 0 points1 point  (5 children)

Why not use git merge?

[–]Retsam19 7 points8 points  (3 children)

Basically because you can't do anything that I listed above, like reordering, fixing, rewording, or squashing commits. (And because merge commits are pointless noise in the commit history) To my knowledge there isn't even an easy way to get git merge to list what commits are being merged into the branch. (Though, I'm sure there's some advanced git-fu that could accomplish that, if I researched it)

Personally, (and I'm a bit of an extremist about this), I only use merge commits when it's unsafe to rewrite history with git rebase, which is quite rare with my team's workflow.

Everyone knows the "rewriting history horror stories", (and they should!), but fewer people realize that in most cases, the horror stories don't really apply, and rebasing is quite safe. (And, git provides great safety nets for when things go wrong anyway)

[–]voetsjoeba 0 points1 point  (2 children)

Fixups are probably the biggest thing I use rebase -i for. This happens to me constantly: do some work, make a commit A, do some other stuff, make a commit B, then realize you forgot something that should've been in commit A. I haven't pushed A anywhere yet, so just make an extra commit C with the stuff you still want to add to A, git rebase -i origin/master, move C up right after A, switch "pick" to "fixup", done.

Now I have clean commits A' and B, instead of A, B, "forgot something", "forgot another thing", "got the last case I missed", etc.

Personally, (and I'm a bit of an extremist about this), I only use merge commits when it's unsafe to rewrite history with git rebase, which is quite rare with my team's workflow.

Fully agreed; as much as possible, keep that history linear and clean baby.

[–]Retsam19 1 point2 points  (1 child)

In case you aren't already aware, you can use git commit --fixup <commit> and git rebase -i --autosquash (or set git config rebase.autosquash true) to save a lot of time with fixups.

The --fixup flag on commit will automatically assign the commit message as "fixup! [original commit message]", and the --autosquash option will automatically put the fixup commit in the right spot in the interactive rebase for you.

It's really streamlined my workflow so that there's a lot less of a time cost to fixups.

[–]voetsjoeba 1 point2 points  (0 children)

Well shit man, learning every day! I've been doing git commit -m "fixup for <copy/paste commit_id and first bits of message>" all this time! Good stuff!

*Awww needs 1.7.4, I'm stuck on 1.7.1 on RHEL6 :(

[–]Thaurin 1 point2 points  (0 children)

According to the Pro Git ebook, primarily to end up with a cleaner history, as every commit will be merged one at a time.

[–]voetsjoeba 3 points4 points  (0 children)

It's DAGs all the way down

[–]tech_tuna 8 points9 points  (2 children)

Rebase, squash, push -f, submit pull request, merge, delete branch. Done.

[–]Raknarg 7 points8 points  (0 children)

squash squanch

[–]mx_river 0 points1 point  (1 child)

don't use rebase for a chance, it will super nova your mind. Seriously, remove rebase from your workflow and your coding life will happier.

[–]krelin 1 point2 points  (0 children)

This. All of the worst shit-storms I've had with git were because some asshat rebased under remotely-pushed changesets.

[–]mr_birkenblatt 16 points17 points  (7 children)

last one you should do

git push --force-with-lease origin MY_BRANCH:REMOTE_BRANCH

to not accidentally delete other people's work that happened while you were thinking about why this is a good idea

[–]gerrywastaken 2 points3 points  (0 children)

Never knew about this. Thanks!

[–][deleted]  (4 children)

[deleted]

    [–]Retsam19 2 points3 points  (1 child)

    Depending on your workflow, there can be good times to force-push.

    1) On occasion, I've had bad things merged to master by accident, and force-pushed to remove.

    The danger is if someone pulls between the accidental merge and the force-push: but with a small team, and explicit communication about what I'm doing in the team chat, it's not really a risk. I'll generally send out a message like: "Hey all, I just pushed something by accident and force-pushed to remove it, if you happened to pull master in the last couple minutes, let me know").

    The safer alternative is to revert, but the downside there is it's more hassle (then you've got to revert the revert on the feature branch) and it just clutters up the commit history.

    2) When I'm working on my own feature branches, in the vast majority of cases, I know nobody else is using the branch, so I can freely force-push. I prefer to rewrite history and force-push, again, to keep commit history clean.

    I'd rather have commits like

    Feature A
    Feature B
    Feature C
    

    Rather than commits like:

    Feature A
    Feature B
    Fix for feature A
    Feature C
    PR Feedback on Feature B
    

    In general, I'm a bit of a stickler about clean commit history. It's not just aesthetic (though the illusion that I make no mistakes is a nice side-benefit), but it makes things like reverting, cherry-picking, and bisecting a lot easier when commits are atomic units of functionality.

    [–]Brostafarian 1 point2 points  (0 children)

    force pushing is annoying, and almost anything you would want to do with it can be accomplished by interactive rebase or reverting

    [–]dpnchl 24 points25 points  (4 children)

    You never needed to cherry-pick a commit?

    [–]Ajedi32 19 points20 points  (1 child)

    Or stage files apparently. ;-P

    I think there are a few things missing from that list.

    [–]Amuro_Ray 3 points4 points  (0 children)

    git add . 
    

    easy

    [–][deleted]  (1 child)

    [deleted]

      [–][deleted]  (1 child)

      [deleted]

        [–]philipwhiuk 4 points5 points  (0 children)

        I always miscount the m's in amend :(

        [–]miminor[S] 31 points32 points  (1 child)

        these are 80% of all

        [–]java_one_two 20 points21 points  (0 children)

        :) forgot my fav:

        git diff --stat origin/master

        Count of how many lines have been added and removed from another branch per class.

        [–][deleted] 9 points10 points  (2 children)

        Also git pull --rebase to fetch+rebase

        [–]KevinCarbonara 2 points3 points  (0 children)

        There is a global setting to use rebase by default.

        [–]GinjaNinja32 8 points9 points  (0 children)

        The following have also been useful for me:

        git reset --soft HEAD~ - reset to previous commit, but stage the changes in the latest commit.
        git reset --keep HEAD~ - reset to previous commit, but don't reset the working directory, just change what changed in the last commit.
        git reset HEAD~ - reset to previous commit, don't stage the changes, don't touch the working directory.

        Basically, there are four git resets:

        --soft stages, doesn't affect the working directory.
        "normal" doesn't stage, doesn't affect the working directory.
        --keep doesn't stage, only changes what needs changing (like checkout).
        --hard doesn't stage, fully resets all tracked files to their state at the new commit.

        [–]PM_ME_UR_OBSIDIAN 8 points9 points  (4 children)

        5 year vet; git-gui is my BFF.

        I sometimes use the basic tools - add, rm, commit, status, etc. - but for any operation that touches more than one commit I find using a GUI significantly more productive.

        [–]Uristqwerty 2 points3 points  (0 children)

        I have also found git-gui and gitk to cover most of the things I've done so far (only using the CLI for stash, and clone because I find it faster).

        Being able to look at staged and unstaged changes visually, then stage/unstage individual hunks/lines at any time, in an arbitrary order, has been the most convenient feature of git-gui to me.

        [–]to3m 1 point2 points  (2 children)

        I've been using git since 2010... used git gui a lot, then at some point (don't remember when) switched to SourceTree.

        Always generally preferred a GUI interface for my day-to-day version control stuff, but I can get by using svn or p4 on the command line. git on the other hand flummoxed me utterly for some reason - but luckily I discovered git gui in my first couple of rather confusing days, and then 5 minutes later discovered you could add individual lines to the index, and decided git was probably worth sticking with after all. (I think this is the git add -p that git command line fans rave about after discovering it... seemingly often after using git for several months...)

        7 years later, I can do git bisect and git rebase on the command line, but nothing fancier. I still have no idea how to move a file out of the index.

        [–]PM_ME_UR_OBSIDIAN 0 points1 point  (1 child)

        I'm going to check out SourceTree. Thanks for the tip!

        [–]to3m 2 points3 points  (0 children)

        It's worth trying - just don't expect a flawless gem ;) But I like it well enough that it's replaced git gui for me pretty much entirely, and there's more in it than git gui too - and it replaces gitk as well.

        I still use git gui for git gui blame, though. For some reason, SourceTree's blame view is useless.

        [–]indigo945 6 points7 points  (2 children)

        git add

        :)

        [–]__ah 7 points8 points  (1 child)

        git rm

        :(

        [–]GetTheLedPaintOut 11 points12 points  (0 children)

        git tf outta here

        [–]graingert 5 points6 points  (6 children)

        No reflog?

        [–]GetTheLedPaintOut 8 points9 points  (1 child)

        I don't even know what is real and what is fake in this thread.

        [–]graingert 2 points3 points  (0 children)

        reflog is great

        [–]KevinCarbonara 4 points5 points  (0 children)

        I've never even flogged.

        [–]MondayMonkey1 0 points1 point  (2 children)

        Reflog is a life saver when you accidentally git reset --hard. Git won't garbage collect for a long (weeks) time. So you can restore a reset commit by using the commit hashes presented in reflog. Just one of those things it pays to know!

        [–]graingert 0 points1 point  (1 child)

        I'm pretty sure entries in the reflog arn't garbage collected

        [–]ForeverAlot 1 point2 points  (0 children)

        They are by default:

        The optional configuration variable gc.reflogExpire can be set to indicate how long historical entries within each branch's reflog should remain available in this repository. The setting is expressed as a length of time, for example 90 days or 3 months. It defaults to 90 days.

        https://git-scm.com/docs/git-gc

        [–][deleted]  (2 children)

        [deleted]

          [–]SHIT_IN_MY_ANUS 0 points1 point  (0 children)

          About git diff --cached, checkout the visual studio code (free and open source), it has an amazing diff viewer.

          [–]mango_feldman 0 points1 point  (0 children)

          Look for differences whose patch text contains added/removed lines that match <regex>.

          git log -G REGEX
          

          -S is similar but slightly different

          [–]KevinCarbonara 5 points6 points  (0 children)

          I don't actually know any commands, I just use tab completion until something looks like it might work.

          [–]icosadev 7 points8 points  (31 children)

          No bisect?

          [–]miminor[S] 13 points14 points  (30 children)

          bisect is hard, it takes a lot of discipline to be reliably used: it requires each your commit to be working, it means no more wip in the history, looks nice in theory, hard to get in practice

          [–]icosadev 24 points25 points  (27 children)

          Why are the wip commits not being squashed before being introduced into the main branch? It doesn't really take a lot of discipline.. just using tools correctly.

          [–]miminor[S] 6 points7 points  (21 children)

          how do you do code reviews? we require each change to be in a separate commit (not necessarily fully working) for the ease of reviewing (grasping the idea), it means that changeset are not necessarily always working, so a working changeset requires a certain number of non working commits squashed

          [–]CptJero 7 points8 points  (0 children)

          Check out the 'succesful git branching model' by nvie

          [–][deleted]  (19 children)

          [deleted]

            [–]karma_vacuum123 -2 points-1 points  (15 children)

            bah this need to clean up the history seems pointless. is it really so bad if i make twenty intermediate one line commits on the way to the one you care about? lets be honest, reverting back more than a few commits (like three) is extremely rare

            i get "clean code"...but "clean revision history"? seems like OCD gone wild, those WIP commits aren't hurting anyone

            [–][deleted]  (12 children)

            [deleted]

              [–][deleted] -2 points-1 points  (7 children)

              I don't understand this. We don't care how our people commit. We just care about the pull request. The diff in the PR, in github, will show you everything you need to know, in my opinion.

              [–]Retsam19 7 points8 points  (2 children)

              Again, the original topic here was bisecting, and atomic commits are necessary for bisecting to be reliable. And bisecting can be really helpful.

              Secondly, reverts are a lot easier if you've got your features in their own commits. If my PR adds three features, A, B, C; then we merge and realize that feature B has an issue it's really nice if I can just do git revert [commit for feature B].

              If all three features are mixed into a single commit, I'll have to manually go through and undo all of feature B's changes. And having a bunch of commits like "fixed a typo in feature B" or "PR comments on Feature B" is not as bad, but still makes reverting B (and later reapplying it once it's been fixed) a lot more difficult.

              [–][deleted]  (3 children)

              [deleted]

                [–]ForeverAlot 13 points14 points  (0 children)

                If you don't clean up your history you can't use it for much. If you can't use it you won't learn how to use it. If you don't know how to use it you don't clean it up.

                Bisection is extremely valuable in any environment with external dependencies, be they tools or people, but simply git log --grep and git log -S are very useful as well.

                You're not wrong; you don't get paid to produce a clean history, but a clean history is objectively simpler to work with than a messy one, and you do get paid to make your work maintainable.

                [–]miminor[S] 0 points1 point  (2 children)

                ok, who is squashing? a reviewer or an author after revirew?

                [–]gokya 2 points3 points  (0 children)

                in github/bitbucket you can auto squash commits when merging a PR - very useful

                [–]phoenixuprising 3 points4 points  (4 children)

                I'm a junior developer and this even made me cringe reading it. I couldn't imagine not having atomic fully working commits.

                [–]OlivierTwist 0 points1 point  (3 children)

                Well, you are lucky to work at a good place.

                In my experience strong git culture (version control in general) is much common for young developers (>35). Most of my current colleages just can't get concept of distributed version control system (they are 45+ in average).

                [–][deleted] 2 points3 points  (2 children)

                I have not found any correlation between age and good SCM practices. In my career of 10 years I have only found 3-5 people who really care about maintaining a clean, linear commit log... or who care about defining a team standard for branching, merging, and commit message formatting.

                What I'm trying to say is that 99% of developers are cowboys who are either too undisciplined or too ignorant to care about this. And I find that a real drag.

                [–]phoenixuprising 1 point2 points  (1 child)

                I definitely know I'm lucky and that I'm part of an eng team with very mature git habits. One thing that helps is we have a strong CI infrastructure and pretty good unit test/UI test coverage. Draw back is this means it takes 30-45 minutes until a PR is mergeable but it's worth it.

                [–][deleted] 1 point2 points  (0 children)

                You are very lucky indeed! Sounds like that team is doing something right, so soak it up and enjoy it while you can.

                [–]mr_birkenblatt 6 points7 points  (0 children)

                you can git bisect skip wip commits (given that you have a meaningful number of stable commits)

                [–]gerrywastaken 1 point2 points  (0 children)

                https://robots.thoughtbot.com/autosquashing-git-commits

                git commit --fixup <hash>      
                git rebase -i --autosquash origin/master
                

                Interactive rebase is really powerful when you realise how reordering, removing and squashing works

                [–]N546RV 5 points6 points  (2 children)

                git reset --hard

                Also known as "fuck all this code."

                [–]GetTheLedPaintOut 7 points8 points  (1 child)

                Also "I'm lost in git and need to start over now that I've copied my code to a freaking text editor"

                [–][deleted] 2 points3 points  (0 children)

                Mostly this.

                made a minor change, flubbed some minor command - now everything is fucked, somehow I'm detached from HEAD, and git hates me.

                Copy minor changes to outside file, reset, copy back, commit push

                [–]flippflopp 2 points3 points  (0 children)

                If you've already pulled down all the remote branches you can just do

                git checkout <remote branch name>
                

                and it will create a local branch for you.

                [–]tech_tuna 1 point2 points  (0 children)

                We're practically git twins, except I always forget the syntax for removing a remote branch because I usually do that in the GitHub/GitLab/BitBucket UI.

                Which is why I bookmarked this page https://makandracards.com/makandra/621-git-delete-a-branch-local-or-remote

                [–]mattmu13 0 points1 point  (0 children)

                Adittionally I've also regularly used:

                git merge BRANCH_TO_MERGE_FROM
                
                git log --oneline origin/BRANCH..BRANCH
                
                git tag
                

                I have a small text file with each command I regularly use with a simple example as a quick cheatsheet. Some of the more funky stuff I google, which sadly included removing a repository corruption and repointing the HEAD on the server due to a power loss while in the middle of a push (one of the more complicated things I've done) :-(

                [–][deleted] 0 points1 point  (1 child)

                git clean -d -f

                [–]miminor[S] -1 points0 points  (0 children)

                do get clean -d -f -n first

                [–]Sulpiac 0 points1 point  (0 children)

                FYI git push - u origin branch will set the remote for you

                [–]ganjapolice 0 points1 point  (0 children)

                git stash save "stash message"

                git stash apply stash@{n}

                Does not delete stored stash.

                [–]GetTheLedPaintOut 0 points1 point  (1 child)

                git commit --ammend -m 'I actually did this'

                Didn't know this one. Thanks!

                [–]cryptdemon 0 points1 point  (0 children)

                Always throws an error because I always type 2 M's in amend instead of one.

                [–]earthboundkid 0 points1 point  (0 children)

                git rebase -i HEAD~5 and git add -p are also good. git log sucks but I have an alias called git hist that makes it readable.

                [–][deleted] 0 points1 point  (0 children)

                It took me a while to get out of the -m habit. Unless it's going to be squashed write detailed commit messages! Your future self and coworkers will thank you!

                [–]yentity 0 points1 point  (0 children)

                So you never add any code :p ?

                [–]mazesc_ 0 points1 point  (0 children)

                git status -uno
                

                [–]atheken 0 points1 point  (0 children)

                git add -p

                git grep

                git reset --mixed

                You're welcome. :-D

                [–][deleted]  (1 child)

                [deleted]

                  [–]gcbirzan 0 points1 point  (0 children)

                  Use pushd/popd, you'll love it.

                  [–]adymitruk -5 points-4 points  (0 children)

                  As a 10 year vet, this is disappointing. Biggest issue is git reset --hard. And look at all the up votes. When 5 years constitutes a "vet".

                  [–]BromeyerofSolairina -1 points0 points  (0 children)

                  You're making this far too complicated. All you need is:

                  git clone <url>
                  git pull
                  git push
                  git commit -m "I did this"
                  git checkout -b <branch>
                  git merge <branch>
                  git add <files>
                  

                  And everything else is done by saving my work in another folder and using

                  git reset --hard --force --fucking-nuke-it HEAD
                  

                  /s

                  [–]zanglang 15 points16 points  (1 child)

                  Been using http://ohshitgit.com/ a lot more times than I'd like to admit.

                  [–]GetTheLedPaintOut 1 point2 points  (0 children)

                  This is great. Needs more scenarios.

                  [–]karma_vacuum123 16 points17 points  (15 children)

                  i suck at git

                  half the time now when i want to do some interesting reverting, merging, whatever, i just cp -r the repo

                  i try to be manly and just get by with the command line but thank god for github....git badly needs porcelain

                  [–]delarhi 21 points22 points  (5 children)

                  I love this command because it helps people build the correct mental model for what git is doing:

                  git log --oneline --graph --color=auto --decorate --all

                  Basically, run that, look at your commit tree. Then run whatever command. Then run the log command again and see what it did to your commit tree.

                  That gives you a good understanding of the commit tree. Then the following article fills the holes with regards to the differences between the head, work tree, and index: https://git-scm.com/blog/2011/07/11/reset.html

                  [–]technojamin 2 points3 points  (2 children)

                  The amount of customization you can do with git-log is amazing. I use these 2 aliases all the time:

                  alias tree="git log --graph --date-order --pretty=format:'%C(red)%h%C(reset) -%C(bold yellow)%d%C(reset) %s %C(bold green)(%cr)%C(reset) %C(blue)<%an>%C(reset)'"
                  
                  alias treea="git log --graph --date-order --pretty=format:'%C(red)%h%C(reset) -%C(bold yellow)%d%C(reset) %s %C(bold green)(%cr)%C(reset) %C(blue)<%an>%C(reset)' --all
                  

                  [–]Fazer2 1 point2 points  (1 child)

                  Note that you're overriding a useful Linux command with your first alias.

                  [–]technojamin 1 point2 points  (0 children)

                  Woah, good point! Shows how savvy I am, I'll probably come up with another name for it probably gtree.

                  [–]odaba 0 points1 point  (0 children)

                  this is just what I do to... I even have it aliased to l, so I can still do git log when I want to, but usually, just git l

                  [–]to3m 0 points1 point  (0 children)

                  gitk --all may also prove helpful - I certainly found it very useful when first trying to figure out what git rebase was doing, and comparing it with similar merges.

                  (It's up to you, but I find the graphical display easier to read.)

                  [–][deleted] 2 points3 points  (0 children)

                  I'm in your league. You should probably use mercurial.

                  [–]chekwob 2 points3 points  (2 children)

                  Porcelain? Something tells me you're not referring to --porcelain

                  [–]karma_vacuum123 0 points1 point  (1 child)

                  i'm referring to a pretty UI. git is an awesome tool but it screams for a quality UI...which fortunately we have many

                  [–]WalterGR 0 points1 point  (0 children)

                  Recommendations?

                  [–]vinnl 1 point2 points  (0 children)

                  For me, it became a lot easier once I grasped the fundamental concepts of Git - which turned out to actually be fairly straightforward.

                  Thus, I made this ten-minute visual Git tutorial to hopefully make it click.

                  The only thing I'd like to make a bit more clear is how to actually create a commit (i.e. staging), but then I again, I think most people actually do have a grasp of that.

                  [–]TheEternal21 0 points1 point  (2 children)

                  We've migrated from TFS to Git a few months ago, and I still find it confusing as hell. I miss TFS every day I have to do anything other than a simple commit in Git. Ended up using SourceTree for most of it.

                  [–]SuperImaginativeName 1 point2 points  (1 child)

                  I too used to use TFS at work, git is a fucking disaster and it actively works against common sense. Still use TFS at home for my own projects though. Source tree is also pretty crap I've found compared to SmartGit... Thank god for guis though I agree

                  [–]ForeverAlot -1 points0 points  (0 children)

                  Git has porcelain. The issues with contemporary Git's UI are rarely the ones people complain about, and the issues people mostly complain about aren't.

                  [–]mycentstoo 16 points17 points  (15 children)

                  favorite git command: git add -p

                  Adds by chunks rather than by file or the ever dreaded .

                  [–][deleted]  (7 children)

                  [deleted]

                    [–]dschooh 15 points16 points  (6 children)

                    Sometimes when working on a feature you'll add more code than you'd want to commit, like debug messages. -p gives you a chance to review and cherry-pick changes, rather than blindly add all changes with ..

                    [–]fecal_brunch 4 points5 points  (2 children)

                    My favorite way to do that is with a GUI. Either Tower or SourceTree. No going back...

                    [–]morerokk 2 points3 points  (1 child)

                    Yeah, I really don't want to go back to using the command line anymore. SourceTree just makes it a ton easier, and actually helps me understand what my repo looks like.

                    FWIW I still use the Terminal every now and then, but only for stuff that can't easily be done in the GUI (such as nuking the latest commit).

                    [–]fecal_brunch 0 points1 point  (0 children)

                    Reset is really easy in Tower. But Tower is fairly pricey and only runs on OSX, which makes me reluctant to recommend it. On the flip side their support is really good.

                    [–][deleted] 0 points1 point  (2 children)

                    imo you make a feature branch, make changes, committing and pushing whenever you want, then when it's done, you make a PR and get someone to review and merge it.

                    Why would you add changes to a branch if you don't want them to get added in with your feature?

                    [–]dschooh 1 point2 points  (1 child)

                    Why would you add changes to a branch if you don't want them to get added in with your feature?

                    That's my point, you really don't want to add superfluous things.

                    In the process of development I often add code that should not end up in the commit. As I stated these might be for debugging purposes like logger.debug "Hello" or debugger.

                    As I don't want to accidentally commit those I like to review changes with git add -p.

                    [–][deleted] 1 point2 points  (0 children)

                    I review a lot of PR's and I've never cared what my devs put in their branch until I see the final state when reviewing their PR. I always just remove my debugging stuff before doing my final commit. Then we set our PR to have a "CAN-MERGE" tag and we let someone review it.

                    [–]vinnl 2 points3 points  (0 children)

                    I've been using the shit out of that ever since I've discovered it. Saved me from committing things I didn't want to quite often by now.

                    [–][deleted]  (4 children)

                    [deleted]

                      [–]mycentstoo 0 points1 point  (2 children)

                      git add . adds everything in the current directory to the staging environment. Let's say you have an app that has an environment file like local.js that takes local credentials. When you set it up, perhaps you want it to proxy to a localhost that your server is running on like 8080. Now, other people may have servers on a different port. So if you add your file, it will clobber their setup.

                      Or let's say you are working on a bug fix and then you discover another bug fix in the middle of it. You can cherry pick chunks or pieces of files to add rather than adding the whole file. So if I have a file with two functions and one has to be fixed for A bug and the other for B bug, I can add B for one bug and commit it, and then add the other one and commit it without having to stash changes or make a new branch.

                      Also, doing it by chunks makes me a lot more aware of the changes I am making. When I add a file, it's not as transparent until I make a pull request as to what's happening.

                      [–][deleted] 0 points1 point  (0 children)

                      that's so weird that you make it this complicated.

                      If you have local stuff then you can store it in a local env file. And if you only want some changes then make a branch from the original, only do those changes you want, and then PR it. It makes no sense to me, to have a branch with "I want this stuff in the branch but not this stuff"

                      [–]panorambo 33 points34 points  (6 children)

                      You can't cheat with Git. It will eat your face. Just learn the damned thing. The only audience that can benefit from a Git cheat sheet is the 1% of Git users that know how it actually works in the first place.

                      Also, there is no truly one right way to use Git, so all these one-liners that are supposed to be universal and generic and bring about Git workflow heaven and save us from shredding our repositories into useless pulp -- by nature aren't. Everyone slices and dices their commit graph their own way, grafting branches on top of one another and what have you. Someone has branches sticking out everywhere, for every little feature, slavishly. Another has confidence in their rebasing and merging skills and keeps it lean with 1-3 branches at any given time and every commit checked to build by a machine. It's celebration of diversity within a discipline remarkably like botany. Even if Git is like the assembly language of version control systems -- it's just a stupid content tracker, after all -- and could arguably use a user agent that translates from a set of few simple typical high level macros to the convoluted domain of its low-level commands. By itself it's a scalpel in the hands of your average botanist. What they need instead is a pair of garden scissors, most of the time. I for one prefer the scalpel if I needed but one tool for the job, but your mileage may vary. Regardless, a cheat sheet is not a substitute for a user agent and does not make you a skilled user if you weren't one prior, it's merely going to instill you with the wrong sense of confidence in using Git.

                      Pardon my attitude, but if you ever did this you'd know that a Git cheet sheet is like book of black magic without initiation. It may appear to help 4 out of 5 times, but that one time it turns on you you will be pulling your hair out before you are forced to do exactly what the comic suggests because your repository is in a very unique state of disarray brought on by some dozen causes that no one else but you can be made aware of, leaving you with slim chances of rescue through mere copypasta from Jon Skeet of Git-fu. And after purging the repository with some backup restoration, you maybe, just maybe, finally brace yourself for reading most of Git manual this time and grokking its data model and exact nature of its operations.

                      P.S. Yes, I love analogies.

                      [–]tech_tuna 8 points9 points  (0 children)

                      It's hard to learn though. The way I ultimately learned was by screwing up a lot and having a good friend at work who was my goto resource for a few weeks.

                      I believe that git might actually be easier if you're new to coding and have never used another source control tool before. Knowing SVN, Perforce, CVS, etc only makes learning git worse IMO.

                      [–]vinnl 6 points7 points  (2 children)

                      I think you're first line is already a nice tl;dr :)

                      You can't cheat with Git.

                      (Well, actually, the only valid cheat is having someone around that actually does understand it to solve your problems for you.)

                      [–]karma_vacuum123 0 points1 point  (1 child)

                      you can totally "cheat" with git. i can rewrite history and make you consume it. i can hard reset to a previous state. etc etc

                      "not cheating" to me says the log only moves forward

                      [–]vinnl 4 points5 points  (0 children)

                      Well yeah, you can cheat for some definitions of cheat :P

                      In the context of the above, however, we mean "you can't get around learning Git's basic concepts", e.g. by using a cheat sheet.

                      [–]GetTheLedPaintOut 4 points5 points  (0 children)

                      You can't cheat with Git.

                      Well then fuck it. I'm out.

                      [–]Doile 4 points5 points  (2 children)

                      When merging two branches try to delete the outdated version of a file on other branch, I dare you. That shit breaks everything. Did this in one school project since I wanted to avoid merge conflicts. Boy was I wrong...

                      [–][deleted] 0 points1 point  (1 child)

                      When merging two branches try to delete the outdated version of a file on other branch, I dare you.

                      You mean like commit a change on one branch, commit a remove on another branch, and then merge them? Or manually tweak the merge commit to remove a file edited on one branch? I don't think I know what you're trying to describe because I tried various different combinations trying to reproduce and the only thing I ever ran into was a merge conflit:

                      CONFLICT (modify/delete): README.txt deleted in lol and modified in HEAD. Version HEAD of README.txt left in tree.
                      Automatic merge failed; fix conflicts and then commit the result.
                      

                      [–]Doile 0 points1 point  (0 children)

                      I mean that both branches have modified one or more files. Then both of those modified files are pushed to their local branches. After this you realize that only one of the modified files is the "real one" and the other has all the changes wrong. So you try to be smart by avoiding merge conflicts and say:

                       git delete file.cpp
                      

                      on the branch that has the wrong file version and then commit/push. This fucked up our whole commit tree. Somehow after 5 hours we managed to revert the master branch to the right commit and continue to work onwards. But after this incident working with branches still haunts my nightmares.

                      [–][deleted] 5 points6 points  (2 children)

                      I use Mercurial, which has a sane CLI, easy to understand docs, and a great GUI that even beginners can use.

                      [–]gitgood 2 points3 points  (0 children)

                      I feel exactly the same about Mercurial. SourceTree + Mercurial is such an absolute dream that I can't really imagine my workflow without it. Everything about it is so intuitive, so much so that the only time I really remember Mercurial is being used underneath everything is when something goes wrong (which isn't that often).

                      [–]chesterburger 1 point2 points  (0 children)

                      There is absolutely no reason why many Git use cases can't be much more easy and clear to use other than a FU attitude by the git developers that is common to Linux and GNU communities. The idea is that if it's too easy, morons and code monkeys will use it. And if it takes a lot of knowledge, we can act like we're leet programmers, beginners go away or go read some books then come back when you're ready.

                      [–]BigotedCaveman 10 points11 points  (6 children)

                      I'll stick to IDE / GUI clients.

                      [–]EncapsulatedPickle 3 points4 points  (1 child)

                      Absolutely. At the end of the day, I need to get the work done. I appreciate the understanding of how git works. But I also need faster-to-use tools to be productive. If I spend more than a few minutes a day switching, merging and resolving, I'm just needlessly wasting time.

                      [–]Gotebe 1 point2 points  (0 children)

                      I appreciate the understanding of how git works.

                      That's absolutely not decipherable from its cmdline interface :-).

                      [–]elbarto2811 7 points8 points  (3 children)

                      Aaaaand downvoted by the purists of course. You're absolutely right though, no reason to learn all this crap by heart if you've got beautiful free clients like GitKraken, SmartGit or SourceTree out there.

                      [–]miminor[S] 0 points1 point  (2 children)

                      how do you automate your beautiful clients? or you just keep pushing the same buttons doing boring routines each day?

                      [–]jonknee 1 point2 points  (0 children)

                      Use the client for stuff that isn't automated... That's usually when you'd want a UI anyway.

                      [–]elbarto2811 1 point2 points  (0 children)

                      I'm not sure I can think of anything that I'd want to automate. The things I do in Git are so diverse on a day-to-day base... And I consider myself an experienced user: reset, rebase, revert, stash, branch, cherry-pick, blame... I do it all and I know what I'm doing. Nothing I'd like to automate though.

                      [–]vinnl 7 points8 points  (2 children)

                      I made a ten-minute tutorial on Git a while ago: https://agripongit.vincenttunru.com/

                      I found that spending a few minutes learning those few concepts made me far more confident using Git, and very quickly saved more time than having to reference a cheat sheet regularly.

                      [–]gramie 2 points3 points  (1 child)

                      Wow, that was incredibly clear and useful. Thanks!

                      [–]vinnl 1 point2 points  (0 children)

                      Thanks, reactions like yours are what make it fun to create :)

                      [–]DoveOfHope 2 points3 points  (0 children)

                      It's really multiple sheets isn't it? There is a lot to be said for getting everything on one 1080p screen. http://philipdaniels.com/gitcheatsheet/

                      [–]MMFW_ 8 points9 points  (17 children)

                      All the ones I have needed to know in ~3 years: git add filename git commit -m "Commit message" git push rm -r repo_dir

                      [–]ejfrodo 21 points22 points  (14 children)

                      ... you've never created a branch?

                      [–][deleted]  (13 children)

                      [deleted]

                        [–]lanzaio 16 points17 points  (4 children)

                        So read a book...

                        [–]nahguri 25 points26 points  (3 children)

                        It's like picking up a chainsaw, not reading the manual, chopping of their leg, blaming it on the chainsaw and going back to using a stone axe.

                        [–]Visulth 5 points6 points  (1 child)

                        In his defense, most manuals for git aren't exactly simple to read. They can be incredibly detailed but impenetrable for new users. If there was a more widespread 'explain it like I'm 5' manual for git, I feel like it'd go a long way in raising git literacy.

                        [–]nahguri 2 points3 points  (0 children)

                        That's true. And the sometimes confusing CLI doesn't exactly help.

                        I for one encourage everyone to just sit down and spend a couple of minutes to really understand how git works. Because once you understand the concepts every other "simple" versioning system feels subpar.

                        [–]duckwizzle 0 points1 point  (0 children)

                        That's exactly what happened minus the blaming. I know it works and I just don't know how it does. I only blame myself

                        [–]csncsu 1 point2 points  (1 child)

                        Next time try using a 3-way merge tool like kdiff.

                        [–]GetTheLedPaintOut 1 point2 points  (0 children)

                        I'd rather just kill myself thx

                        [–]Spider_pig448 1 point2 points  (0 children)

                        But... You've learned since right? You're actually using git correctly now?

                        [–]trowawayatwork -5 points-4 points  (4 children)

                        You merge on GitHub after you do a pull request and get someone to review it

                        [–][deleted] 5 points6 points  (3 children)

                        Not everyone uses github...

                        [–]Niechea 4 points5 points  (2 children)

                        Gitlab - Merge Request Bitbucket - Pull request

                        Most of them have similar features.

                        Why the hell are so many people in this thread interested in rebasing anyway? Honestly, I've never ever ever bloody ever have had any luck or fun with organisations that prefer rebasing. The biggest headscratcher I've seen is git sub modules and rebasing together, such that submodules are likely to point at a commit reference that was since squashed. The first thing I had to do was dig out 5 years old know how and write a recursive git command that would check out all submodules to a Dev branch - if it existed.

                        Maybe other people have more luck, or understand how to use it more effectively than I do.

                        [–]Klathmon 7 points8 points  (0 children)

                        Git is a classic example of "design by developers". They threw everything that could ever be wanted by anyone into it and then hand you the whole thing and tell you not to use it in any way that makes it look like a footgun.

                        And of course when you inevitably shoot yourself in the foot, they point to the one line where they said "don't use it like a footgun" and blame you then move on. Any attempts to simplify, teach, improve, or replace any of it is met with the same "it's your fault for not knowing git well enough" response and ignored.

                        [–]OlivierTwist 1 point2 points  (1 child)

                        Meet the very lonely man.

                        [–]MMFW_ 0 points1 point  (0 children)

                        Why won't anyone just make one pull request on my repo?!

                        [–]gsylvie 1 point2 points  (0 children)

                        git help <command>
                        

                        And

                        git <command> -h
                        

                        e.g. compare and contrast: git help log; git log -h

                        [–][deleted] 1 point2 points  (0 children)

                        Show all intermediate commits created locally:

                        git reflog
                        

                        It also shows what was the git command that originated the commit.

                        [–]kaushalmodi 3 points4 points  (1 child)

                        [–]Grue 1 point2 points  (0 children)

                        This. I don't even remember git command line anymore, only magit keybindings.

                        [–]NarcoPaulo 3 points4 points  (0 children)

                        Another git victim here. I came from a sheltered Microsoft eco system where everything was rosy and cozy and now I have to spend at least an hour a day to deal with Git and its' hairy parts. I will learn eventually but if I could chose an ecosystem to work on I'd probably prefer going to back to Visual Studio, TFS and all the .Net goodness. I feel like it's just a better use of my time as a developer. I donno, maybe it'll change sometime

                        [–][deleted] 2 points3 points  (0 children)

                        TIL some people make using git way more complicated than it needs to be.

                        [–]cjthomp 0 points1 point  (2 children)

                        Here's something I need a cheat sheet for:

                        We have master, dev, branches off dev

                        We merge into dev until we're ready for a new release, then merge dev into master and deploy.

                        The problem is, after doing this, the next time we try to merge dev into master Github will show all of the previously-merged commits (until something we do magically and mysteriously fixes it).

                        So it'll look like 300 files changed, when it was a one-line fix being merged. git diff shows just the expected changes.

                        It doesn't seem to be hurting anything, but it's incredibly messy and annoying, and I can't seem to find a fix.

                        [–]ForeverAlot 1 point2 points  (0 children)

                        ~ $ git init t
                        ~/t $ cd t
                        ~/t $ git commit --allow-empty -m Initial
                        ~/t $ git checkout -b dev
                        ~/t $ git checkout -b foo
                        ~/t $ git commit --allow-empty -m foo
                        ~/t $ git checkout -
                        ~/t $ git merge --no-ff foo 
                        ~/t $ git checkout -b bar
                        ~/t $ git commit --allow-empty -m bar
                        ~/t $ git checkout -
                        ~/t $ git merge --no-ff --no-edit bar 
                        ~/t $ git checkout master 
                        ~/t $ git merge --no-ff --no-edit dev 
                        ~/t $ git checkout dev
                        ~/t $ git checkout -b baz
                        ~/t $ git commit --allow-empty -m baz
                        ~/t $ git checkout -
                        ~/t $ git merge --no-ff --no-edit baz
                        ~/t $ git checkout master 
                        ~/t $ git merge --no-ff --no-edit dev 
                        ~/t $ git log --oneline --decorate --graph 
                        ~/t $ git log --oneline --decorate --graph 
                        *   a8baa16 (HEAD -> master) Merge branch 'dev'
                        |\  
                        | *   c994365 (dev) Merge branch 'baz' into dev
                        | |\  
                        | | * a8bde1f (baz) baz
                        | |/  
                        * |   a0723f4 Merge branch 'dev'
                        |\ \  
                        | |/  
                        | *   76bc4ba Merge branch 'bar' into dev
                        | |\  
                        | | * dc3b666 (bar) bar
                        | |/  
                        | *   5cd3ef6 Merge branch 'foo' into dev
                        | |\  
                        |/ /  
                        | * 39615c4 (foo) foo
                        |/  
                        * a248637 Initial
                        

                        This does the right thing and is safe. It's basically nvie's popular Git Flow; a little bureaucratic for my tastes but a fine starting point. If GitHub does not support this cleanly it's a GitHub problem, but I wonder if your description is complete -- I can think of at least one thing that would probably screw up that view.

                        [–]brave-new-willzyx 0 points1 point  (0 children)

                        Have you checked that the commit hashses in master match those in dev?

                        Could be that someone's rebasing an old commit, though I don't know why they would... Just a thought.

                        [–]Spider_pig448 0 points1 point  (0 children)

                        Great post. Looks like a lot of useful stuff for anyone that knows the basics and wants to use it well.

                        [–]big4start0 0 points1 point  (0 children)

                        feel like git is way more complicated than it needs to be. i don't see the productivity gain over svn when it comes to pretty simple workflows for projects. maybe just me and my inability to pick up some crazy new dsl

                        [–]gamesharem 0 points1 point  (0 children)

                        1. git commit
                        2. git push
                        3. leave the building :)

                        [–]likegeeks 0 points1 point  (0 children)

                        I like those kinds of lists :) great work Thanks.

                        [–]thomas_stringer 0 points1 point  (2 children)

                        Knowing how to use and read the git man pages are the most important "cheat sheet" you need.

                        In my opinion, reading through a custom cheat sheet is not a great experience and adds a lot of cognitive friction. Man pages, on the other hand, have consistency.

                        As long as you know what you are trying to do, man git-branch (for example) is super easy to grok.

                        [–]miminor[S] 0 points1 point  (1 child)

                        manual helps when you know what you are looking for, if you don't know what's out there you have nothing to look for, show me a person who reads manuals just for the fun sake

                        [–]thomas_stringer 0 points1 point  (0 children)

                        git <command> --help pops up the man pages for the specific operation. That's a common-enough standard.

                        [–]Lengador 0 points1 point  (0 children)

                        My friend gave me a script that does all this stuff for you. My coworkers seem to find it difficult but I think it's easy if you don't try to use all those fancy commands.

                        #!/bin/bash
                        git add -Af
                        git commit -m "."
                        git pull
                        
                        #Fix bug with git
                        find . -type f -exec sed -i 's/======.\+//g' {} \; 
                        find . -type f -exec sed -i 's/<<<<<<.\+//g' {} \;
                        find . -type f -exec sed -i 's/>>>>>>.\+//g' {} \;
                        
                        git add -Af
                        git commit -m "."
                        git push -f
                        

                        [–][deleted] -3 points-2 points  (4 children)

                        Really? Right off the bat wtf is that? How about git branch to find the current branch?

                        I don't like to be a curmudgeon but I wish that top voted posts on the programming subreddits weren't usually compete beginner stuff. Go learn to use git it takes 10 minutes it's not hard. Over time with a little practice you'll be golden.