|
| 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 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 10 20 ...
|
| 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
| , where 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:
| But what's the carbon footprint and contributed sea
| level rise of this frivolity?
| 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) |