b0rk, (edited )
@b0rk@jvns.ca avatar

what's your favourite way to simplify your life with git? mostly interested in slightly unusual tricks to reduce the number of git features you're using, like:

  • never using the stash, just creating temporary branches instead
  • deleting your main branch so that you can never accidentally commit to it
glyph,
@glyph@mastodon.social avatar

@b0rk never use pull, only ever fetch and merge.

pull is an anti-feature, because it confuses separate actions with different emotional valences.

fetch: retrieve work from upstream, see what other folks have committed, prepare for being offline. Always safe, should do it constantly, doesn’t affect working copy state at all.

merge: reconcile work with others, update working state. Always requires pausing, everything being committed, careful attention to detail, preparation

jacob,
@jacob@jacobian.org avatar

@glyph @b0rk I try really really hard to avoid saying tools are "bad” so I'll just say that I find it incredibly hard to understand why a command that’s featured in literally every "intro to git" article is actually something dangerous

glyph,
@glyph@mastodon.social avatar

@jacob @b0rk a lot of git documentation is written from the perspective of an instructor trying to make git seem easy so that people can get right to their work and ignore the “annoying details” of version control. Slowing down and considering the multi-step process of change reconciliation, when it can usually be automatic and done without merge conflicts, particularly in a tutorial environment where the changes are controlled for simplicity, feels like a digression that gets in the way

b0rk,
@b0rk@jvns.ca avatar

@glyph @jacob people also have wildly different git workflows from each other -- git pull has ~never been an issue for me with my personal git workflows (either when collaborating or working on my own), and it’s always genuinely hard for me to remember why it's an issue for others (though glyph's examples are great, and reminded me of the some times when pull has been a problem for me)

i think the "wildly different workflows" thing makes teaching git challenging

glyph,
@glyph@mastodon.social avatar

@b0rk @jacob my own phrasing of this advice as “don’t use pull” is based on scenarios where folks using pull without understanding the nuance of its two-step nature. There are other valid workflows that save some typing and are equally safe which do use pull, but the non-negotiable part is that you do need to understand that nuance, viscerally, and to think about change reconciliation and change transmission as separate steps so you can understand what happens when a gap opens between them

b0rk,
@b0rk@jvns.ca avatar

@glyph i don’t really agree but i try to avoid getting into arguments on mastodon :)

really appreciate the examples!

glyph,
@glyph@mastodon.social avatar

@b0rk I respect your position here as an expert and as an educator and if you would like to share a countervailing view I would absolutely appreciate it. But I certainly understand not wanting to get into a back-and-forth, it might be more illuminating to read your final work here :-). But as a final thought here let me give you a more complete picture of what my individual workflow cycle looks like:

glyph,
@glyph@mastodon.social avatar

@b0rk I don’t actually use “merge” and “pull”, I use “git up” (aliased to “fetch —all”) and “git down” (aliased to “merge —ff-only”). In the happy path, I don’t really think about this. When “down” fails, I address the merge depending on the upstream project’s history rewriting policy. Either ‘merge’ (which is always configured as —no-ff and to prompt for a commit message when I am not using the “down” alias) or ‘rebase’. “Catching up” and “merging changes” are very different in my workflow.

b0rk,
@b0rk@jvns.ca avatar

@glyph yeah I understand that! I absolutely believe that "never use pull” is a workflow that make sense for you (and for many other people!) but (from this poll https://social.jvns.ca/@b0rk/112118493083676573 ) it looks like it's a minority stance

in general if 37% of people prefer "only pull” and 12% of people prefer "only fetch”, I'm more likely to believe that both groups of people have legitimate reasons for their preferences, even if the "only fetch" group are probably on average more knowledgeable about git

glyph,
@glyph@mastodon.social avatar

@b0rk I would love to see a deeper dive into why people have these preferences: like @hynek just articulated a countervailing expert view on the use of pull but my own experience of helping people with git suggests that most people using it just followed a tutorial. However my educational role wrt git has almost always been as a troubleshooter, not as a teacher, so I have a huge sample bias; when people are talking to me about pull, something has already gone wrong.

