[HN Gopher] Extremely Linear Git History
       ___________________________________________________________________
        
       Extremely Linear Git History
        
       Author : zegl
       Score  : 419 points
       Date   : 2022-11-22 10:43 UTC (12 hours ago)
        
 (HTM) web link (westling.dev)
 (TXT) w3m dump (westling.dev)
        
       | gyulai wrote:
       | Sane revision numbers are among the many reasons I prefer SVN to
       | GIT.
        
         | MAGZine wrote:
         | ... What are the other reasons?
        
           | gyulai wrote:
           | Basically, not to put too fine a point on it, I believe that
           | distributed version control is a problem no one ever truly
           | had, and no one intends to ever have in the future.
           | 
           | I mean: Imagine going back in time 20 years to when git, hg,
           | and bzr were created and telling the creators of those tools:
           | "Hey, while designing your technology, you should be aware
           | that it'll end up being used as a worldwide centralized
           | monorepo run by Microsoft, and no one will ever use any of
           | that distributed stuff."
           | 
           | They'll either laugh you out of the room or you'll be in
           | trouble with the Department of Temporal Investigations for
           | polluting the time line, because what we currently understand
           | as git sure as hell won't be the design they'll come up with.
           | 
           | So for me: I prefer centralized. And SVN is just a reasonable
           | one to use.
        
             | tasuki wrote:
             | > I believe that distributed version control is a problem
             | no one ever truly had, and no one intends to ever have in
             | the future.
             | 
             | Sure. The problem is not "distributed version control",
             | some problems are:
             | 
             | - I'm on a train with no internet, finished working on a
             | thing and want to start working on another thing and don't
             | want to mix them up.
             | 
             | - I want to make a branch and don't want to wait for eons
             | while everything gets copied on the server.
             | 
             | - Oops there's a problem with the server now no one can
             | perform any work.
             | 
             | Yes, SVN might simple commands, but its internals are
             | messed up. Git's UI sucks, but just learn about blobs,
             | trees, commits, branches (pointers to commits), and you
             | basically understand how Git works.
        
               | tjoff wrote:
               | All those things could be done on a centralized version
               | control system as well. Just not on SVN.
        
             | breck wrote:
             | Oh we use distributed day in and day out for everything.
             | Once you start battling censorship you'll get it.
        
               | gyulai wrote:
               | ...so you are among the 1% who use the functionality that
               | causes 99% of what makes git's mental model so convoluted
               | and hard to learn (for _everyone_ , not just the one-
               | percenters).
        
               | detaro wrote:
               | That does sound like the 99% are pretty dumb then for
               | using a tool that's not suitable for them... Or maybe
               | it's not as binary, and Gits model with its complexity
               | has more useful properties making the trade off worth it.
        
               | breck wrote:
               | Fair point! I would love to use the Extremely Linear Git
               | History of the parent post.
               | 
               | I actually wrote a new layer on top of Git years ago (I
               | called it git4 IIRC) and I pitched it to both GitHub and
               | GitLab but they ignored it.
               | 
               | I guess I should have pitched it to the mailing list. I
               | think I was too afraid it was dumb. Will do that at some
               | point.
        
               | seniorThrowaway wrote:
               | the mental model is hard for so many people precisely
               | because all they know of git is github
        
             | yamtaddle wrote:
             | It's worth having distributed version control just so you
             | can work on your own with your own branches and crap and
             | only bother others when you're ready to share. And so you
             | can work seamlessly when offline.
             | 
             | SVN feels like working in someone else's kitchen while
             | several other people are trying to cook in it, too. It's
             | hell. I prefer that we each have our own kitchen and bring
             | our dishes to the table when they're ready.
             | 
             | I've also _repeatedly_ found git a suitable (if not great--
             | if they 'd put all their effort behind libgit2 and make
             | that the official implementation, that'd help a ton) tool
             | to form the foundation of larger systems. It's a damn fine
             | toolbox for attacking certain problems. SVN wouldn't have
             | been much help in any of those situations.
        
             | fgeiger wrote:
             | > it'll end up being used as a worldwide centralized
             | monorepo run by Microsoft, and no one will ever use any of
             | that distributed stuff.
             | 
             | And I thought I use git in a decentralized fashion all the
             | time ... at least I don't need to connect to any other
             | machine when committing, switching branches, merging,
             | rebasing, etc. And my colleagues can do the same without
             | any network connection at the same time.
             | 
             | Also, while it has the biggest brand recognition, not
             | everyone is using GitHub for all their repositories, are
             | they?
        
         | jstimpfle wrote:
         | You could automatically tag each uploaded commit with a number
         | drawn from a sequence - using a git post-update hook. The only
         | problem is that this centralizes the process. It's not possible
         | to have fully "blessed" commits without pushing them first. And
         | that's how SVN works, too.
        
           | loeg wrote:
           | For local repositories, you can do it as a post-commit hook.
           | 
           | In the hook:                 prefix=whatever       old=$(git
           | rev-parse HEAD)       new=$(brute force $prefix)       git
           | update-ref -m "chose prefix $prefix" --create-reflog HEAD
           | "$new"
           | 
           | Of course, it's pretty silly and slow.
        
       | chrsig wrote:
       | Cool hacker project, learned stuff about git reading the article.
       | I don't want to put this into practice, and don't see the utility
       | of it.
        
         | guipsp wrote:
         | It's not supposed to be put into practice, and it's not
         | supposed to be useful.
        
       | bloppe wrote:
       | This is a fun idea, but it will mess with your GC heuristics.
       | 
       | https://git-scm.com/docs/git-gc#_configuration
       | 
       | Git does something called "packing" when it detects
       | "approximately more than <X (configurable)> loose objects" in
       | your .git/objects/ folder. The key word here is "approximately".
       | It will guess how many total objects you have by looking in a few
       | folders and assuming that the objects are uniformly distributed
       | among them (these folders consist of the first 2 characters of
       | the SHA-1 digest). If you have a bunch of commits in the
       | .git/objects/00/ folder, as would happen here, git will
       | drastically over- or under-approximate the total number of
       | objects depending on whether that 00/ folder is included in the
       | heuristic.
       | 
       | This isn't the end of the world, but something to consider.
        
       | jasmer wrote:
       | Wouldn't it have been better if we could use something other than
       | SHA1 as the actual name of something?
       | 
       | Where in the worst dystopian parts of software do we do this?
       | 
       | The SHA1 is kind of a security feature if anything, a side-show
       | thing that should be nestled 1-layer deep into the UI and
       | probably most people are unaware of.
       | 
       | Whereas commits and branches should be designed specifically for
       | the user - not 'externalized artifacts' of some acyclic graph
       | implementation.
       | 
       | Git triggers a product designers OCD so hard, it's hard for some
       | of us to not disdain it for spite.
        
         | jonstewart wrote:
         | I don't want to make up a good name for every commit. Good
         | comments are hard enough.
         | 
         | A SHA-1 might not look friendly to a dev who doesn't understand
         | it, but as someone who works with hash values all the time,
         | having my repo be a Merkle tree gives me a warm fuzzy.
        
           | jasmer wrote:
           | You wouldn't 'make one up' there would be an automatic
           | variation of Semantic Versioning, or something actually
           | useful.
           | 
           | Your 'warm and fuzzy' comes at the cost of confusion (even to
           | yourself), not having any clue what the information really
           | means.
           | 
           | It's not even clear that it's a commit, it could be anything.
           | 
           | This posture is exactly what I'm complaining about: it's
           | objectively bad design engineering, embraced as though
           | somehow it's 'smart'.
           | 
           | Git has a few problems like this.
        
             | jonstewart wrote:
             | Git has problems: stipulated. Improvements in design are
             | possible: also stipulated.
             | 
             | But, your reply is annoying in opining about my mental
             | state and preferences. How am I confused by the SHA-1
             | commits, exactly? And how am I unclear that I'm looking at
             | commits when I issue a "git log"?
        
       | rock_artist wrote:
       | To make sure I've got it right.
       | 
       | In order to get this 'beautiful' hashes, they're crunching
       | numbers leveraging cpu power?
        
         | contradictioned wrote:
         | yep
        
         | kzrdude wrote:
         | Yep. If you squint it's similar to bitcoin mining in that
         | particular aspect
        
           | Bellyache5 wrote:
           | And vanity Tor .onion addresses
        
       | enriquto wrote:
       | I love linear git! Branches are very confusing for a nonempty set
       | of people. For us, it is always clearer to work with explicit
       | files in the main branch. You are implementing a new feature?
       | Nice: just create a new file on the main branch and keep updating
       | it until you add it to the tests, and later you call it from the
       | main program. This system may break down on large teams, but when
       | you are just a handful of grug-brained developers, it's perfectly
       | appropriate.
        
         | mjburgess wrote:
         | That requires your programming language to identify files with
         | modules, and with your system architecture to be extended by
         | modules alone.
         | 
         | This is an ideal case, of course.
        
           | enriquto wrote:
           | I don't understand your comment. The method that I describe
           | only requires that the programming language ignores unused
           | files. As far as I know, all modern programming languages
           | have this feature.
        
             | mjburgess wrote:
             | In the way most languages and applications work, a "new
             | feature" requires modification to several existing file.s
        
               | DaiPlusPlus wrote:
               | .csproj-anxiety
               | 
               | The worst is when you move a bunch of files around in
               | Solution Explorer and commit, maybe do a merge and push,
               | before you realise the MSBuild/csproj files were never
               | saved (gotta press Save All for some reason) - now you
               | have a change you need to apply to a pre-merge commit.
               | Good luck with that.
        
         | aqme28 wrote:
         | This feels like a lot of extra work to throw away the benefits
         | you actually get out of version control. I would very much not
         | like to work on this team.
        
         | bigDinosaur wrote:
         | This doesn't handle the reasonably common case very well where
         | someone is working on changes which are constantly breaking the
         | branch for everyone else. They should have their own branch and
         | be frequently rebasing/merging so as to not disrupt others.
         | 
         | Also exploratory branches where any nonsense may go on (that
         | may end up being merged, at least partially!). Also
         | test/development vs. production branches! One may be broken,
         | the production branch should ideally never be in a state that
         | cannot be deployed.
         | 
         | That said, keep the branches limited and try to keep them
         | 'linear' in the sense that you don't want to be merging
         | _between_ 100 different non-main branches in some byzantine
         | nightmare. Perhaps encourage merges only to the development
         | branch and then rebranching.
        
           | Filligree wrote:
           | > Also exploratory branches where any nonsense may go on
           | (that may end up being merged, at least partially!). Also
           | test/development vs. production branches! One may be broken,
           | the production branch should ideally never be in a state that
           | cannot be deployed.
           | 
           | Well, why don't you simply copy the code into a new directory
           | and commit that? Then you can do whatever you want in the
           | scratch directory.
        
             | bigDinosaur wrote:
             | To me that seems messier than a new branch. For one, how
             | are others to know my files are test/scratch/feature branch
             | files? I'd have to use a naming scheme, and some kind of
             | other signal to make sure nobody imports them before
             | they're ready or mistakes them for deployable files - and
             | at that point I'm just replicating a branch!
        
               | enriquto wrote:
               | > and at that point I'm just replicating a branch!
               | 
               | Yes. My entire point is that you can always replicate
               | branches with actual, explicit files, and that this is a
               | good thing to do because files are (very often) better
               | than branches. Files plus some editor discipline are
               | essentially equivalent to branches.
               | 
               | Files+discipline are better than branches, according to
               | standard unix philosophy: (1) everything is a file, (2)
               | protocol not policy.
        
               | Filligree wrote:
               | Oh dear. I was joking.
        
           | enriquto wrote:
           | > the reasonably common case very well where someone is
           | working on changes which are constantly breaking the branch
           | 
           | But isn't this bad practice? My grug brain refuses to commit
           | anything that does not pass tests. Check tests, then commit.
           | Check tests, then commit.
           | 
           | You can hide your as yet incomplete feature inside an
           | undocumented option, and work from there, without breaking
           | anything.
        
             | bigDinosaur wrote:
             | I don't see why this would be bad practice. If you complete
             | half a feature during your work day then you may well want
             | to commit it (and likely push it to a remote). Merging it
             | to a branch others are working on is likely to be worse
             | than not merging it until it is complete as it may simply
             | be in a not working state.
        
             | eru wrote:
             | There's nothing special about commits. Feel free to commit
             | as many broken and non-working things as you feel like.
             | It's not much different from saving in your editor.
             | 
             | It's in master (or your production branch etc) where you
             | only want Commits That Work.
             | 
             | Btw, if you are re-factoring your types, you won't be able
             | to hide that from your compiler via a simple feature flag.
             | 
             | What's a grug brain?
        
             | DaiPlusPlus wrote:
             | How do you handle major refactoring, or entire directory
             | structure reorganisation? Stuff like that you can't hide
             | behind a switch.
        
               | enriquto wrote:
               | Do it on a single commit? (or contiguous series of
               | commits) It's not going to conflict with any other branch
               | because there are no other branches ;)
               | 
               | I guess that large refactorings/reorganizations are
               | _harder_ if you have many branches, because they will
               | inevitably lead to merging conflicts. On a linear setup,
               | you don 't have this problem.
        
       | nsajko wrote:
       | Gitlab supports an option called "Fast-forward merge":
       | 
       | > No merge commits are created.
       | 
       | > Fast-forward merges only.
       | 
       | > When there is a merge conflict, the user is given the option to
       | rebase.
       | 
       | The maintainer can enable this for a project.
        
         | spyremeown wrote:
         | So does almost every PR-based workflow tool for (bitbucket,
         | GitHub etc). It's very common.
        
       | infogulch wrote:
       | Github-style rebase-only PRs have revealed the best compromise
       | between 'preserve history' and 'linear history' strategies:
       | 
       | All PRs are rebased and merged in a linear history of merge
       | commits that reference the PR#. If you intentionally crafted a
       | logical series of commits, merge them as a series (ideally you've
       | tested each commit independently), otherwise squash.
       | 
       | If you want more detail about the development of the PR than the
       | merge commit, aka the 'real history', then open up the PR and
       | browse through Updates, which include commits that were force-
       | pushed to the branch and also fast-forward commits that were
       | appended to the branch. You also get discussion context and
       | intermediate build statuses etc. To represent this convention
       | within native git, maybe tag each Update with pr/123/update-N.
       | 
       | The funny thing about this design is that it's actually more
       | similar to the kernel development workflow (emailing crafted
       | patches around until they are accepted) than BOTH of the typical
       | hard-line stances taken by most people with a strong opinion
       | about how to maintain git history (only merge/only rebase).
        
         | pnt12 wrote:
         | I wholeheartedly agree!
         | 
         | With this, you can also push people towards smaller PRs which
         | are easier to review and integrate.
         | 
         | The downside is that if you es o work on feature 2 based on
         | feature 1,either you wait for the PR to be merged in main
         | (easiest approach) or you fork from your feature branch
         | directly and will need to rebase later (this can get messier,
         | especially if you need to fix errors in feature 1).
        
         | couchand wrote:
         | What's weird about most of these discussions is how they're
         | always seen as technical considerations distinct from the
         | individuals who actually use the system.
         | 
         | The kernel needs a highly-distributed workflow because it's a
         | huge organization of loosely-coupled sub-organizations. Most
         | commercial software is developed by a relatively small group of
         | highly-cohesive individuals. The forces that make a solution
         | work well in one environment don't necessarily apply elsewhere.
        
       | larschdk wrote:
       | I want the 'merge' function completely deprecated. I simply don't
       | trust it anymore.
       | 
       | If there are no conflicts, you might as well rebase or cherry-
       | pick. If there is any kind of conflict, you are making code
       | changes in the merge commit itself to resolve it. Developer end
       | up fixing additional issues in the merge commit instead of actual
       | commits.
       | 
       | If you use merge to sync two branches continously, you completely
       | lose track of what changes were done on the branch and which
       | where done on the mainline.
        
         | nextlevelwizard wrote:
         | If you have bunch of commits in a feature that are related it
         | is easier to revert merges (even if you do pre-merge rebase
         | from master and then merge with --no-ff)
        
         | Chris2048 wrote:
         | I'd like a "quick ff" that will ff if there are no conflicts,
         | or ff as far as it can with no conflicts - and an easy way to
         | apply to many branches.
         | 
         | Also, a way to "rebase" that works the same as cherry picking
         | commits on top of the target. As far as I can see, the regular
         | rebase works it's way up the target branch, so that I end up
         | resolving conflicts in code that eventually changed in the
         | target.
        
         | BiteCode_dev wrote:
         | This work if you have only experienced professional developpers
         | in the team. If you have juniors or non devs (mathematicians,
         | geographers, qwants...) that just happen to also code, rebase
         | is a minefield. This is espacially true in open source
         | contributions.
        
           | kzrdude wrote:
           | Merge and conflict resolution is a minefield if unexperienced
           | developers do it too. Fortunately it can (often) be arranged
           | that those with some understanding of the issues involved can
           | do the resolution.
        
             | cerved wrote:
             | you get the same, and often more, conflicts using rebase
        
           | voakbasda wrote:
           | If you can't rebase, I don't want you pushing to my main
           | branches. I would rather teach everyone how to rebase before
           | I cave and allow merge commits.
        
             | BiteCode_dev wrote:
             | In a perfect world with infinite resources and no time
             | constraints, sure.
        
               | antris wrote:
               | I've done several projects rebase-only with limited
               | resources and time constraints. In fact, it saved
               | resources and time when we did it.
               | 
               | You have been repaid the time investment spent learning
               | rebase commands, after once being able to avoid a really
               | bad merge conflict.
        
         | u801e wrote:
         | What I would like to see is a way to enforce fast-forward only
         | merges along with the forced creation of a merge commit that
         | references the same git tree as the HEAD commit of the branch
         | that was just merged.
         | 
         | This way, you know which set of commits was in the branch by
         | looking at the parent commits of the merge commit, but the
         | merge commit itself did not involve any automated conflict
         | resolution.
        
           | wnoise wrote:
           | Yes, it is a shame that you can't combine git merge --ff-only
           | --no-ff .
        
             | cerved wrote:
             | git rebase && git merge --no--ff
        
           | breatheoften wrote:
           | I've wanted this for awhile as well. Squash only merges,
           | which are enforceable in github, get you close but leave you
           | without any automated way to determine if a given branch was
           | ever merged to main or not ...
        
             | cerved wrote:
             | merge is the only way to reliable determine if a branch is
             | merged - \ _ ( tsu ) _ / -
        
         | sidlls wrote:
         | Rebasing is a tool of last resort, when something has so fowled
         | up the code that merging a large-scale refactor is even more
         | time consuming.
         | 
         | Rebasing takes longer and is actually more prone to error
         | because of the clunky interface. There is absolutely nothing
         | wrong with squashing commits in a feature branch and merging
         | that into master/main. In fact, it's generally better for the
         | health of the repo and the mental health of developers.
        
           | cerved wrote:
           | in my experience, rebase works great if the commits are
           | structured and much more painful with lots of overlapping
           | changes, say by continiusly doing _wip_ commits every hour
        
         | rjmunro wrote:
         | I usually rebase the branch onto the upstream branch (master or
         | main or whatever) if there are merge conflicts. You can then
         | resolve the conflicts commit by commit. This requires force
         | pushes, but they are are not normally a problem because only
         | one dev tends to work on a particular branch before it's
         | merged.
         | 
         | If you do have multiple devs working on the same branch, use
         | `git pull --rebase` to stay in sync with each other, don't use
         | merges and leave lots of merge commits. If you need to resolve
         | conflicts with upstream, make sure other people have stopped
         | working on the branch, rebase it, then merge.
        
         | masklinn wrote:
         | I think merge is great, having a "unit" for a feature branch
         | being integrated is nice and not all things can be done in
         | commits which are individually justifiable. The ability to
         | bisect cleanly through the first ancestor is precious.
         | 
         | I do agree that resolving conflicts in merges is risky though.
         | It can make sense when merging just one way between permanent
         | branch (e.g. a 1.x branch into a 2.x), but as soon as cross
         | merges become a possibility it's probably a mistake.
        
           | losvedir wrote:
           | > I do agree that resolving conflicts in merges is risky
           | though.
           | 
           | How do you do otherwise, though? Or is your workflow a
           | combination of rebases and merges? Continual rebasing of the
           | feature branch onto `main` and then a final merge commit when
           | it's ready to go?
        
             | neweroldguy wrote:
             | This is what I do unless I'm working with a large number of
             | people on the feature branch (which is rare, usually that
             | would be multiple branches).
             | 
             | You get the equivalent of "mergeless" history (just
             | restrict your git log to merge commits) but can dig into
             | the individual feature histories easily.
        
             | masklinn wrote:
             | > Or is your workflow a combination of rebases and merges?
             | Continual rebasing of the feature branch onto `main` and
             | then a final merge commit when it's ready to go?
             | 
             | Yes. You don't usually need "continual" rebasing, most
             | commonly just once just before merging.
             | 
             | In fact a good merge tool can do it for you (and refuse to
             | merge if there are conflicts when rebasing).
        
         | eurasiantiger wrote:
         | It is also a security risk. Someone could add whatever
         | unreviewed code and it would get glanced over as a merge
         | commit. Put your payload in an innocuous file not likely to be
         | touched and call a boilerplate-looking function as a side
         | effect from somewhere.
        
         | [deleted]
        
         | silon42 wrote:
         | Personally, I believe merging 'master' to your feature branch
         | is the wrong model... what one should do is create a new branch
         | from master and merge the old branch into it.
        
           | dahart wrote:
           | Why? Merging master into the feature branch is done so that
           | you can test the conflict resolution in the branch before
           | inflicting it on everyone. It's also done on a regular basis
           | in longer running feature branches to prevent large conflicts
           | from accumulating- you can merge master into your branch
           | multiple times to stay current with master before ever
           | merging back into master. I'm not sure why parent says this
           | causes them to lose track of which changes happened in which
           | branch. The history does get a bit more complex at a glance,
           | but for any given commit, it's easy to pinpoint their origin
           | if using only merge commits. It only gets harder if you
           | accidentally rebase someone else's commits along the way. For
           | smaller feature branches and smaller projects, it's okay to
           | merge branches into master, but for large branches, large
           | projects, large teams, and teams that care about testing,
           | merging master into feature branches is a best practice. What
           | makes you consider it 'wrong'?
        
           | phailhaus wrote:
           | A merge commit is just a commit with two parents. You're not
           | affecting the master branch at all when you "merge in
           | master", you're just creating a new commit where the first
           | parent is your branch, and the second parent is the master
           | branch.
           | 
           | If you do things the way you're suggesting, you'll make it
           | really hard to tell what commits were made on your branch.
           | Git clients tend to assume the first parent is the branch you
           | care about.
        
           | piskerpan wrote:
           | If you're merging (and not rebasing) it's the same exact
           | thing. You're just switching the "incoming" version, but
           | conflicts will be identical.
        
         | foobarbecue wrote:
         | > Developer end up fixing additional issues in the merge commit
         | instead of actual commits.
         | 
         | As long as the merge commit is being reviewed with the rest of
         | the PR, that's fine, right? (We use rebase while working on
         | feature branches, and then squash & merge for completed PRs,
         | which seems to be the best of both worlds)
        
         | e40 wrote:
         | I have never had issues with merge, unless rerere was enabled.
         | I've had some extremely surprising results recently with it
         | enabled and I finally disabled it for good.
        
         | simiones wrote:
         | Unfortunately, git rebase has a very very annoying limitation
         | that git merge doesn't. If you have a branch with, say, masterX
         | + 10 commits, and commit 1 from your branch is in conflict with
         | masterX+1, then when you rebase your branch onto masterX+1, you
         | will have to resolve the conflict 10 times (assuming all 10
         | commits happen in the same area that had the original
         | conflict). If instead you merge masterX+1 onto your branch, you
         | will only have to resolve the conflict once.
         | 
         | Even though I much prefer a linear history, losing 1h or more
         | to the tedious work of re-resolving the same conflict over and
         | over is not worth it, in my opinion.
        
           | broeng wrote:
           | In your example, you pretty much have to change the same
           | line, or neighbouring line, those 10 times to end in that
           | scenario. If it's just somewhere else in the file, git auto-
           | merging will handle it just fine.
           | 
           | It seems like a very contrived example to me. We have been
           | running rebase/fast-forward only for close to 10 years now,
           | and I have never experienced anything that unfortunate.
        
             | ncann wrote:
             | Yeah that scenario only ever happens if you have an
             | extremely large branch that hasn't been merged into the
             | target branch for a long time (like a feature branch that
             | takes months to develop), which btw isn't really something
             | that should be done anyway (always try for more frequent
             | merge with small side branches).
        
             | simiones wrote:
             | It happens pretty often when two different people are
             | adding a new function in the same area of a file. It's
             | likely that as you're working on that function, you'll be
             | modifying the surrounding lines a few times (say, you have
             | a first pass for the happy path, then start adding error
             | handling in various passes; or, handling one case of an
             | algorithm in each commit).
             | 
             | Rebase is still by far the most common case in our repo, as
             | yes, these cases appear very rarely. But when they do
             | happen, it's often worth it to do a merge and mess up a
             | history a little bit (or squash, which messes with history
             | in another way) rather than resolving conflicts over and
             | over.
             | 
             | Someone else was also suggesting rerere for this use case,
             | but I've never used it myself and I don't know how well it
             | actually handles these types of use cases.
        
             | Beltalowda wrote:
             | > It seems like a very contrived example to me.
             | 
             | I run in to this quite frequently, even on projects where
             | I'm the only one working on it (I tend to have a lot of
             | things going on in parallel). Once branches diverge and
             | commits accumulate it can become a right pain. Usually my
             | solution is to merge master into the branch just to keep up
             | to date and then just undo everything, make one new commit
             | in the master, and rebase that. But in some more difficult
             | cases it was "just merge and fuck it because life's too
             | short". I've also just manually "copy/paste merged" things
             | to a new branch, because that seemed quicker than dealing
             | with all the merges/conflicts.
             | 
             | Maybe there are better ways of doing this, and arguably I
             | shouldn't have all these long-lived branches in the first
             | place (but it works well for me, so...), but it's not that
             | much of a contrived edge case.
        
               | couchand wrote:
               | > arguably I shouldn't have all these long-lived branches
               | in the first place
               | 
               | This is the problem here. If you have multiple long-lived
               | branches, there's no technical solution to preventing rot
               | -- you must actively keep them in sync.
               | 
               | Regularly merging in main is the opposite of the proper
               | solution. Constantly rebasing on top of main is the
               | proper solution.
        
               | MaxBarraclough wrote:
               | > If you have multiple long-lived branches, there's no
               | technical       > solution to preventing rot -- you must
               | actively keep them in sync.
               | 
               | Rebasing isn't an alternative to this, it's just a
               | different way of manually keeping in sync.
               | > Regularly merging in main is the opposite of the proper
               | solution.       > Constantly rebasing on top of main is
               | the proper solution.
               | 
               | Why? You've given no justification for your preference.
        
               | couchand wrote:
               | > Rebasing isn't an alternative to this, it's just a
               | different way of manually keeping in sync.
               | 
               | I never said it was, I said it was the right way to keep
               | them in sync.
               | 
               | > Why? You've given no justification for your preference.
               | 
               | I don't need to, the GGGGP said it perfectly:
               | https://news.ycombinator.com/item?id=33705026
        
               | jacobsenscott wrote:
               | A rebase and a merge result in the same code. A rebase is
               | more error prone though. Just because someone "feels" a
               | merge isn't as safe doesn't make it so.
        
               | pqdbr wrote:
               | How do you constantly rebase on top of main if more than
               | one person is working on the feature branch?
        
               | couchand wrote:
               | recursion
        
               | frant-hartm wrote:
               | Doesn't git's rerere help here?
        
             | collinvandyck76 wrote:
             | It's not as contrived as you may think. I, along with what
             | I imagine are many others, do a lot of frequent micro-
             | commits as time goes on and the feature becomes more
             | complete, with a lot of commits in the same area of any
             | given file. Rebasing a development branch in this state is
             | pretty gnarly when a conflict arises.
             | 
             | Sadly, my current approach is to just reset my development
             | branch to the merge base and make one huge commit, and then
             | rebase.
        
             | michaelt wrote:
             | Sounds like you've never worked on a project with a file
             | everyone wants to append to :)
             | 
             | If every error in your system needs a separate entry in the
             | error enum, or every change needs an entry in the changelog
             | - loads of changes will try to modify the last line of the
             | file.
        
               | olddustytrail wrote:
               | Depending on the format of your files, entries like
               | "changelog merge=union" in your .gitattributes file might
               | work for you.
        
               | account42 wrote:
               | Even multiple appends are not that bad for rebasing - if
               | you put the remote changes before your own then after the
               | first commit the context for your remaining commits will
               | be the same.
               | 
               | If order actually matters then yeah, git can't magically
               | know where each new line should go.
        
           | adgjlsfhk1 wrote:
           | you can often solve this by squashing before rebasing.
        
             | erik_seaberg wrote:
             | Reviewing a squashed branch is much harder than reviewing
             | one set of closely related deltas, and then reviewing a
             | different set of closely related deltas that happen to
             | overlap.
        
             | MaxBarraclough wrote:
             | That has its own problems. Separating whitespace-only
             | reformatting commits from substantive commits makes it much
             | easier to inspect the real changes, for instance.
             | 
             | Also, more fine-grain commits can help you trace down a
             | bug, perhaps with the help of _git bisect_. Once you 've
             | tracked down the commit that introduced the bug, things
             | will be easier if that commit is small.
             | 
             | Fortunately you can just merge _from_ master, bringing your
             | code back in sync with master without touching master
             | itself. I see Beltalowda has mentioned this.
        
             | IshKebab wrote:
             | You mean you can often give up and avoid solving the
             | problem by squashing before rebasing?
        
           | quadhome wrote:
           | man git-rerere
        
             | simiones wrote:
             | It often amuses me that some people will say "git is
             | actually easy, you just need to know git commit, git pull,
             | git push, and git branch", but when you go into the
             | details, you find out you have to learn a hundred other
             | rarer tools to actually fix the 5% or 1% use cases that
             | everyone eventually hits.
             | 
             | For what it's worth, I had heard of git rerere before, and
             | have looked at the man page, but haven't understood how
             | it's supposed to work, and haven't had time to play with it
             | to see how well it actually works in practice. `git merge`
             | or `git squash` and accepting a little bit of a mess in
             | history seems much easier than spending time to learn
             | another git tool for some use case, but I fully admit I may
             | be missing out.
        
               | Izkata wrote:
               | When you hit a merge conflict, rerere (re)members how you
               | (re)solved it and (re)applies the same fix when the same
               | conflict happens again. But using it can create a new
               | problem/annoyance: If you make a mistake with the initial
               | resolution, and revert the merge/rebase to try again,
               | it'll remember the wrong one next time. So you have find
               | and tell it to forget that resolution.
        
           | [deleted]
        
           | YetAnotherNick wrote:
           | You should do reverse rebase(if it makes sense lol) for this.
           | Instead of rebasing branch to master, rebase master to
           | branch. The only downside is that it requires many force push
           | in the branch.
        
             | moonchrome wrote:
             | Yeah force push on master is a huge no no - I can't even
             | remember the number of times I've force pushed wrong shit
             | in a hurry - I can't imagine entire team dealing with this.
        
             | cerved wrote:
             | > it requires many force push in the branch
             | 
             | Can't say I recommend this approach.
        
             | simiones wrote:
             | I would first say that I would sooner re-code the whole
             | feature by hand from memory than ever rebasing master onto
             | anything for any serious project.
             | 
             | Even if we were to do that, rebasing master is likely to
             | lead to the same issue.
             | 
             | My preferred solution is rebase featureB onto master for
             | the 99% or 99.9% of use cases where this is smooth, and in
             | the rare case that you have too many conflicts to resolve,
             | merge master into featureB (and/or squash featureB then
             | rebase onto master, depending on use case).
        
           | acchow wrote:
           | Hmmm I think in your scenario you could avoid resolving the
           | conflict 10 times by using `git rebase --onto`
           | 
           | Suppose "masterX+1" is called latest
           | 
           | Suppose "masterX" is the SHA of your mergebase with master
           | (on top of which you have 10 commits)
           | 
           | `git rebase --onto latest masterX`
        
           | [deleted]
        
           | mamcx wrote:
           | I was converted to rebase by my current team, and this hit
           | every time.
           | 
           | I wish it works like merge, or exist a way to merge, resolve
           | conflict, rebase?
        
             | cerved wrote:
             | merge, then resolve conflicts with rerere, undo the merge
             | and rebase
        
             | HWR_14 wrote:
             | Can I asked how they converted you (or do you mean by
             | dictate, as opposed to becoming convinced it was better)? I
             | find myself loving merges and never using rebases. It's not
             | that I cannot describe technically what's happening, but I
             | just don't understand the love.
        
               | scubbo wrote:
               | (Not the person you replied to, but a passionate rebase-
               | preferred) For me there are two reasons - one aesthetic,
               | one practical.
               | 
               | The aesthetic reason is that it tells a more coherent
               | story. The codebase is a single entity, with a linear
               | history. If I asked you "how old were you last year", and
               | you asked "which me are you asking about?", I'd be
               | confused. Similarly, if I want the answer to the question
               | "what was the codebase like at this point in time //
               | immediately prior to some point?", you shouldn't need to
               | ask clarifying questions. `HEAD^` should only ever point
               | to a single commit.
               | 
               | The practical reason is that it discourages a bad-
               | practice - long-lived branches. The only vaguely
               | compelling reason I have heard for merge commits is that
               | they preserve the history of the change, so that when you
               | look at a change you can see how it was developed. But
               | that's only the case if you're developing it (in
               | isolation) for a long-enough time that `main` will get
               | ahead of you. You should be pushing every time you have a
               | not-incorrect change that moves you closer towards the
               | goal, not waiting until you have a complete feature! If
               | you make it difficult to do the wrong thing _while also_
               | making it easy to do the right thing (too many zealots
               | forget the second part!), you will incentivize better
               | behaviour.
               | 
               | (Disclaimer - I've been lucky enough to work in
               | environments where feature flagging, CI/CD, etc. were
               | robust enough that this was a practical approach. I
               | recognize this might not be the case in other situations)
               | 
               | And yeah, I'm kinda intentionally invoking Cunningham's
               | Law here, hoping that Merge-aficionados can tell me what
               | I'm missing!
        
               | xeyownt wrote:
               | In my case, I switched rapidly to git-rebase because it
               | produces history that is much cleaner and easier to
               | understand. I only do merge if there is a good reason to
               | preserve history (e.g. some other branches depend on it,
               | or some test reports refer to a given commit).
        
               | mamcx wrote:
               | Mostly is about the way they do things, and I always
               | adopt the team ways (also: my initial PRs look weird to
               | them!).
        
           | semiquaver wrote:
           | As sibling mentioned, this is totally solved by git-rerere.
        
             | booleandilemma wrote:
             | When can we move to Sapling again?
        
               | Shish2k wrote:
               | I already have - it's pretty great :D
        
               | IshKebab wrote:
               | How would Sapling avoid this? As I understand it it uses
               | the same data model as Mercurial which is really the same
               | as Git's. I think you would need something like Pijul to
               | solve it nicely. At least as far as I can tell.
               | 
               | I might actually try this in Pijul because I too
               | encounter this semi-regularly (it's not a freak
               | occurrence at all) and my solution is basically to give
               | up and squash my branch before rebasing.
        
             | BiteCode_dev wrote:
             | Partially. Unfortunatly, rerere is not perfect, and will
             | only solve 80% of the cases.
             | 
             | For big rebase, this can add up to a lot, which I just paid
             | the price last week.
        
         | pnt12 wrote:
         | I don't understand the hate for merges, or the love for
         | rrbaded. Let's consider what may happen using a github flow
         | strategy (main branch, feature branches based solely on main):
         | 
         | * If you screw up a merge, you undo the merge commit. Now your
         | branch is exactly as it were. May not happen with a rebase.
         | 
         | * If you push some code to the remote, and later find out it
         | was outdated, you can merge it with main and push again: no
         | need to force, github can distinguish what's already been
         | reviewed and what hasn't. With rebase, you may need to push --
         | force, and if someone already reviewed the code they're going
         | to be shit out of luck, as github will lose the capability to
         | review "changes since last review", as the reference it has may
         | have been lost.
         | 
         | I also merge these features using squash commits, which
         | provides a very linear history. This also saves some effort
         | (you don't need to be rebase the commits in the feature branch,
         | which can be a pain in the ass for unorganized people and git
         | newbies, and you are pushed towards making smaller, granular
         | PRs that make sense for the repo history).
        
         | GuB-42 wrote:
         | > I want the 'merge' function completely deprecated. I simply
         | don't trust it anymore.
         | 
         | Merge is perfectly fine and it is the only way to synchronize
         | repositories without changing the history, which is very
         | important for a decentralized system. It certainly has the
         | potential to make a mess if used improperly, but so do rebase,
         | cherry-pick, and basically every other command.
         | 
         | > If you use merge to sync two branches continously, you
         | completely lose track of what changes were done on the branch
         | and which where done on the mainline.
         | 
         | If you do things correctly, that is by making sure that when
         | you merge changes from a feature branch into the mainline, the
         | mainline is always the first parent, you shouldn't have any
         | problem. Git is designed this way, so normally, you have to go
         | out of your way to mess things up. If did it like that and you
         | don't want to see the other branch commits, git-log has the
         | --first-parent option.
        
           | cerved wrote:
           | way easier to mess up a rebase
        
             | couchand wrote:
             | way easier to tell that you've messed up a rebase
        
               | cerved wrote:
               | it's actually way easier to accidentally mess up a
               | rebase, especially if rearranging commits.
               | 
               | I can recommend git diff @{1} post rebase I alias it to
               | d-
        
               | couchand wrote:
               | I'm not sure if you misread my comment, but my point was
               | that it's far too easy to accidentally introduce bugs in
               | merge commits that go unnoticed for a long time.
               | 
               | I've never seen a rebase gone awry introduce production
               | bugs, but I've known multiple gnarly bugs caused by
               | errant merges. YMMV.
        
           | benatkin wrote:
           | Proper use of merge is table stakes. You get warned in your
           | PR if your non-main branch is out of date with your main
           | branch, and after you rebase and force push your non-main
           | branch, you review the diff in the PR.
        
             | couchand wrote:
             | Then you don't actually need merge? Am I missing something?
             | 
             | If you always rebase the branch, the commits can be applied
             | directly.
        
               | xxpor wrote:
               | if you do this:
               | 
               | (starting on main)
               | 
               | git checkout -b feature
               | 
               |  _do work_
               | 
               | git commit -a
               | 
               | git checkout main
               | 
               | git pull
               | 
               | git checkout feature
               | 
               | git rebase main
               | 
               |  _publish code review, get approval_
               | 
               | git checkout main
               | 
               | git merge feature
               | 
               | You still use merge at the end, even though it's not
               | actually doing anything that'll result in a conflict.
        
               | couchand wrote:
               | Totally on board (except the forbidden -a switch).
               | 
               | The last command is:                   cp
               | .git/refs/heads/feature .git/refs/heads/main
               | 
               | No merge needed.
        
               | xxpor wrote:
               | Touching files in .git (outside of like, .git/config)
               | directly gives me the heebee jeebees
        
               | couchand wrote:
               | Fair point, and I would not advocate that specific
               | workflow! My point was just to illustrate that we can
               | live without merge.
        
               | micw wrote:
               | Rather than switching to "main" and pull it, you can just
               | stay in "feature" and do a fetch followed by "rebase
               | origin/main". Then pull "main" before you merge the
               | feature.
               | 
               | I'd also use "merge --no-ff" to force an empty commit
               | that visualizes where a feature begins and ends.
        
         | bsza wrote:
         | > you might as well rebase or cherry-pick
         | 
         | Both tools are pure vandalism compared to merge. Among the two,
         | cherry-picking is preferable in this case because you're "only"
         | destroying your own history, so in the end, it's your funeral.
         | 
         | > Developer end up fixing additional issues in the merge commit
         | instead of actual commits.
         | 
         | A merge commit IS an actual commit, in every sense of the word.
         | The notion it somehow isn't, is what you need to get rid of.
        
           | cerved wrote:
           | Rebasing / rerolling is completely fine if done right, no
           | need to be overly zealous. But merges are often more elegant
        
         | danwee wrote:
         | I usually do `git merge --no-ff development` when working on my
         | feature branch. We do not leave feature branches "open/live"
         | for too much time, so merge conflicts are not usually a
         | problem, but sometimes they do happen.
         | 
         | I like cherry-pick, but I barely use it (e.g., I need to
         | cherry-pick one commit from branch X into my branch). I don't
         | like rebase much because it requires force-push.
        
           | cerved wrote:
           | rebase only require force push if you're rebasing something
           | already pushed
        
         | gpvos wrote:
         | _> If there is any kind of conflict, you are making code
         | changes in the merge commit itself to resolve it._
         | 
         | I don't get it. If you rebase, you get 20 chances to do the
         | same.
        
           | thargor90 wrote:
           | Reviewing merge commits is harder because they will sometime
           | have huge diffs to both branches.
           | 
           | Rebasing is the process of redeveloping your feature based on
           | the current master. This is smaller, easier steps to review
           | later.
           | 
           | It is a pitty that we can't have tooling to create "hidden"
           | merge commits to allow to connect rebased branches, this
           | would retain the history better and allow pulling more
           | easily.
        
       | davide_v wrote:
       | I thought I was a very tidy person, then I saw this.
        
         | Thev00d00 wrote:
         | Im not sure it is tidy to inject random junk into your commit
         | message to get a hash prefix
        
           | mgsk wrote:
           | Or maybe it is _extremely_ tidy.
        
             | kreetx wrote:
             | I think the question boils down to "where is the junk?" ;)
             | I.e, there is always junk, some put it in a commit hash,
             | others into the files committed.
        
               | mikehotel wrote:
               | And now this uses invisible junk (white space). See
               | update: https://news.ycombinator.com/item?id=33704810
        
       | hoseja wrote:
       | This is very silly.
        
         | zegl wrote:
         | Do not try this at home.
        
         | chii wrote:
         | but fun. Also might as well just mine bitcoins tbh...
        
       | u801e wrote:
       | Why does the version skip from 19 to 20? What about 1A, 1B, 1C,
       | 1D, 1E, and 1F?
        
         | cjbprime wrote:
         | It's using a neat numbering system called "decimal", you should
         | check it out.
        
       | pelasaco wrote:
       | if it was SHA256 we could find an usage for all bitcoin miners
       | that we have...
        
       | forgotmypw17 wrote:
       | I am writing a solo project. I only use main (aka master) and
       | never use branching. Otherwise, I inevitably screw something up.
       | It is good enough to keep me from losing stuff most of the time,
       | and I almost never have to struggle with understanding what the
       | heck Git is doing.
        
       | [deleted]
        
       | maxbond wrote:
       | Has anyone tried using git alternatives like fossil in
       | production? Did it work out? Did you build CI/CD around it?
        
       | bcoughlan wrote:
       | I wish Git had more support for "linear" revisions in the main
       | branches. It's great for continuous delivery where you can get a
       | unique identifier that's also human-friendly.
       | 
       | I emulate this by counting the number of merges on main:
       | 
       | git rev-list --count --first-parent HEAD
       | 
       | But it's not that traceable (hard to go from a rev back to a
       | commit).
        
         | tazjin wrote:
         | We do this at TVL, and push the corresponding revision as a ref
         | (refs/r/$n) back to git. See for example our cgit log view:
         | https://code.tvl.fyi/log/
         | 
         | This way, a correctly configured git client (which pulls those
         | refs) can use `git checkout r/1234` to get to that revision.
         | It's also noteworthy that this is effectively stateless, so you
         | can reproduce the exact revisions locally with a single shell
         | command without fetching them from the remote.
         | 
         | The revisions themselves are populated in CI:
         | https://cs.tvl.fyi/depot@c537cc6fcee5f5cde4b0e6f8c5d6dcd5d8e...
        
       | titzer wrote:
       | I prefer a linear version number on the main branch and I have a
       | really tiny version file that gets incremented on every change to
       | the src/ directory. That's not entirely automated, but a commit
       | queue could do that.
       | 
       | Brute-forcing hash collisions seems like an April Fool's joke.
       | You can't really be serious that people are going to do this
       | regularly?
        
         | javier123454321 wrote:
         | I don't think people actually take this project seriously
        
       | chrismorgan wrote:
       | It has been my habit for a while to make the root commit 0000000
       | because it's fun, but for some reason it had not occurred to me
       | to generalise this to subsequent commits. Tempting, _very_
       | tempting. I have a couple of solo-developed-and-publicly-shared
       | projects in mind that I will probably do this for.
        
         | jrmg wrote:
         | How do you make the first commit 0000000? (Without using this
         | project, obviously).
        
           | robertlagrant wrote:
           | Might be by using that hashcrash tool.
        
           | chrismorgan wrote:
           | lucky_commit
        
           | boxed wrote:
           | You only need to do it once if it's the first commit and you
           | make it empty...
        
       | zegl wrote:
       | I don't know how stupid this is on a scale from 1 to 10. I've
       | created a wrapper [1] for git (called "shit", for "short git")
       | that converts non-padded revisions to their padded counterpart.
       | 
       | Examples:
       | 
       | "shit show 14" gets converted to "git show 00000140"
       | 
       | "shit log 10..14" translates to "git log 00000100..00000140"
       | 
       | [1]: https://github.com/zegl/extremely-linear/blob/main/shit
        
         | couchand wrote:
         | Thank you for addressing my one and only concern with this
         | scheme! No notes.
        
         | informalo wrote:
         | Other customers also brew-installed: fuck [1]
         | 
         | [1]: https://github.com/nvbn/thefuck
        
         | thih9 wrote:
         | Why the trailing zero? The article quotes hashes starting with
         | "0000001", or "0000014".
         | 
         | Shouldn't "shit show 14" get converted to "git show 0000014"?
        
       | wirrbel wrote:
       | I think the sweet spot in Developer productivity was when we had
       | SVN repos and used git-svn on the client. Commits were all
       | rebased on git level prior to pushing. If you committed something
       | that broke unit tests your colleagues would pass you a really
       | ugly plush animal of shame that would sit on your desk until the
       | next coworker broke the build.
       | 
       | We performed code review with a projector in our office jointly
       | looking at diffs, or emacs.
       | 
       | Of course it's neat to have GitHub actions now and pull-requests
       | for asynchronous code review. But I learned so much from my
       | colleagues directly in that nowadays obscure working mode which I
       | am still grateful for.
        
         | sshine wrote:
         | > If you committed something that broke unit tests your
         | colleagues would pass you a really ugly plush animal of shame
         | that would sit on your desk until the next coworker broke the
         | build.
         | 
         | We did have an ugly plush animal, but it served more obscure
         | purposes. For blame of broken builds, we had an info screen
         | that counted the number of times a build had passed, and
         | displayed below the name of the person who last broke it.
         | 
         | Explaining to outsiders and non-developers that "Yes, when you
         | make a mistake in this department, we put the person's name on
         | the wall and don't take it down until someone else makes a
         | mistake" sounds so toxic. But it strangely enough wasn't so
         | harsh. Of course there was some stigma that you'd want to
         | avoid, but not to a degree of feeling prolonged shame.
        
           | cfuendev wrote:
           | No joke, a few weeks ago a colleague from university shared a
           | few anecdotes about his mentor-coworker-boss at work with me,
           | and it's similar. Every time they broke the production branch
           | and the boss had to change the code or pull out some AWS
           | magic to restore a database, he would give the fixed commits
           | names like "C _gada de [Employee Name] " which roughly
           | translates to "[Employee Name] F*_ed Up", since he knew they
           | wouldn't forget it that way.
           | 
           | It's specially cool given that he would always see his
           | employees' f*k-ups as learning opportunities. He would always
           | teach them what went wrong and how to fix it before shaming
           | them in the git history. He always told them he did it to
           | assure they wouldn't forget both the shameful f*k-up + the
           | bit of learning that came along with it. They always laugh it
           | off and understand the boss' intentions. It isn't harsh or
           | anything.
        
             | bornfreddy wrote:
             | Yes, it's all about context. Good intentions matter a lot
             | here.
             | 
             | Additionally, it keeps developers humble, because their
             | mistakes are in the codebase "forever".
             | 
             | That said, it is s fine line - things can easily get toxic
             | very quickly, so it's important that everyone sees it as a
             | (half serious) joke.
        
           | jonstewart wrote:
           | I once interviewed a junior-ish developer who told me that
           | his then-current team had a dunce cap to be worn by whomever
           | broke the build. I copied it immediately. There was no
           | toxicity, it was a good laugh, and as manager I wore it more
           | than once being a bit too liberal with my commits.
           | 
           | On another team I was on, in 2002 using CVS, we had an
           | upside-down solo cup as a base for a small plastic pirate
           | flag. If you were ready to commit, you grabbed the pirate
           | flag as a mutex on the CVS server. Of course, this turned
           | competitive... and piratical.
           | 
           | I despair about long-lived git feature branches and pull
           | requests. The pull request model is fine for open source
           | development, but it's been a move backwards for internal
           | development, from having a central trunk that a team commits
           | to several times a day. The compensating factors are git's
           | overall improvements (in speed and in principled approach to
           | being a content addressable filesystem) and all of the
           | fantastic improvements in linters and static analysis tools,
           | and in devops pipelines.
        
             | Sohcahtoa82 wrote:
             | > The pull request model is fine for open source
             | development, but it's been a move backwards for internal
             | development
             | 
             | The more paranoid would claim that requiring PRs that then
             | require approvals prevents a malicious engineer from adding
             | an obvious back door to the code.
             | 
             | You would hope you can trust your co-workers, but sometimes
             | a hack is an inside job.
        
               | jonstewart wrote:
               | There are all sorts of workflows that can be arranged to
               | prevent that while still having optimistic continuous
               | integration on trunk.
        
             | thunky wrote:
             | > I despair about long-lived git feature branches and pull
             | requests
             | 
             | This comes up a lot - multiple people on this thread have
             | even said that it's a bad idea to have a long running
             | feature branch.
             | 
             | This seems like a case of the tool imposing it's will on
             | workflows, rather than enabling them. Not all features are
             | tiny. I don't see anything wrong with a long lived branch
             | if the feature is in fact large. After all it may be
             | completely redesigned multiple times over before being
             | merged into the main branch. Or it may never make it.
             | 
             | And no I don't think it always works to break down a large
             | feature into smaller ones, because your course may change
             | as you go, and it's much easier not to have to revert
             | incremental features when it does.
             | 
             | But people are so worried about having a perfect history.
             | So they rebase. But if it's a long lived (shared) branch
             | you don't want to do that. So now what? A merge would be
             | ugly, can't do that. So now you've painted yourself in a
             | corner for no good reason.
        
               | mook wrote:
               | A long lived branch was a pain even in the CVS days. I'm
               | in particular thinking about the "aviary" branch (for
               | Phoenix/Thunderbird) Mozilla had for quite a while.
               | 
               | Of course tooling can make it harder -- there was no such
               | thing as rebasing on CVS.
        
               | geon wrote:
               | A long lived feature branch is not a problem if you
               | rebase it to master often. Move all refactoring to the
               | beginning of the branch and merge them to master if they
               | become too many.
        
               | thunky wrote:
               | > A long lived feature branch is not a problem if you
               | rebase it to master often.
               | 
               | Yes but if it's a shared branch then you may have
               | problems with this.
               | 
               | The safer way is to merge from master into the branch but
               | nobody wants to do that because it's ugly.
        
               | tcoff91 wrote:
               | For long-lived feature branches that are the target of
               | multiple smaller PRs, history should never be rewritten.
               | I call these branches integration branches. I agree with
               | you wholeheartedly that master should be merged into the
               | branch. It's also so much easier to resolve merge
               | conflicts all at once in the merge commit rather than
               | iteratively for each commit. Also, the information on how
               | merge conflicts are resolved is then preserved in the
               | merge commit. It's critical however that when you merge
               | the branch back into master, you use --no-ff. It gets
               | really confusing when you fast forward master to the
               | feature branch.
               | 
               | The solution for it being ugly is to look at
               | main/master's history with the --first-parent option.
               | This lets you cut through the noise and just see the true
               | history of the main branch. Without --first-parent, you
               | see a bunch of commits in the log that master was never
               | actually pointing at. This is why it's critical that you
               | use --no-ff when merging these 'integration' branches as
               | I call them. It's important that the integration branch
               | is the second parent of master.
        
               | thunky wrote:
               | I agree with you here.
               | 
               | But what you are describing still isn't good enough for a
               | lot of people, because even though `--first-parent` hides
               | the noise it's still there and just knowing there's a
               | mess under the rug is enough to be problematic.
               | 
               | I don't think it's really the fault of the tooling,
               | moreso with what is a common interpretation of what is a
               | mess and what isn't. If the github commit history allowed
               | you to show `--first-parent` maybe it would be less of a
               | problem.
        
               | tcoff91 wrote:
               | The github history view is garbage and people should stop
               | using it.
        
               | rocqua wrote:
               | Can one merge master into tye feature branch often, and
               | then interactive-rebase onto master removing all the
               | merges?
        
           | exabrial wrote:
           | we did something similar, but everyone knew it was a joke and
           | we all took turns with it. I guess we didn't take ourselves
           | as seriously
        
           | rfrey wrote:
           | It's not toxic because every single developer knows that it
           | could be them next time around.
        
             | voxl wrote:
             | It is literally the definition of toxic. It is the
             | antithesis of making it okay to fail, having the entire
             | team to take responsibility. Instead individual mistakes
             | are highlighted and publicly shamed. How can you possibly
             | not think this is toxic?
        
               | rfrey wrote:
               | What I meant is that we know, inside our blood cells,
               | that breaking the build can happen to anyone, and
               | probably will. The trophy is not public shaming, it's the
               | camaraderie that comes from shared humility.
               | 
               | You say to somebody downthread "remind me never to work
               | with you". I would find it difficult to work with someone
               | as hyper sensitive -- on other people's behalf, yet! --
               | as you seem to be in this thread.
        
               | Sohcahtoa82 wrote:
               | Think of it more as a fun and gentle ribbing than public
               | shaming.
        
               | daveguy wrote:
               | Sounds like the definition of making it okay to fail.
               | 
               | The only consequence is a plush toy of shame on your desk
               | until the next person fails? Yes, please.
               | 
               | Sounds like a great way to lighten the mood about
               | failure.
        
               | voxl wrote:
               | Uh no, and please never work with me. The definition of
               | "making it okay to fail" is a pat on the back and a
               | retrospective to figure out what went wrong and prevent
               | it from happening again.
        
               | HWR_14 wrote:
               | Toxic is not the highlighting of breaking the build with
               | a trophy, it's what gets associated with it.
               | 
               | Imagine an "ugliest shirt" trophy, given out to whoever
               | wheres the ugliest shirt of the week. At a fashion
               | magazine, this may be toxic shaming. At a tech-heavy
               | startup it might have people start buying the worst
               | shirts they can to try to win it.
               | 
               | If the attitude associated with getting the trophy is
               | condemnation, that's bad. If it's a reminder that
               | everyone fucks and be careful, that's fine.
        
               | bthater wrote:
               | Oof that hits a sore spot. I was the 2016 Winner of the
               | Ugliest Shirts Award at one of the first technology
               | companies I worked at. Being singled out in front of all
               | your peers for poor fashion sense and then the ensuing
               | obligatory laugh ruined my opinion of that company's
               | leadership. I would strongly encourage anyone in a
               | professional environment (especially those in leadership
               | roles) to keep comments on appearance to yourself.
        
               | HWR_14 wrote:
               | I'm sorry to remind you of a bad time. I would like to
               | point out that "2016 Ugliest Shirts" is a pretty
               | different concept from "Person who wore the ugliest shirt
               | this week" with a picture of you in a ratty beloved tee.
               | It sounds like those were year end remarks, which means
               | instead of judging an act they were judging your long
               | term taste. Also it implies the most memorable thing
               | about you was your shirt choice. And lastly, you weren't
               | anticipating it, so you found out everyone was secretly
               | judging you on something.
               | 
               | If, during orientation you were told a trophy gets given
               | out every week for it, and some people wear really ugly
               | shirts each Friday to try to win it, it would have felt
               | very different.
               | 
               | But yeah, year end humorous awards like that probably
               | belong confined to episodes of The Office.
        
           | com2kid wrote:
           | Thankfully modern development practices should ideally run
           | tests before commiting, the build should never be broken.
           | 
           | With good infra, everything from unit tests to integration to
           | acceptable tests get ran before code hits main.
           | 
           | The only excuse for builds breaking nowdays. is insufficient
           | automated safeguards.
        
             | wirrbel wrote:
             | Our whole practice revolved around not pushing broken code
             | because all code was tested locally prior to the push. In
             | fact we practiced continuous integration as in its original
             | meaning, integrating code multiple times per day. Releases
             | were performed from a release branch so the occasional
             | hiccup wasn't worse than let's say a PR that does not
             | build. However fixing the broken build was the TOP priority
             | if it happens (like every two months)
        
         | couchand wrote:
         | I have my old team's rubber chicken and I'm never giving it up.
         | 
         | In-person code review is the only way to do it. Pull requests
         | optimize for the wrong part of code review, so now everyone
         | thinks it's supposed to be a quality gate.
        
           | wirrbel wrote:
           | Yep. It makes a lot of sense for open source where gate
           | keeping makes sense (to reduce feature bloat, back doors and
           | an inflated API surface that needs to be maintained almost
           | indefinitely).
           | 
           | Most corporate code bases are written by a smallish team
           | operating under tight time constraints so most contributions
           | are actually improving on the current state of the code base.
           | Then PRs delay the integration, and lead to all kinds of
           | follow up activities in keeping PR associated problems at
           | bay. For example the hours wasted by my team in using stacked
           | PRs to separate Boy Scout rule changes to the code from the
           | feature is just abnormal.
        
         | titzer wrote:
         | Commit queues are so far superior to shaming broken builds that
         | I think it's only nostalgia that makes you miss it.
        
           | thewebcount wrote:
           | Absolutely. In my experience, it's only "not toxic" to a few
           | people, and for most others it is toxic, but the people who
           | like it won't ever be able to see that.
        
             | wkdneidbwf wrote:
             | exactly. even if the current team is cool with it, team+1
             | may not be, and now they're in a position that feels shitty
             | to them. it's good 'ole boys club shit.
             | 
             | people brag about their dunce caps, "john's fault" commit
             | messages from managers, and other forms of public shame as
             | a badge of honor when it would be so much more interesting
             | to here about how they fixed their broken processes that
             | led to the problems in the first place.
             | 
             | "oops, a developer fucked up the prod db" says more about
             | the org and its processes than it does about the developer.
        
             | wirrbel wrote:
             | For the record: I am not recommending people to adapt a
             | toxic culture.
             | 
             | What I would like people to take away from these
             | discussions is the curiosity to question established
             | practices and processes and re-evaluate the cost-benefit
             | ratio of process steps just like the manufacturing people I
             | write software for continue to optimize their working mode
             | again and again
        
           | [deleted]
        
         | flir wrote:
         | Two years from peak Covid, and the plushies are the object of
         | nostalgia.
        
         | unnah wrote:
         | Next step: a svn-git proxy that allows one to use a subversion
         | client with a remote git repository.
        
         | newswasboring wrote:
         | I am literally in the middle of trying to convince my group
         | from moving away from all this. Would you recommend going back
         | to this system?
        
           | wirrbel wrote:
           | In this case I reminisced about the toolset but the work flow
           | is what brought the value so I advise of course against using
           | subversion.
           | 
           | Look up trunk based development and read the continuous
           | integration book published by Addison Wesley (Is it the hez
           | humble book or the Duvall book I always confuse the authors,
           | both books are great though).
           | 
           | The hard part will be to convince people of exploring a
           | different way working mode AND to learn that what is proposed
           | is not an anarchist style of development but a development
           | model that optimizes on efficiency
        
         | tomtom1337 wrote:
         | This (plush toy and projector) has "feel good" all over it :)
        
       | jordigh wrote:
       | Mercurial always has had sequential revision numbers in addition
       | to hashes for every commit.
       | 
       | They aren't perfect, of course. All they indicate is in which
       | order the current clone of the repo saw the commits. So two
       | clones could pull the commits in different order and each clone
       | could have different revision numbers for the same commits.
       | 
       | But they're still so fantastically useful. Even with their
       | imperfections, you know that commit 500 cannot be a parent of
       | commit 499. When looking at blame logs (annotate logs), you can
       | be pretty sure that commit 200 happened some years before commit
       | 40520. Plus, if you repo isn't big (and most repos on Github are
       | not that big by numbers of commits), your revision numbers are
       | smaller than even short git hashes, so they're easier to type in
       | the CLI.
        
         | silvestrov wrote:
         | Seems like a design fault in git that commits only have a
         | single id (sha1 hash) and that hashes are written without any
         | prefix indicating which type of id it is.
         | 
         | If all hashes were prefixed with "h", it would have been so
         | simple to add another (secure) hash and a serial number.
         | 
         | E.g. h123456 for the sha1, k6543 for sha256 and n100 for the
         | commit number.
        
       | unnouinceput wrote:
       | Extremely Linear Git History...also known as SVN. Guess
       | reinventing the wheel does get you to top HN.
        
         | oneeyedpigeon wrote:
         | This is _Hacker_ News. You could add this as a canonical
         | example in the FAQ as far as I 'm concerned.
        
         | adql wrote:
         | You need to do it badly and wastefully.
        
           | zegl wrote:
           | Using SVN doesn't cause your computer to heat up. ;-)
        
             | adql wrote:
             | Just someone's else computer
        
         | mgsk wrote:
         | Are you allergic to fun? :(
        
       | tambourine_man wrote:
       | The fact that we use a hash as the main way to interact with
       | commits shows how bad git interface is. Sure, you should be able
       | to easily check the sha anytime, but expose the plumbing to end
       | users on almost any interaction is mad. We just got used to it.
        
       | Ayesh wrote:
       | I wonder if Git provides a pluggable hashing mechanism as part of
       | SHA2 migration.
       | 
       | I imagine stuff like this and SVN to Git mirroring to work nicely
       | with identical hashes.
        
         | masklinn wrote:
         | Not currently, it's a repo-level flag and you get one or the
         | other.
         | 
         | It'll undoubtedly be easier to further expand, but it's nowhere
         | near pluggable.
        
       | conaclos wrote:
       | Another approach could be to use prefixes. A 0 could separate the
       | prefix (fixed hash part) from the suffix (random part).
       | 0<suffix>       10<suffix>       20<suffix>       ...
       | 
       | Combined with auto-completion, you preserve the main advantage
       | (ordering) and you are able to quickly compute the hash.
        
       | kzrdude wrote:
       | Clever and tempting. I would maybe like to use a smaller prefix
       | but ensure a 0 suffix to the number too, to make it easy to read
       | anyway. Like 00010bad, 00020fed, 00030be1, etc..
       | 
       | Wraparound doesn't really matter, as long as it's spaced long
       | apart.
        
       | alvis wrote:
       | It look appealing from a perfectionist point of view.
       | 
       | But! How can I collaborate with my team when PR merges are
       | inevitable? O:
        
       | zomglings wrote:
       | Is it possible to change the checksum implementation that git
       | uses, through configuration or a plugin?
       | 
       | I find all this hash inverting quite inelegant.
        
         | yjftsjthsd-h wrote:
         | There's an effort to add support for sha256, but it's... not
         | recommended https://lwn.net/Articles/898522/
        
       | shadytrees wrote:
       | There's a memorable Stripe CTF from 2014 that had something
       | similar (Gitcoins). This brought back fond memories of that.
        
       | malkia wrote:
       | Hail p4, g4, svn and blessed be their monotonically increasing
       | revision number!
        
         | cerved wrote:
         | All hail centralized version control, make life slow again!
        
           | charcircuit wrote:
           | Decentralized version control is slower than centralized
           | version control since it requires downloading and working
           | with the entire repository.
        
       | mihaaly wrote:
       | Sounds great for a single person project but perhaps a simpler
       | VCS was better then?
        
       | lloydatkinson wrote:
       | I am confused. Why not use git tags for versioning?
        
       | Pirate-of-SV wrote:
       | Very good! I use this hack every day in winter to heat my
       | apartment (charging laptop at work, run git brute force at home).
        
       | hiergiltdiestfu wrote:
       | wtf, back to SVN :D
       | 
       | I honestly expected this to be from another "really cool date" -
       | April 1st :D
        
       | JoachimS wrote:
       | A neat trick with this tool is to generate a commit message that
       | corresponds to a given issue number. It could almost be useful.
       | 
       | Kudos to @zegl for this cool project.
        
         | mjochim wrote:
         | > It could almost be useful.
         | 
         | I'm still pondering the "almost" ;-).
        
       | HextenAndy wrote:
       | Wait until you see subversion :)
        
         | breck wrote:
         | Two steps forward one step back. So it goes.
        
       | joosters wrote:
       | Just like perforce and its "p4 changes" command. I like the
       | simplicity.
        
       | pcthrowaway wrote:
       | I mean.. this kind of breaks down if you have more than one
       | person on the team
        
         | globular-toast wrote:
         | It just means you have to coordinate more. Or just have one
         | person in charge of the master branch. I don't think the post
         | is supposed to be taken so seriously, though.
        
           | Zoadian wrote:
           | which just means: lets waste many hours coordinating, for the
           | benefit of having a 'nice looking' history.
        
             | eru wrote:
             | You realise that this is a joke project?
        
               | chrismorgan wrote:
               | I would not call this a joke project. It's a fun and
               | optional sort of a thing, but there's no reason why you
               | shouldn't take it seriously, provided your approach to
               | work makes it compatible.
        
             | breck wrote:
             | Commit once read forever
        
       | breck wrote:
       | This is absolutely genius. Would be nice to upstream it and make
       | it fast. I would start using it.
        
       | johmue wrote:
       | this is a joke right?
        
       | kinduff wrote:
       | See also Lucky Commit [0], which uses various types of whitespace
       | characters instead of a hash inside the commit, which makes it
       | look more magical.
       | 
       | I wonder about performance, though. Why is the author's method
       | slower than the package I linked?
       | 
       | [0]: https://github.com/not-an-aardvark/lucky-commit
        
         | zegl wrote:
         | Thanks for sharing, this is really cool! Using whitespace is a
         | really clever trick, and running on the GPU makes it even more
         | impressive.
         | 
         | I've been using githashcrash [1], but it's only running on the
         | CPU, which is why it's a bit slower. :-)
         | 
         | [1]: https://github.com/Mattias-/githashcrash
        
           | zegl wrote:
           | Update: git-linearize now uses lucky_commit as it's backend!
        
             | kretaceous wrote:
             | I haven't checked your codebase so I don't know how easy it
             | was but damn, you replaced your backend within 16 minutes
             | according to your comment timings.
             | 
             | That's some nice modularization. Good job!
        
               | zegl wrote:
               | You're giving me too much credit. The script [1] is only
               | 50 lines of bash.
               | 
               | [1]: https://github.com/zegl/extremely-
               | linear/blob/0011003da13132...
        
           | oneeyedpigeon wrote:
           | Using whitespace is cool, but you know what would be _really_
           | cool? Using a thesaurus to reword the commit message until it
           | matches the hash :)
        
             | koliber wrote:
             | ... or refactor the code using an automated thesaurus and a
             | bit of AI in a way to generate a particular hash.
             | 
             | - Hey Bob, why did you rename the 'pick_person' function to
             | 'choose_desirable_candidate'?
             | 
             | - git made me do it
        
               | hoosieree wrote:
               | I was going to solve some business problems today but
               | instead there became an urgent need to GPU accelerate the
               | task of making my commit hash appear to have the rich
               | semantics of "a number that goes up". Hm, I bet this old
               | FPGA could be repurposed to add a 2x speedup...
        
             | whoooooo123 wrote:
             | Only works if your commit message is written in hexadecimal
             | characters
        
               | Biganon wrote:
               | "it" (in "it matches the hash") = "the next sequential
               | number", not "the commit message", afaict. Not very
               | clear, I agree.
        
               | oneeyedpigeon wrote:
               | I don't understand -- the example in the article adds the
               | string "magic: MTQIpN2AmwQA" to the commit message. The
               | final hash is hexadecimal, but what you feed into it
               | isn't.
        
             | lelandfe wrote:
             | "Indubitably overhaul insect"
        
         | masklinn wrote:
         | Git also support extra headers in commits. Interesting that
         | neither went with that.
        
           | jwilk wrote:
           | What do you mean by "extra headers"?
        
             | masklinn wrote:
             | Exactly what the name says.
             | 
             | A git commit is composed of a number of headers (key: value
             | fields) and a commit message.
             | 
             | There is a set of "standard headers" (tree, parent*,
             | author, committer, encoding?), but then you can add more.
             | In fact there's a set of semi-standard headers, as in
             | headers git itself will add under some conditions: `gpgsig`
             | and `gpgsig-sha256` if the commit is signed, and I think
             | `mergetag` for signed tags. They are documented as part of
             | the signature format but they're not "baseline" features:
             | https://git-scm.com/docs/signature-
             | format#_commit_signatures
             | 
             | But because of this, a git client should support arbitrary
             | commit headers, and round-trip them even if it does not
             | expose them.
        
       | cranium wrote:
       | Now, merge only the next-in-line hashes and the contributions to
       | your repo can reach Cloud Scale(tm). Harness the ultimate power
       | of distributed intelligent agents to create the future, backed by
       | strong mathematical foundations and an ecosystem of innovative
       | technologies. Just at your fingertips
        
       | otikik wrote:
       | This is horrible and I like it.
        
       | blux wrote:
       | I fail to see the point of this, in fact, I think this is a
       | fundamentally flawed approach to dealing with your revision
       | history. The problem is that rebasing commits has the potential
       | of screwing up the integrity of your commit history.
       | 
       | How are you going to deal with non-trivial feature branches that
       | need to be integrated into master? Squash them and commit? Good
       | luck when you need to git bisect an issue. Or rebase and
       | potentially screwing up the integrity of the unit test results in
       | the rebased branch? Both sound unappealing to me.
       | 
       | The problem is not a history with a lot of branches in it, it is
       | in not knowing how to use your tools to present a view on that
       | history you are interested in and is easy for you to understand.
        
         | thewebcount wrote:
         | > The problem is not a history with a lot of branches in it, it
         | is in not knowing how to use your tools to present a view on
         | that history you are interested in and is easy for you to
         | understand.
         | 
         | To me this is like saying to a construction worker: "The
         | problem is not that your hammer has sharp spikes coming out of
         | the handle at every angle. The problem is that you don't put on
         | a chain mail glove when using it." That's certainly one way to
         | look at it.
        
         | tasuki wrote:
         | > I fail to see the point of this
         | 
         | I'm pretty sure the point is that this is a one-person project
         | and the author can play around. He's not suggesting your team
         | of 100 people to adopt this for the development of your
         | commercial product.
        
         | tcoff91 wrote:
         | If people knew about --first-parent everyone could stop
         | complaining about merge commits in the history.
        
         | michaelmior wrote:
         | This somewhat depends on how big your features are. Arguably,
         | large long-lived feature branches are the problem themselves.
         | If larger features are broken down and developed/merged
         | piecemeal, then you still have smaller commits you can fall
         | back on.
         | 
         | IIRC, GitHub uses a development model where partially
         | implemented features are actually deployed to production, but
         | hidden behind feature flags.
        
         | diekhans wrote:
         | It is amazing how much time projects seem to spend on rewriting
         | history for the goal of displaying in in a pretty way. Leaving
         | history intact and having better ways to display it seems far
         | saner. Even after a merge, history in the branch maybe useful
         | for bisect, etc.
        
         | boxed wrote:
         | It's a joke. The swooshing sound you heard was it going past
         | you.
        
       | shawabawa3 wrote:
       | Sadly if you use commit signing it's unfeasibly slow to do this
       | :(
        
         | imiric wrote:
         | You think signing is what makes this unfeasibly slow? :)
        
         | mkj wrote:
         | It shouldn't be, won't the signature be made after the hash
         | brute force is finished?
        
       | chrismorgan wrote:
       | The article talks about _eight_ -character prefixes later in the
       | article, but Git short refs actually use _seven_ -character
       | prefixes when there is no collision on that (and that's what's
       | shown earlier in the article). So you can divide time by 16.
       | 
       | For me on a Ryzen 5800HS laptop, lucky_commit generally takes
       | 11-12 seconds. I'm fine with spending that much per commit when
       | publishing. The three minutes eight-character prefixes would
       | require, not quite so much.
        
         | avar wrote:
         | Git hasn't used "seven-character prefixes when there are no
         | collisions" in a long time.
         | 
         | It's a combination of the "repo size" (as in, estimated number
         | of objects) and a hard floor of seven characters.
         | 
         | You can see this by running "git log --oneline=7" on any non-
         | trivially sized repository (e.g. linux.git). There's plenty of
         | hashes that uniquely abbreviate to 7 characters, but they're
         | currently all shown with 12 by default.
        
           | chrismorgan wrote:
           | There may be some _extra_ trigger that causes it to go beyond
           | seven for everything, I don't know (never worked on a
           | repository anywhere near that large), but there's certainly
           | still at least _some_ form of collision logic in there (and
           | this is why I said what I said, because I've used
           | lucky_commit enough to experience it):                 $ git
           | init x       Initialized empty Git repository in /tmp/x/.git/
           | $ cd x            $ git commit --allow-empty -m one
           | [master (root-commit) 4144321] one            $ git log
           | --oneline       4144321 (HEAD -> master) one            $
           | lucky_commit            $ git log --oneline       0000000
           | (HEAD -> master) one            $ git commit --amend --no-
           | edit --reset-author --allow-empty       [master 3430e13] one
           | $ git log --oneline       3430e13 (HEAD -> master) one
           | $ lucky_commit            $ git log --oneline       0000000f
           | (HEAD -> master) one            $ git reflog --oneline
           | 0000000f (HEAD -> master) HEAD@{0}: amend with lucky_commit
           | 3430e13 HEAD@{1}: commit (amend): one       00000005
           | HEAD@{2}: amend with lucky_commit       4144321 HEAD@{3}:
           | commit (initial): one            $ git reflog expire
           | --expire=now --all            $ git reflog --oneline
           | $ git log --oneline       0000000f (HEAD -> master) one
           | $ git gc --aggressive --prune=now       Enumerating objects:
           | 2, done.       Counting objects: 100% (2/2), done.
           | Writing objects: 100% (2/2), done.       Total 2 (delta 0),
           | reused 0 (delta 0), pack-reused 0            $ git log
           | --oneline       0000000 (HEAD -> master) one
        
             | avar wrote:
             | Yes, there's _also_ a collision check, but it 's not
             | truncating to 7 characters and adding as needed to get past
             | collisions. Rather it's truncating to N and then adding as
             | needed. N=7 for a new repository, but it'll relatively
             | quickly bump that to 8, then 9 etc
             | 
             | You don't need a very large repository to start bumping it
             | up to 8 etc. E.g. my local redis.git is 9, some local few-
             | thousand commit (partially automated) that I've only ever
             | added to are at 8 etc.
             | 
             | This changed in v2.11 released in late 2016[1], but because
             | the observable default on a new repository is 7 the "it's 7
             | unless collisions" has persisted in various places online.
             | 
             | All of which is to say that if you brute-force the first
             | commit to be 0000001..., it'll start being displayed as
             | <that><x>, where <x> is a random 0..9a..f character, unless
             | you brute force to 8, 9 etc.
             | 
             | 1. https://github.com/git/git/commit/e6c587c733b4634030b353
             | f402...
        
         | zegl wrote:
         | I left some details out of the post to make it shorter.
         | 
         | What I'm actually is doing is generating a 7-digit incremental
         | number followed by a fixed 0. Some UIs show 7 characters and
         | some show 8, this felt like a nice compromise. Plus it's easier
         | to distinguish between the prefix and the suffix when looking
         | at the full SHA when they are always separated by a 0.
        
       | [deleted]
        
       | ccbccccbbcccbb wrote:
       | <sarcasm> But what's the carbon footprint and contributed sea
       | level rise of this frivolity? </sarcasm>
        
         | housel wrote:
         | This is a serious criticism... even if it's not likely to catch
         | on enough to have a real effect on the sea level, it is a
         | complete waste of energy to accomplish something that could be
         | done much more efficiently some other way, if it is indeed
         | worth doing at all.
        
       | codeulike wrote:
       | So this is for if you want to use Git as if its Subversion?
        
       | jbergstroem wrote:
       | The Webkit project would love this. Can't help but feel that half
       | the reason they spent all the extra effort with subversion was
       | user-friendly commit revisions.
        
       | sagebird wrote:
       | " So we only have one option: testing many combinations of junk
       | data until we can find one that passes our criteria. "
       | 
       | I have a somewhat related interest of trying to find sentences
       | that have low Sha256 sums.
       | 
       | I made a go client that searches for low hash sentences and
       | uploads winners to a scoreboard I put up at https://lowhash.com
       | 
       | I am not knowledgeable about gpu methods or crypto mining in
       | general, I just tried to optimize a cpu based method. Someone who
       | knows what they are doing could quickly beat out all the
       | sentences there.
        
       | oneeyedpigeon wrote:
       | I bet I wasn't the first person who thought this would have to be
       | done by modifying actual file content -- e.g. a dummy comment or
       | something. That would clearly have been horrible, but the fact
       | that git bases the checksum off the commit message is...
       | surprising and fortunate, in this case!
        
         | entropy_ wrote:
         | It's a hash of everything that goes into a commit, including
         | the commit message. The idea is that nothing that makes up a
         | commit can change without changing the hash.
        
           | mjochim wrote:
           | > It's a hash of everything that goes into a commit,
           | including the commit message
           | 
           | ... and, very notably, the hash of the parent commit. That is
           | also part of the commit, which means that changing a parent
           | commit would also imply changing the hashes of all later
           | commits. This is sort of the whole point of git/version
           | control.
        
             | Biganon wrote:
             | This might be a stupid question, but does anyone call git
             | history a blockchain, then? A centralized blockchain,
             | without proof of work or proof of anything really of
             | course, but still, it sounds like the basic blockchain idea
             | is there
        
             | ludwigvan wrote:
             | Poor man's blockchain it is, then :)
        
         | belinder wrote:
         | I feel like it would be better to have some dummy file in your
         | repo that the tool modifies than mucking up your commit
         | messages
        
       | Semaphor wrote:
       | > Full collision (entire hash is zeros, then 000...1, etc.) --
       | `git linearize --format "%040d"` (takes ~1033 years to run per
       | commit)
       | 
       | Hah :D
        
       | low_tech_punk wrote:
       | Extremely effective way to waste electricity and emit CO2.
        
       | ChrisMarshallNY wrote:
       | I find tags to be a fairly useful way of providing a linear
       | progression, but I guess that's no fun.
       | 
       |  _> but it can also mean to only allow merges in one direction,
       | from feature branches into main, never the other way around. It
       | kind of depends on the project._
       | 
       | That sounds like the Mainline Model, championed by Perforce[0].
       | It's actually fairly sensible.
       | 
       | [0] https://www.perforce.com/video-tutorials/vcs/mainline-
       | model-...
        
         | actuallyalys wrote:
         | Yeah, I think tags are a more practical way of accomplishing
         | this. If you're really interested in having a linear history,
         | it might also make sense to switch to an alternative. Mercurial
         | has linear version numbers and can even push to Git
         | repositories.
         | 
         | At risk of coming across as a humorless Hacker News commenter,
         | I will add that I enjoyed this post. It's a neat hack!
        
           | ChrisMarshallNY wrote:
           | Yes, it is a cool hack. I enjoy these, even if I can't find a
           | practical application.
        
       ___________________________________________________________________
       (page generated 2022-11-22 23:00 UTC)