I don’t recommend git pull to anyone. The magical ways that .git/config sets up tracked vs untracked branches are too opaque for me.
It’s always been much easier to understand (and explain) what’s going on when you separate fetch from rebase/merge*, and I feel like all these “just re clone and start again” memes are all because people’s branch tracking broke and they wanted magical “git push # no further args” to work properly again.
Once you know how to “git push remote myref:theirref” you become much less dependent on magic. Knowing about / having to know about how it works internally is the fun / tedium of git.
*Just kidding about doing git merge, btw. Linear history for life!
Fetch means “safely fetch new data from one of your remotes without affecting any of your local work”.
Pull means “do what fetch does, but with the spicy bonus risk that your precious work will be modified in an unexpected way depending on when and how you checked out the branch you’re on, what version of git you are using, and what config options you have set.”
Most confusion I've ever seen from beginners comes from them trying to pull, ending up in a conflict and not realizing, not resolving it but not aborting either and just continuing their work and then getting confused when trying to do anything else.
That's true. I think the worst thing about git CLI is it hides the state and forces you to issue another command to query the state, but you could easily forget. A lot of people add the thing to the PS1 to show some state, but it's not default.
However, I'm still not sure git will actually fuck things up with a pull. I think that's the users later when they go nuclear and delete the repo.
> Pull means “do what fetch does, but with the spicy bonus risk that your precious work will be modified in an unexpected way depending on when and how you checked out the branch you’re on, what version of git you are using, and what config options you have set.”
That's going to happen anyway when you need to rebase/merge. May as well type one command (pull), deal with the conflicts and continue, rather than type command, type another command, deal with the conflicts and continue.
Unless you have some other strategy that does not include rebasing or merging upstream changes, there's no advantage to not pulling. And, TBH, if you workflow is "this branch is worked on while specifically ignoring other changes by other people", then you have bigger problems than version control.
> Unless you have some other strategy that does not include rebasing or merging upstream changes, there's no advantage to not pulling.
Of course there is: after fetching you can see if there are differences between upstream and local, you can inspect those difference, and you can decide how to reconcile the two.
“Pull” is a big hammer which unconditionally performs an integration operation, and the default integration is one you almost never want too.
There‘a no advantage to pulling IME, in the best car scenario it’s just an alias for “git fetch && git merge”, if that’s what you want you can just do that and create your own alias.
> Of course there is: after fetching you can see if there are differences between upstream and local, you can inspect those difference, and you can decide how to reconcile the two.
[FWIW, it seems you know more about this than I do, so don't think that I am purposefully trying to be annoying. I'm not, I hope :-)]
I agree that you can see the differences, but I'm asking how helpful is this.
For me, anyway (not an advanced git user) seeing the differences between master and my feature branch before doing the rebase makes no difference - I'm still going to do the rebase no matter what I see in the feature branch.
It is going to be rare for me to be able to see, of the 10 merges to master, if an of them are going to break the code in a way that I cannot continue (in which case I won't rebase).
The longer I put off rebasing, the harder it is going to be to do it, so I am highly motivated to rebase on whatever master has, even if it just got broken, because it will be more painful to rebase later.
One big benefit to fetch+rebase over pull is that you can create a backup branch before you rebase so that if you mess up the rebase too much, you can undo easily.
Another situation I've run into is that sometimes I've made a small change that's stacked on top of a lot of other branches. And if those other branches get squashed and merged, regular rebasing can be really annoying - it is often easier to cherry-pick (I use rebase --onto, but same idea) your changes onto main/master instead.
> If you mess up a rebase you can always rebase -—abort (/ use the reflog) to restore the pre-rebase state.
That is true. But a few times, I've finished rebasing and regretted how I handled conflicts. And once the rebase is complete, you can't abort any more.
And I haven't put in the time to learn how to use reflog. Maybe this is my sign to do so.
As in `git fetch ...; git reset --hard ...;`? I guess that is what people are trying to achieve a lot of the time... For some reason people are more scared of `reset` than `pull`, though.
>Fetch updates your local repository (which is behind the scenes, separate from your literal local files).
Therein lies the chief problem with git: it's a leaky abstraction. Nobody actually should give a flying shit about commit hashes and ^HEAD or whatever it's called.
All the newbie tutorials you find waste so much time on that, but what people really care about when they start using git is "what the fuck happened to my files and how do I get them back the way they were".
Git docs and tutorials are breathtakingly bad at showing this.
git pull with fast-forward (--ff-only) is the only sane way to use git pull (if one must use git pull).
The most powerful one most people don’t use is reset. Soft and hard resets are my bread and butter. I don’t even bother with interactive rebases for squashing. I do a soft reset against origin/<branch> and create a new commit.
Yes I agree. Have you ever seen the "command line instructions" GitHub prints at the bottom of pull requests to checkout the PR code?! I don't think you'd approve of them. I'm pretty expert at git having used it every day for the last 15 years or whatever and I have no idea how to do anything after following GitHub's instructions!
To do it sanely you need to add the contributors remote, and fetch, and checkout, as usual. Would be happy to be educated here if I'm missing something.
Honestly the picture shown in that thread are fine and most people I have met grok those commands really quick.
The issue is git's interface is terrible and very powerful. Which means when something goes awry and they land outside those 5 or 6 commands they often have no idea how to fix it. Which invariably leads to a copy paste of their changes and a delete and re-clone.
Honestly I really like mercurial. I found its interface better but in this day and age all the tooling is built around git so ...
> ..when something goes awry and they land outside those 5 or 6 commands..
Yes, this. I have no problem adding, rm-ing, branching, making and accepting PRs, etc. These are what the overwhelming majority of git for dummies tutorials cover. (I've even paid for a very well-known and well-reviewed course and completed it.) And, these photos upthread are fantastic for that initial git-101 progression.
Then, I eventually landed my first tech-sector job and still haven't picked up much more since. My solution to every ounce of apprehension is deleting and re-cloning out of paralysis and fear.
I find great difficulty in being able to glean a repository's "environment" in a sense analogous to gleaning the environment of an initially compromised machine (the foothold) when you've popped a fresh shell on a boot2root box. (I thank the digital gods for IppSec and his hands-on videos that teach you how to clear up the fog of war around you!)
> My solution to every ounce of apprehension is deleting and re-cloning out of paralysis and fear.
Having worked with older version control systems, I found that to be one of the best things about git. If I had a problem with a version control system like AccuRev, that sort of simple fix was not possible. Your every action resulted in a change of the server state, so if you got your workspace into a confusing state, the confusion would be synced to every machine.
These days I understand git well enough that I can fix just about any mistake, but the 'delete and start over' workflow was extremely valuable to me as a beginner. Knowing that there was a foolproof fallback of just deleting and recloning let me experiment without fear.
The other day Jujutsu featured on HN, with git as a possible back-end. Describing itself as "both simple and powerful" with a combination of practices adopted from multiple tools:
> Jujutsu is a Git-compatible DVCS. It combines features from Git (data model, speed), Mercurial (anonymous branching, simple CLI free from "the index", revsets, powerful history-rewriting), and Pijul/Darcs (first-class conflicts), with features not found in most of them (working-copy-as-a-commit, undo functionality, automatic rebase, safe replication via rsync, Dropbox, or distributed file system).
> The issue is git's interface is terrible and very powerful.
Git is basically that a programming language. The time you need to "master" git is comparable to "master" a programming language.
I'm being writing code for more than half of my lifetime so far, and every time I need to use an unusual git command I feel like a script kiddo who copies and pastes from SO.
Though, if you know enough to edit diffs by hand, you could use git apply --cached to stage parts of the diff in a way to make a sensible set of commits instead of a single commit for a large change.
As someone who's having a very difficult time coming to grips with git, would really appreciate another source for this. It does not load for me, in the eight ways I have tried to load it (two devices each on a different IP, on two browsers, with that %2F left encoded and attempted with it unencoded.)
I'm probably showing my ignorance of what is possible/required, but I'd like to see a GUI front-end for Git that looked like the background of this image, where each commit was a lozenge that I could just drag from one column to the other. Maybe individual files could be circles inside the lozenges.
Just drag-and-drop, and the front-end figures out all the underlying Git commands to use.
https://nitter.net/pic/orig/media%2FFjJ62xKXkAYfFjt.jpg