b0rk,
@b0rk@jvns.ca avatar

@glyph yeah my experience talking to people here on mastodon about git is that a lot of people have preferences that are different from mine, and that a lot of them have thought through their choices very carefully, even if it's a choice that I thought was "wrong”

i've learned to be extremely careful about making judgements

b0rk,
@b0rk@jvns.ca avatar

@glyph but a huge part of my teaching philosophy is to respect where people are at and to avoid assuming that if people are doing something different from me, it's because they "just followed a tutorial" or something

i've learned that the hard way many many times

glyph,
@glyph@mastodon.social avatar

@b0rk reading you echo that back to me I can see it might come off as dismissive!

A) I really didn’t mean it that way, there’s nothing wrong with like… learning a skill and then applying that skill without futzing around with it a bunch past the point where one is already effective, and

B) I do have a sense that a lot of documentation does exclusively explain pull and set people up for potential problems (having seen those problems).

So, in the interest of science: https://mastodon.social/@glyph/112179953355145017

b0rk,
@b0rk@jvns.ca avatar

@glyph gonna disengage, I don't think I'm communicating very effectively and this isn't going anywhere.

glyph,
@glyph@mastodon.social avatar

@b0rk I don’t think I have much more to say either, but I do hope we are not ending on a sour note here — I really appreciated this conversation, and your posts generally. Thanks for your time!

b0rk,
@b0rk@jvns.ca avatar

@glyph glad it was helpful!

meejah,
@meejah@mastodon.social avatar

@glyph @b0rk I basically only use "git fetch" when about to go offline.

I have an alias for example that does "git fetch" on approximately all interesting repositories. Similarly, I have a private gitolite3 service on a VPS that I can bulk "push --all" to without e.g. thinking "should this be public?"

That said, I'm comfortable enough with the "undo" tools to go back if I found a conflict or some other reason that the merge wasn't a good idea.

tab2space,
@tab2space@mastodon.social avatar

@glyph @b0rk @hynek

"pull-safe" workflows and collaborator practices are an option I've lived well.

A complex branch and merge scheme can continue to be run separately. with no special status for branch "main" or "master".

The pull-safe side can reference the complex side's artifacts via tags, while the complex side goes to town with deeper git operations. Don't forget about your branches, though!

So... welcome to my day-to-day existence, with a foot in both pull and fetch-only worlds

tef,
@tef@mastodon.social avatar

@glyph it's worth remembering that pull's behaviour has changed over the years

before, you had to do fetch for safety

now pull is ff only by default, so there's less risk

glyph,
@glyph@mastodon.social avatar

@tef this just makes me madder about it, because “it depends what version of git you are using” is even worse than “it depends on your config” (which it also still does)

But thank you, this is useful to know, and as a never-puller I definitely missed this update. Do you happen to know about when this happened?

tef,
@tef@mastodon.social avatar
glyph,
@glyph@mastodon.social avatar

@jacob @b0rk to me this feels like skipping the eye protection portion of shop class so we can get to the fun sparks coming off the angle grinder. I understand why folks want to skip it, you don’t need it until you need it, but when you actually need this understanding it’s too late to gain it in a low-stakes way where you’re not already in fight-or-flight. My own approach is to really push hard on making it seem simple rather than easy

hynek,
@hynek@mastodon.social avatar

@jacob @glyph Don’t listen to Big Fetch. I couldn’t make their imaginary workflows ever work in practice. I gave in once and now have a CONTRIBUTING.md in the attrs repo that I don’t understand. They’ve played us for complete fools.

(I’m only half-joking. Whenever I tried that fetch/merge nonsense I ended up with three branches in two origins and six merge commits without changing anything.)

glyph,
@glyph@mastodon.social avatar

@hynek @jacob changing stuff is strenuous, you want to always make sure to create a few extra origins and merge commits every morning to get warmed up

