Git's getting in my way again
-
At the moment, that PR has three merge commits which I'd like to get rid of. Presumably, I can do that by rebasing/reparenting commit 736221a onto commit 8560685 instead of commit 121d4d3, and remove the merge commits entirely. Question is, what's the magic incantation(s) to do so?
-
Maybe
git rebase -i HEAD~4
?It's interactive so you can just try it out.
-
@grunnen I had a look at that, but it wasn't going to rebase into the right place.
-
I've looked at the documentation for the commands I think are the right ones to use, and... I just ended up with even less clue than before.
I might just nuke the whole thing and start again.
-
@raceprouk said in Git's getting in my way again:
I might just nuke the whole thing and start again.
Fuck it, I'm nuking and starting over. It's only one image.
-
You've already merged the other branch in, so a rebase won't work as you're on top of the other branch. Plus, rebasing will wipe out whatever merge conflict resolution you've already done, so don't do that.
What you can do is take the state of your latest merge commit, diff it against origin's tip, and create a new commit using the diff.
Assuming the branch you want to merge into is
master
and your branch israceprouk/master
git checkout master git diff --full-index --binary master raceprouk/master | git apply git add -A # Or specify which files you need git commit
Then just copy the old commit message across and you're done
-
@raceprouk said in Git's getting in my way again:
I might just nuke the whole thing and start again.
-
@cark There are other ways of doing it.
In particular, soft resets and writing (full) commit IDs to the right places can let you do some really funky stuff (which can be necessary when you've had to bring a branch up to date in stages due to complex conflicts).
-
The solution is to just never ever ever merge and always rebase.
-
@jazzyjosh said in Git's getting in my way again:
The solution is to just never ever ever merge and always rebase.
Doesn't help when making a PR to someone else's repo.
-
You just add their repo as a remote and do a
git pull --rebase <remote name> <branch your PR is going to be merged into>
-
-
I'm not smart enough to understand Git.
I consider this to be a failing of Git.
This is also one of the reasons I still work for WtfCorp - if I go anywhere else I'll probably have to use Git.
-
@weng said in Git's getting in my way again:
I'm not smart enough to understand Git.
Me neither.
Like for example, the "never merge, always rebase" advice-- isn't "rebasing" just telling Git "oh BTW I'm working on a different branch now, but don't bother actually checking whether the current files on disk match that new branch or not"? Because if so that advice seems horribly dangerous.
But maybe I just misunderstand what "rebase" does.
-
Join the Church of Source Control History Preservation and don't worry about it!
-
@mikehurley said in Git's getting in my way again:
Join the Church of Source Control History Preservation and don't worry about it!
If you want to preserve history, then it's "never rebase, always merge" which is what I do.
YMMV.
-
@heterodox said in Git's getting in my way again:
never rebase, always merge
When you're working on changes in a separate branch for a while, before you merge it, if the branch you forked from was updated, you can/should rebase your your branch before merging it.
That's the main usage of rebase I see.
-
@timebandit said in Git's getting in my way again:
@heterodox said in Git's getting in my way again:
never rebase, always merge
When you're working on changes in a separate branch for a while, before you merge it, if the branch you forked from was updated, you can/should rebase your your branch before merging it.
That's the main usage of rebase I see.
I would just merge into my working branch.
-
@mikehurley said in Git's getting in my way again:
I would just merge into my working branch.
When you rebase, what happen is basically this:
- All your changes are undone
- All changes done on the original branch since you forked are applied to your branch
- All your changes are re-applied
That makes a cleaner history
-
Why doesn't WTDWTF come up with their own source control software?
-
@pie_flavor said in Git's getting in my way again:
Why doesn't WTDWTF come up with their own source control software?
Do you seriously want
file1.ext
,file1real.ext
in
proj1.zip
,realproj.zip
stored in git.
All of git's files stored in svn.
etc.
I'm sure we could come up with a "wonderful" system...
-
@dcon said in Git's getting in my way again:
@pie_flavor said in Git's getting in my way again:
Why doesn't WTDWTF come up with their own source control software?
Do you seriously want
file1.ext
,file1real.ext
in
proj1.zip
,realproj.zip
stored in git.
All of git's files stored in svn.
etc.
I'm sure we could come up with a "wonderful" system...The configuration file is probably XML and parsed via regex.
-
@pie_flavor said in Git's getting in my way again:
@dcon said in Git's getting in my way again:
@pie_flavor said in Git's getting in my way again:
Why doesn't WTDWTF come up with their own source control software?
Do you seriously want
file1.ext
,file1real.ext
in
proj1.zip
,realproj.zip
stored in git.
All of git's files stored in svn.
etc.
I'm sure we could come up with a "wonderful" system...The configuration file is probably XML and parsed via regex.
And the metadata stored in an oracle database?
-
@pleegwat said in Git's getting in my way again:
@pie_flavor said in Git's getting in my way again:
@dcon said in Git's getting in my way again:
@pie_flavor said in Git's getting in my way again:
Why doesn't WTDWTF come up with their own source control software?
Do you seriously want
file1.ext
,file1real.ext
in
proj1.zip
,realproj.zip
stored in git.
All of git's files stored in svn.
etc.
I'm sure we could come up with a "wonderful" system...The configuration file is probably XML and parsed via regex.
And the metadata stored in an oracle database?
#[cfg(windows)] panic!();
-
@pleegwat said in Git's getting in my way again:
@pie_flavor said in Git's getting in my way again:
@dcon said in Git's getting in my way again:
@pie_flavor said in Git's getting in my way again:
Why doesn't WTDWTF come up with their own source control software?
Do you seriously want
file1.ext
,file1real.ext
in
proj1.zip
,realproj.zip
stored in git.
All of git's files stored in svn.
etc.
I'm sure we could come up with a "wonderful" system...The configuration file is probably XML and parsed via regex.
And the metadata stored in an oracle database?
Nah - put it in sqlite. And check that file into git.
-
@timebandit said in Git's getting in my way again:
That makes a cleaner history
"clean" and "dirty" are not words that should be applied to engineering problems.
Is your method better than doing a merge? For reasons other than aesthetics?
-
@dcon said in Git's getting in my way again:
@pleegwat said in Git's getting in my way again:
@pie_flavor said in Git's getting in my way again:
@dcon said in Git's getting in my way again:
@pie_flavor said in Git's getting in my way again:
Why doesn't WTDWTF come up with their own source control software?
Do you seriously want
file1.ext
,file1real.ext
in
proj1.zip
,realproj.zip
stored in git.
All of git's files stored in svn.
etc.
I'm sure we could come up with a "wonderful" system...The configuration file is probably XML and parsed via regex.
And the metadata stored in an oracle database?
Nah - put it in sqlite. And check that file into git.
Stored in an Oracle NoSQL database. Then save it to disk as another XML file via regex.
-
@blakeyrat This explains it better than I could
-
@timebandit Git help from the people who brought you SourceTree?
No thanks, I want to talk to HUMAN BEINGS.
-
@blakeyrat said in Git's getting in my way again:
Is your method better than doing a merge? For reasons other than aesthetics?
Yes. By rebasing instead of using merge commits you should be able to run a successful build on every single commit. With merge commits, you can end up with broken code between where code diverged and where the merge commit is.
-
@jazzyjosh said in Git's getting in my way again:
Yes. By rebasing instead of using merge commits you should be able to run a successful build on every single commit.
Which is desirable because...?
-
@blakeyrat said in Git's getting in my way again:
@jazzyjosh said in Git's getting in my way again:
Yes. By rebasing instead of using merge commits you should be able to run a successful build on every single commit.
Which is desirable because...?
You don't get triggered because something is broken ever?
-
@blakeyrat said in Git's getting in my way again:
@jazzyjosh said in Git's getting in my way again:
Yes. By rebasing instead of using merge commits you should be able to run a successful build on every single commit.
Which is desirable because...?
TIL having a broken build is desirable.
-
@blakeyrat said in Git's getting in my way again:
Like for example, the "never merge, always rebase" advice
It's tabs versus spaces. I'm a person who goes with always merge, never rebase. You can do whatever you want, but if you're contributing, you follow the repo guidelines.
-
@jazzyjosh said in Git's getting in my way again:
TIL having a broken build is desirable.
I don't see any point of caring whether the build on a non-finished branch is broken or not, which is the topic we were actually talking about.
Obviously the build needs to be up and running by the time you create a pull request and get a code review.
-
@blakeyrat I personally like to ensure that every commit compiles so that I can use
git bisect
to easily figure out which commit (and therefore which code) introduced a bug. Of course that depends on how you develop - if you just commit broken WIP code and then squash it all into a single working commit at the end, there's less of a point.@jazzyjosh said in Git's getting in my way again:
With merge commits, you can end up with broken code between where code diverged and where the merge commit is.
I don't see how, unless you're blindly merging without testing and fixing the code during the merge. Just use
git merge --no-commit
and then test it before concluding the merge, fixing any problems. That's what merge commits are there for.
-
@lb_ said in Git's getting in my way again:
I personally like to ensure that every commit compiles so that I can use git bisect to easily figure out which commit (and therefore which code) introduced a bug.
I would like that too, but since Git has no way of storing stashes on the server, alas, I frequently end up having to commit in-process code. But we've all had that discussion before.
@lb_ said in Git's getting in my way again:
Of course that depends on how you develop - if you just commit broken WIP code and then squash it all into a single working commit at the end, there's less of a point.
I commit broken WIP code, because Git doesn't provide me the tools I need to avoid doing that. I don't "squash" however because there's only one GUI tool I know of which allows it, and its usability is utter garbage.
-
@blakeyrat yeah I agree with you on that - sorry if it sounded like I was suggesting that committing broken WIP code was bad. I just meant it's a different style of development.
-
@lb_ I still don't get the
git bisect
argument. That command works whether or not the changes it found build, right? What's the relationship betweengit bisect
and having to have every single commit, even those no feature branches, build?
-
@blakeyrat How do you know if a commit introduced a bug if it doesn't build? You can look on either side of it and figure it out with some extra reasoning, but I like to reduce the amount of detective work I have to do to find the code responsible.
-
@blakeyrat said in Git's getting in my way again:
@weng said in Git's getting in my way again:
I'm not smart enough to understand Git.
Me neither.
Like for example, the "never merge, always rebase" advice-- isn't "rebasing" just telling Git "oh BTW I'm working on a different branch now, but don't bother actually checking whether the current files on disk match that new branch or not"? Because if so that advice seems horribly dangerous.
But maybe I just misunderstand what "rebase" does.
Note that the following might be confusing when saying things about "source" and "target branches", a visual approach might be better but I can't be bothered.
One way to think of it is that a (simple) rebase takes a bunch of commits / changes from a source branch, grabs the sources from the target branch, tries to apply each of the changes in turn after it runs "resolve conflicts" so that it can create a new commit for each source commit without linking back to the source branch like a merge would do. Since I generally do an "interactive" rebase I cannot remember if the regular rebase stops if it detects a conflict, but when it does you can always choose to resolve the conflict and continue, or abort and roll back your current branch to the state it was before you started the rebase.
Meanwhile a merge takes a look at the latest state of the repo in the source branch, compares it to the state in the target branch, runs a diff and then tries to resolve conflicts between those latest states while creating a commit which has two commits as parent. Since it only looks at the state of the repo in the latest commits of the branch, the merge might be harder to resolve than had it been done with smaller changes like a rebase does.
If you want to compare the safety of these operations to other VC systems, keep in mind that in TFVC or Subversion you can have pending changes which actually get "rebased" if you run Get Latest Version - the original checkin which you based your changes on is now no longer known (not unless you wrote it down). Even if you have no TFVC conflicts, checking in your changes might still cause compiler failures if it turns out that some other co-worker changed a file you depend on, so while this system keeps a simple linear history there is still no guarantee that everything keeps operating once a checkin happens. Git's rebase is thus not inherently crazier than working with TFVC or Subversion.
There's just one thing to stress: never rebase commits which have been shared with other people when they likely added their own commits on top of it (branches which have been reviewed but not worked on by someone else might be fine). Since rebase clones commits, your co-workers will be unable to do a regular merge as the duplicated commits might trigger false conflicts. There's ways to get out of such a mess, but each co-worker will have to do it over again which won't gain you any points in the Mr. Popular competition.
-
@jbert Yeah my eyes glazed over about a sentence and a half in.
-
@blakeyrat said in Git's getting in my way again:
@timebandit said in Git's getting in my way again:
That makes a cleaner history
"clean" and "dirty" are not words that should be applied to engineering problems.
Is your method better than doing a merge? For reasons other than aesthetics?
One big advantage of rebasing is that because the history is linear, the actual changes at each point stand out better.
Most git tools for example can't easily show what each parent in a merge did or did not contribute, and thus evil merges are possible - whether by choice or accident.
-
@jbert I've never understood the evil-merges argument. Just redo the automatic merge and compare it to the manual merge commit - bam, all evilness (or lack thereof) is exposed. Plus you get to see how merge conflicts were manually resolved.
-
@blakeyrat said in Git's getting in my way again:
@jbert Yeah my eyes glazed over about a sentence and a half in.
Sigh, such a wall of text for nothing.
-
@blakeyrat said in Git's getting in my way again:
@jbert Yeah my eyes glazed over about a sentence and a half in.
Stick shape better than trapezoid shape because less angles. Don't touch someone else's stick.
-
@lb_ said in Git's getting in my way again:
@jbert I've never understood the evil-merges argument. Just redo the automatic merge and compare it to the manual merge commit - bam, all evilness (or lack thereof) is exposed. Plus you get to see how merge conflicts were manually resolved.
I'm not sure I fully understand it but that does sound like extra work, especially when reviewing the history.
-
@jbert well if you don't have a tool that does it for you, then yeah it's extra work, but it should be pretty trivial for a tool to do for you.
-
@jbert said in Git's getting in my way again:
Sigh, such a wall of text for nothing.
I read it (and I agree with it). Plus, you reminded me of that explain-git-with-d3 thingy, which is nice too.
-
@jbert said in Git's getting in my way again:
I had a look at that.
To be honest I’m just guessing, but one feature of git that slowed me down considerably when trying to find out who had removed some lines from the file is that git log pretends that merge commits don’t change any files.
Just when I thought
git
couldn't have any more s...