1. 36
  1.  

  2. 14

    This is how I git, as a self-admitted near-idiot:

    • Never branch, always on m*ster.

    • Commit mainly from IntelliJ’s GUI.

    • Push either from IntelliJ or command line, can go either way.

    • On the server, git pull.

    • If there’s any trouble, mv project project.`date +%s` and re-clone.

    1. 8

      In my opinion people tend to pay too much attention to CLI commands and steps. As long as one understands what branches and commits are, it becomes immensly easier to handle git and potential problems.

      1. 1

        This is what I refer to as the “xkcd git workflow”: https://xkcd.com/1597/

        1. 1

          I feel like even people more used to git resort to the last bullet point every now and then, I know I have :P

          1. 3

            https://sethrobertson.github.io/GitFixUm/fixup.html is a fantastic resource for fixing mistakes, which helps demystify got. It’s a ‘choose your own adventure’ guide where you decide what state you want to end up at and a few other facts, and it tells you what to do.

            1. 1

              First step

              Strongly consider taking a backup of your current working directory and .git to avoid any possibility of losing data […]

              Hehe, off to a good start. This basically sums it up though, that copy of a directory is a safety net in case any other steps go wrong.

            2. 1

              I admit I used it a lot at my university, because they didn’t taught us how git works and I didn’t took to the time to learn it on my own.

              Now, when my local branch is mess, if I have no local changes to keep and I if know for sure that my branch is in a clean state on the remote repository, I just do:

              git reset --hard origin/my-branch

              With the years passing, it appears to me that you don’t end up with this “fak I have to reclone my repo” or “fak I don’t know how to fix this conflict” problems if you are meticulous with what you commit and where.

              It take a bit more time upfront to make commit that you are proud of, but in the end it makes it very easy to understand what you have done some days/weeks/month ago (and it will save your ass when you have to find when a regression/bug happened).

              TL;DR: git flow + self-explanatory commits = <3

              1. 1

                Oh man! I did this two weeks ago. I had folders numbered 1-n and in each one I had the same project cloned but in a messed up state. Granted that it was a new technology stack for me, nodejs to be precise.

            3. 4

              Never merge with GitHub!

              This!

              • Why doesn’t GitHub show commits in the right order?
              • Why doesn’t GitHub have a «Squash fixups» button?
              • Why doesn’t GitHub have a «Rebase» button? To your reviewers, rebasing on the target branch is semantically a completely different act than any other force push.

              Ultimately, I guess I wish GitHub was Gerrit, and Git was Pijul.

              1. 4

                i’m surprised nobody is talking about magit. it’s quite powerful and easy to use. hands down the best gui for git that i’ve seen and it’s pretty accessible to the vim crowd if you use something like spacemacs.

                1. 3

                  I’ve never understood the benefits of adding git aliases instead of (shorter) aliases for your shell. I’ve got plenty of bash aliases like ‘gc’ (git commit - v) instead.

                  Some non-obvious, git related aliases:

                  Show git log with stat and press n and p in less, to jump to next and previous commits:

                  alias gl="git -c core.pager='less -p^commit.*$' log -p -M -w --stat --pretty=fuller --show-notes"
                  

                  A colored alternative to git log --oneline that works well with merge commits, due to --graph:

                  alias glp='git log --pretty="format:%Cred%h %Cblue%d %Cgreen%s %Creset%an %ar" --graph'
                  
                  # create an easy target to compare/rollback to after difficult rebase/merge
                  # etc and the reflog contains too many similar entries
                  alias gp="git tag -d prebase; git tag prebase; git log -n1 prebase"
                  

                  Completion for my aliases (branch/ref names for gl as if I’d written git log):

                  . /usr/share/bash-completion/completions/git
                  __git_complete gco _git_checkout
                  __git_complete gl _git_log
                  

                  Switch between the current and previously checked out branch: git checkout -

                  I always include -M (try to detect moved files) and -w (skip whitespace changes) when using git diff.

                  Complete list of git aliases and functions: https://github.com/chelmertz/dotfiles/blob/e1442914e278db8d237ff06c9c5cf3c31f6bac56/.bashrc

                  1. 11

                    Using git builtin aliases also give you a namespace.

                    For example pressing g<tab> on my system shows 242 possibilities, using git aliases makes sure I don’t have any conflict with existing and upcoming commands on my system.

                    If you’re worried about keystrokes I’d rather have a shell alias to have git availabe as g, and then use git aliases on top, so g l, g lp etc.

                    That’s of course just a personal preference :)

                    1. 7

                      The benefits are for people who think in scopes, missing a better description, I guess. I’ve tried to use “pure shell” git aliases but I found myself not using them and at one point forgetting I had them. When I start typing git then what comes next is a git subcommand. Could be false attribution though, but it helps me memorize stuff.

                      Also lower chance of any conflicts and not spamming the global scope. So many people do “git st” for status, to a point where I wonder why it’s not a default.

                      1. 2

                        I’ve never understood the benefits of adding git aliases instead of (shorter) aliases for your shell.

                        Things like __git_complete gl _git_log is not needed as the git completion handles the aliases transparently.

                        1. 1

                          That’s a good point, but setting it up is a one time cost. Can you imagine how many keystrokes I’ve saved? :)

                          I guess not everyone focuses emacs with F1 and Firefox with F2 etc, either, without modifiers. This might be a thing in the same vein.

                          1. 2

                            If you change shells the modifications doesn’t carry over. Meanwhile my gitconfig is self-contained and doesn’t care. I’m more in the camp of using the built-in functionality unless there is a clear win with the shell aliasing. I don’t see it here. I can also depend on the git completion telling me if I forget an alias instead of grepping over alias to find it.

                            1. 1

                              I neither change shells or forget the aliases, or change from using git to hg (the latter could maybe be abstracted away with aliases/scripts if you’re changing tools often, as your comment implies :)). Thanks for the insights though, now I get why git aliases are being used!

                      2. 1

                        I’ve read many git workflows and one thing that confuses me about rebase-oriented workflows is the force-push aspect. Are you generally expected to be the only person/machine working on, or at least involved with, that particular branch? Do people not fetch proposed branches locally? Am I making too big of a deal out of inconveniencing other people when you force-push? :-)

                        1. 4

                          If the branches are namespaced to start author/ then the author gets to push --force-with-lease their branches as they see fit. Main branches (release, dev, whatever), those should strenuously try to avoid force pushes.

                          1. 2

                            Ooh, I didn’t know about –force-with-lease, I’ll have to read up on that, sounds very useful, thanks!

                          2. 4

                            If you’re following git flow or a similar strategy, you should be doing most of your work on a ‘feature branch’ which should generally only be worked on by one person at a time. Even if you aren’t using rebase, merges can result in annoying conflicts if multiple people are working on the same branch, so I personally recommend against it for most scenarios unless your entire team has a culture of ‘trunk-based’ development.

                            1. 2

                              I’m just curious if, in practice, people adhering to rebase-oriented flows tend to run into trouble with force-pushes, because as a squash/merge practitioner, it sounds like it would give me a headache.

                              1. 2

                                If you’re doing it correctly, not really. You should only force-push onto feature branches that you “own” or with explicit permission of who owns the branch. Assuming you rebase on master/develop/etc. before a ‘merge’ of a feature branch into a primary branch, it should be a pure fast-forward every time. As with most strategies, you should almost never force push to a master branch.

                                1. 2

                                  Generally the assumption is that every branch can be force pushed to at any time by its owner, except for master on the main project. However, no one rebases commits on that master branch (or on another designated branch).

                              2. 2

                                I have almost never worked on a branch that lived long enough that multiple people needed to push to it. A branch exists to work on a single self-contained thing and gets merged when it is done, in most flows I am used to.

                              3. 1

                                Everything I know about git I learned from https://ohshitgit.com/

                                For some reason I seldom have as bad problems with Mercurial, though branches do get hairy from time to time. I don’t know whether that’s because it’s Better or whether I just have fewer/smaller collaborative projects using it.