glyph,
@glyph@mastodon.social avatar

@b0rk consider the case of a bad merge which requires some thoughtful conflict resolution, maybe some history rewriting. If you get into this state with a “pull”, you realize that it would be better with some more local commits, back out of the merge, fix stuff up and try again, your second “pull” might bring different changes which is wildly confusing.

b0rk,
@b0rk@jvns.ca avatar

@glyph can you say more about why 'never use pull' is important to you? (what problems has pull caused for you in the past?)

i've heard this "only use fetch + merge" advice 100 times but i've always struggled to understand exactly what problems with pull people are trying to avoid

glyph,
@glyph@mastodon.social avatar

@b0rk https://mastodon.social/@glyph/112179710733446977 but also just a general reluctance to fetch changes. Consider a conference sprint scenario. You’re working on a feature, and you’re going in parallel with someone else — same branch, different branch, it doesn’t matter. You run out of time, and you’re about to leave for a plane. Do you pull? You’re in the middle of debugging, you don’t want to blow up your local state. But if you don’t fetch your work will diverge for hours longer as you lose access to others’ work

b0rk,
@b0rk@jvns.ca avatar

@glyph thanks, those are great examples

glyph,
@glyph@mastodon.social avatar

@b0rk I want to stress also that these are not hypothetical! These are real scenarios I’ve helped people out with, albeit in the latter case just by shouting “just git fetch —all and merge later, see you online!”

b0rk,
@b0rk@jvns.ca avatar

