For example when I try to bring an old feature branch forward, or when I have two private branches with a common history that I've touched on one side and want rebase to apply my history change onto the other branch, I'm often made to resolve a lot more conflict that seems necessary.
There are scripts like git-imerge that give some much nicer conflicts. imerge may not be perfect, but I think it shows there's room for a more clever algorithm.
I'd happily have a git rebase --full-resolver --wuauctl option that consumes a mysteriously large amounts of CPU time, if it saves me some manual conflict resolution =)
Unless that UX problem is helped by it being much, much faster, but that's usually only going to be matter for larger repositories.
I really like the idea, and wrote my personal little `git autosquash` command that tries to figure out the oldest commit it has to run `git rebase -ir --autosquash` on in order to merge all current "fixup! …" commits into their counterparts.
However, doing this in a simple shell script is rather dodgy if you run into more generic commit messages. Personally, I'd love it if git allowed me to create "fixup! <commit hash>" commits instead. I mean -- it's a fixup. It's not supposed to be readable anyway.
Do you mean that you've got commit subject that are ambiguous within the series you're rebasing, so --autosquash won't correctly attribute them?
What I want to achieve is that I can run my script (i.e. `git autosquash`), and it will automatically start the appropriate interactive rebase for me. That means I still get the rebase description I can check by eye in Vim (and have the option of aborting by emptying the buffer before quitting it).
I usually use this to clean up the history of a private local branch, so I won't trigger anything like `git rebase master`. This means that I have to specify the commit where Git is supposed to start the interactive rebase (i.e. the oldest commit that won't be included). And finding that by looking for the subject line after "fixup!" is rather finnicky (especially if the subject line also matches those of other commits), whereas the simple commit hash would be nice and explicit (and finding the starting point would be a simple `git merge-base --octopus` of all fixup! hashes).
So, my problem isn't the autosquash resolution built into Git, but that I have to reimplement it in a script in order to find the proper rebase starting point. That, and all backward searches for commit messages I know of are either really fuzzy or needlessly convoluted.
The best exact matching search I could come up with is something akin to
git log --pretty=$'%H\x1F%s' "$fixup_commit_hash" | awk -F $'\x1F' -v "subject=$query" '$2 == subject { print $1; exit }'Is there any reason you don't (or perhaps you're not aware that you can) use the branch upstream info for this?
Whenever I work on a branch called "topic" I do the equivalent of "git branch --set-upstream-to origin/master" on it. That means that all of:
git log @{u}..
git diff @{u}
git diff @{u}...
Will use that upstream point (@{u} or @{upstream}). What does this have to do with rebase? If you do: git rebase -i
It's the same as doing: git rebase -i @{u}
That's probably not exactly what you're asking for, i.e. if you've got a history since master of: A foo
B bar
C !fixup bar
D !fixup bar
You'd open an editor with A..D with that, whereas you perhaps only want B..D?> You'd open an editor with A..D with that, whereas you perhaps only want B..D?
That wouldn't be much of an issue for me, but I still tried to implement an option that doesn't rely on my repository having a defined remote.
I quite often start a new local git repository whenever I'm about to start a new experiment (or just scripting some one-off task), and most of these will never get pushed onto a git server. However, even in those cases, my scatterbrain often triggers the "gah, that should have been in a previous commit!" reflex.
By the way: Thank you very much for taking your time and reading all this! :)
Edit: I just re-read the upstream-point thing. Wouldn't that cause a `git push` on `thing` to push directly to `origin/master`?
That also wouldn't be compatible with the workflow we have at work (we use GitLab merge requests)…
I use this extensively with Git(Hub|Lab) (PR|MR)'s. I set the upstream to "master" but push to "topic". The "push.default" docs cover how to have your cake and eat it too there.
1. A consistent cross-language API for reading and writing from a bare/remote git repo in ways that would make sense to an average programmer. Something like `git.stat("/file.txt", commit=...)`, `git.open("/file.txt", branch=...)` `git.list_commits(since=...)`, `git.create_commit(parrent_commits=[], branch="", ...)`
2. A good story, better than LFS, for storing large binaries over time.
For #2 I want to reproducibly build a debian image from vendored packages or recompile gcc from source so I need to check in a pre-built compiler. etc
I know file locks are almost an antipattern for git. But there are definitely good use cases and arguments for better git support and related tooling support around them, especially for binary heavier areas.
The other thing I saw other day was sparse index or something. At work we have a monorepo and I wish that was more control or granularity over checking out a subset of a repo somehow. Our clones even with shallow fetch and lfs can be 5+ minutes for an area that should only take 3 seconds. But no good subset checkout.
I wish `git-log`'s `--follow` wasn't optional so GitHub et al would show the complete history for files I `git mv`. Mercurial got this one right :)
I'd say that most of the work of driving features forward in git is hunting down those various edge cases, taking the time to understand them, and explaining them to others. So if anyone's interested in flipping that particular switch it's very open to first-time contributions.
If I want to quit/escape adding a patch in the interactive mode I type `q` and then enter.
If I want to quit/escape the interactive add subcommand I type `q` and then enter.
But if I want to quit the `update`, `untracked` etc. I have to enter nothing and then press enter. It would be such a wonderful thing if it also accepted `q` so my muscle "memory" is correct.
I looked into changing this once, but it is written in shell and Perl, which I don't know enough about to figure out.
The other thing that was frustrating with that was that the help text for what commands do is printed before everything, so if your window is small and there's a lot of output, it's not obvious that the ? you typed did anything other than re-print the hunk. It seems odd to not print the help information at the end so you will always see it (unless your window is less than one row tall, but.. you're probably here for dragons anyway in that situation).
It looks like the ball may have been dropped on opting users in to it by default, but in any case there's numerous bugs in "git add -p" and "git add -i" that got fixed along the way, and fixing existing ones should be a lot easier now.
Note: I've also worked on the perl compiler/interpreter in a past life, so it's not that I'm afraid of hacking on Perl, but doing so in the context of the Git project is and was always particularly painful. If something's written in C you could use all the APIs git had internally, but anything in .sh or .perl was usually stuck parsing text, or reinventing the wheel.
[alias]
permission-reset = "!git diff -p | grep -E \"^(diff|old mode|new mode)\" | sed -e \"s/^old/NEW/;s/^new/old/;s/^NEW/new/\" | git apply"
So when I run git permission-reset, it sorts it out.
Are there any specific things that git does that you wish were done better? I probably won't be able to help with very generic things like "it's complex", but if there's specific drawbacks in some particular commands I might be able to fix them.
Or anything else, I'll monitor this thread while there's interest.