I think the most interesting "use less git features" tricks from the replies so far are:

  • create a temporary branch (or tag) before any 'destructive’ operation, so that you can recover without the reflog
  • use git push origin HEAD:branchname to always explicitly specify the target branch (instead of using git's tracking feature)
  • have an alias for force-with-lease to avoid ever using git push --force
  • never rebase, always manually cherry-pick the commits instead

(2/?)

suetanvil,
@suetanvil@freeradical.zone avatar

@b0rk

A thing I do a lot is:

  • have a messy personal work branch
  • when I'm done or at a waypoint, create a new branch at the work branch's root.
  • git merge --squash work-branch and add a detailed message

This has most of the advantages of rebasing but isn't destructive.

b0rk,
@b0rk@jvns.ca avatar

@suetanvil oh that's a nice idea

tef,
@tef@mastodon.social avatar

@b0rk i do git commit -m “” --allow-empty --allow-empty-commit as the first commit in a project

so if i add some gh-pages branch later, it always starts from an empty repo

b0rk,
@b0rk@jvns.ca avatar

@tef thanks, that's a good one

jakehamilton,
@jakehamilton@hachyderm.io avatar

@b0rk

> never rebase

This is one I think I need to reconsider and come up with a real strategy for. Years ago I set my pull strategy to rebase and the amount of headaches that has caused may have been higher than if I were doing things the “less technically correct” way.

sandro,
@sandro@c3d2.social avatar

@jakehamilton @b0rk The default to create a merge commit is usually worse.

b0rk,
@b0rk@jvns.ca avatar

a few more "use less git features" tricks I think are interesting (even though I don't do most of them):

  • use worktrees so that you don't have switch branches so much (technically this is 'use an extra feature’, but a lot of people said they find it simplifies things)
  • use git merge --squash instead of git rebase, to avoid rewriting history (and so you only have to fix each conflict once)
  • avoid submodules when possible

(3/?)

ShadSterling,

@b0rk what are “worktrees”?

b0rk,
@b0rk@jvns.ca avatar

@ShadSterling this thing https://git-scm.com/docs/git-worktree. not sure what the best intro is.

i honestly haven't used it but it seems like it could be cool

nguarracino,
@nguarracino@techhub.social avatar

@b0rk Is there a recommended alternative to submodules? I've heard many times not to use them, but not sure how else to replicate what they do.

b0rk,
@b0rk@jvns.ca avatar

@nguarracino honestly I haven't thought about this in depth at all, it's very possible that sometimes submodules are the best answer.

there's this blog post https://diziet.dreamwidth.org/14666.html (I find the beginning much too rant-y to understand but the list of alternatives is pretty clear)

nguarracino,
@nguarracino@techhub.social avatar

@b0rk Excellent, thanks! Sounds like subtrees might be what I'm looking for.

b0rk,
@b0rk@jvns.ca avatar

@nguarracino I like subtree!

floby,
@floby@mastodon.social avatar

@nguarracino @b0rk I've found that most technological stack have at least one decent way to handle dependencies (poetry, npm, cargo, etc.) and that it's better to use that instead of submodules.

Private
vv221,
@vv221@fediverse.dotslashplay.it avatar

I just started using remotes with multiple push URLs. That way I can update all mirrors at once with a single call to git push mirrors.

Before that I often forgot to push to one of the multiple remotes, leading to out-of-sync mirrors.

b0rk,
@b0rk@jvns.ca avatar

@vv221 huh I didn’t know you could do that, cool!

dzamir,
@dzamir@mastodon.uno avatar

@b0rk trying to use git in the dumbest way possible is imho the best way to go:

  • branches are always created for main
  • branches are always merged to main with a squash commit (from GitLab/GitHub web interface)
  • main branch is protected (only PRs can be merged)
  • creating branches from branches different than main is strongly discouraged
infektor,
@infektor@mastodon.gamedev.place avatar

@b0rk I have two aliases, save and load, I use these to “stash” on the feature branch I’m working on so the “stash” doesn’t loose context https://code.infektor.net/config/git/src/branch/master/config#L45

ultimatt,
@ultimatt@hachyderm.io avatar

@b0rk a shell alias named gfind, that wraps find and returns a list of all the files in this git repo, minus the .git and language specific includes of other [sub]modules such as node_modules (js), blib (perl), etc.

b0rk,
@b0rk@jvns.ca avatar

@ultimatt oh interesting! is that like git ls-files? (but maybe with some extra stuff removed too, and also including untracked files?)

ultimatt,
@ultimatt@hachyderm.io avatar

@b0rk yes, I'll paste a copy here in ~1h when I'm back at my desk. I frequently work in git repos on servers (miles from an IDE), so I want to do something like 'grep PAT gfind', and have it search for that pattern in every file checked out in that branch. There's no general purpose git utility that can do that because there's too many language specific idioms to account for.

b0rk,
@b0rk@jvns.ca avatar

@ultimatt thanks, that's really cool!

eichin,
@eichin@mastodon.mit.edu avatar

@b0rk
Not sure I'd generally teach this, but: disk space is free - I never switch branches, I just clone into a new directory. Saves a lot of hassle.

glyph,
@glyph@mastodon.social avatar

@eichin @b0rk having just spent yesterday cleaning out 2TB of accumulated junk, much of which was in git repos, to get my laptop to stop throwing “disk full” errors… yeah, maybe don’t teach this generally

melix,
@melix@mastodon.xyz avatar

@b0rk git worktree so that I don't have to stash/commit unfinished work while having to fix an urgent bug on the same project. https://git-scm.com/docs/git-worktree

b0rk,
@b0rk@jvns.ca avatar

@melix thanks!

colby, (edited )
@colby@kosmos.social avatar

@melix @b0rk the whole benefit to git-stash is that it keeps you from having to stop and think of a name for something. If git-worktree had a switch to atomically 1) generate a name for the new worktree 2) set up the worktree there, and 2) change your shell's CWD to the new worktree, immediately teleporting you there to start working, that would be swell. Plus a --kill switch when you're done to clean it all up.

KasTasMykolas,
@KasTasMykolas@river.group.lt avatar

@b0rk I would have said that my to-go life simplifier is just a single flag. But it appears that most of the people are not aware of it.

git log -S<search string>

b0rk,
@b0rk@jvns.ca avatar

@KasTasMykolas it's so good

kellogh,
@kellogh@hachyderm.io avatar

@b0rk use tig. always have dura running. create aliases that make you chuckle.

avoid merge conflicts — if you’re finding you keep getting conflicts on the same file, try refactoring the file so you don’t always have two people editing the same code. like, move the hot blocks of code further from each other

b0rk,
@b0rk@jvns.ca avatar

@kellogh oh cool, I'd never heard of dura

robryk,
@robryk@qoto.org avatar

@b0rk use custom work trees for any scripts that have to commit changes they make to avoid having to deal with dirty work tree and impact of untracked files on the script's behavior

listrophy,
@listrophy@ruby.social avatar

@b0rk

  • you should almost never need arg flags… if you need an arg flag, there’s a good chance you should create a git-alias for it
  • just knowing that reflog exists addresses a lot of the anxiety about losing work
b0rk,
@b0rk@jvns.ca avatar

@listrophy interesting! why do you find aliases easier than using flags?

Drmowinckels,
@Drmowinckels@fosstodon.org avatar

@b0rk I don't know if it's just normal git works but I've become more and more reliant on checkout to also just remove work I want to abandon. I used to only use it to create and start new branches, but find it such a nice cleanup tool

pulkomandy,
@pulkomandy@mastodon.tetaneutral.net avatar

@b0rk

  • before starting a rebase, create a tag where you start from, so you can easily reference the original code (you can delete the tag when the rebase is done). Also keep gitk --all (or some other gui to view commits) open during the rebase to easily see "where" you are
  • I tend to use "git push origin HEAD:branchname" to push the current head to a branch on the remote (also works with others refs, not just HEAD) instead of just "git push"
b0rk,
@b0rk@jvns.ca avatar

@pulkomandy thanks! I'd seen people suggest "git push origin HEAD:branchname" before but didn't totally understand the motivation, this helps

phairupegiont,
@phairupegiont@mastodon.social avatar

@b0rk Never let git put itself in a state where you need to finish resolving an undefined amount of conflicts before you can do anything else (like, being interrupted by a coworker who needs you to make a trivial change!).

Instead, create a new branch and cherry pick one by one, to stay stateless all the way through. That way, no problem stopping in the middle and continuing later

b0rk,
@b0rk@jvns.ca avatar

@phairupegiont thanks! do you mean basically "never use rebase, always cherry-pick instead”?

phairupegiont,
@phairupegiont@mastodon.social avatar

@b0rk kind of? But big merges have the same problem...

And the same solution. If you really want to merge your branch, you can solve all the conflicts by cherry picking on a new branch, and then merge that conflictless branch.

b0rk,
@b0rk@jvns.ca avatar

@phairupegiont thanks!

dmerej,
@dmerej@mamot.fr avatar

@b0rk I once had my 'zsh' prompt function automatically call git fetch so that I could never forget to do it

b0rk,
@b0rk@jvns.ca avatar

@dmerej interesting thanks! it sounds like you don't anymore? why did you decide to stop?

dmerej,
@dmerej@mamot.fr avatar

@b0rk

Lots of reasons

  • I do most of my work from the command line (not just git operation) - so this was a LOT of useless fetches

  • Sometimes git fetch would not work or take a long time (because of VPN issues or something like that) and that was annoying

  • Since fetch was running in the background I was not notified when a remote branch was created, deleted or updated, which is now something I want to know

b0rk,
@b0rk@jvns.ca avatar

@dmerej thanks, makes sense!

  • All
  • Subscribed
  • Moderated
  • Favorites
  • random
  • everett
  • DreamBathrooms
  • tacticalgear
  • magazineikmin
  • Durango
  • Youngstown
  • ngwrru68w68
  • slotface
  • osvaldo12
  • rosin
  • thenastyranch
  • kavyap
  • khanakhh
  • normalnudes
  • JUstTest
  • InstantRegret
  • cisconetworking
  • GTA5RPClips
  • mdbf
  • cubers
  • anitta
  • ethstaker
  • Leos
  • tester
  • modclub
  • megavids
  • provamag3
  • lostlight
  • All magazines