Re: git-format-patch and dates
Arrgh! That was an e-mail I was drafting when I suffered a power failure. That's why it's full of incomplete sentences and repeitions; I was trying different wordings. It was never supposed to be sent, and when the power came back on I decided not to try to resurrect it. But apparently when the ssh connetion hung up, the draft got sent. :-( My apoogies, mea culpa, and please ignore.
git-format-patch and dates
Re: Why not git reset --hard ?
> I agree with you if we limit the scope to "reset --hard" that does > not mention any commit on the command line (or says "HEAD"). > > However, for things like: > > $ git reset --hard HEAD^ Makefile > $ git reset --hard HEAD@{4.hours.ago} Makefile > > I do not think "reset --hard" is a good match. Conceptually, you > are grabbing what was stored in a given commit and checking that out > to your current workspace (that is, the index and the working tree). I actually disagree, BUT that was based on an inaccurate mental model, so I'm not sure if my judgement can be trusted. Still, I'll blather on just to give a different perspective. To me, "git reset --hard" is "git reset" plus checking out from the index to the working directory. That's the difference and the only difference. So any difference in behaviour between git reset --hard -- and git reset --mixed -- git checkout -- needs to be justified. (There might be some if a file does not exist in the revision.) > All modes of "git reset" are primarily about updating where in the > history DAG your HEAD points at, and then adjusting your current > workspace to that update, taking into account the reason why you are > repointing your HEAD in the history DAG (e.g. when doing --hard > reset, you want the workspace to match what the commit your HEAD now > points at; when doing --soft reset, you don't want any changes > done). Er... no. Re-pointing HEAD can *only* be done as a global operation. That's the single most fundamental difference between git and CVS. Any time you specify a path, *obviously* that part can't be done, so git-reset just skips that part and goes on to the index-updating part.. Git reset also skips that part in the single most common invocation scenario: un-doing git-add. That's for a different reason (pointing HEAD to HEAD is a no-op), but it contributes to the mental model that git-reset is fundamentally used for copying from history to the index. That's my mental model, for what little it's worth (given the caveat above): - git checkout is fundamentally about copying from the index to the working directory. If can also move HEAD first (and create branches!) as a convenience feature. - git reset is fundamentally about copying from HEAD to the index. Like git-checkout, it can also move HEAD first (and copy to the working directory) as a convenience feature. To me, "git reset" is "throw the changes away and get me back to some previous state". That's why it's the tool I reached for in the merge-conflict situation that started this thread. I didn't think to try "git checkout" because I needed to overwrite the merge conflict in the index, and I don't think of "git checkout" as doing that. (Globally, it fails if there are unresolved conflits.) -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Why not git reset --hard ?
Junio C Hamano wrote: > "George Spelvin" writes: >> "git checkout " modifies the index? >> >> Damn, I've been using git for years and I never knew that. > > ... which would be an indication that the behaviour is most likely > the most natural one. I think it's more that often, staging a file to the index is pretty harmless, so it doesn't actually matter. Both of the commonest forms of commit ("git commit -a" and "git commit [-o] ") aren't affected, and if I'm doing something trickier, I'll usually examine the status and make sure I've got it right. So I could have encountered it and put it down to fat-fingering on my part. >> But I just tested, and it does. Damn, now I have to figure out >> how to "leapfrog" a file from history into the working tree without >> overwriting the index; that's occasionally useful. > ... and indeed it is useful in some rare cases. Either > >git diff | git apply -R > > or > >git checkout && >git reset The former would work, and thanks for the idea, but for a single file I'd probably do one of git show : > git cat-file blob : > The checkout/reset wouldn't work in the case I'm thinking about, which is when I want to import a small piece (say, helper function that got deleted) from an old or other-branch version of a file. I.e. a partial revert or cherry-pick. If I had some current changes to merge with, I'd stage them, pull the *other* version into the tree, and use something like git-gui to add the hunk I want to the staged version. The whole point is that the staged state is important and I don't want it overwritten. There are other ways, of course: - Show or cat-file the other version into a temporary file and manually copy and paste. No need to stage anything. - Commit the current change, then add the additional changes and amend the commit. -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Why not git reset --hard ?
Junio C Hamano wrote: > "git checkout HEAD " is a 99% acceptable substitute for it > (the only case where it makes a difference is when you added a path to > the index that did not exist in HEAD). Er, wait a minute... "git checkout " modifies the index? Damn, I've been using git for years and I never knew that. I thought it only modified the working tree. But I just tested, and it does. Damn, now I have to figure out how to "leapfrog" a file from history into the working tree without overwriting the index; that's occasionally useful. -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Why not git reset --hard ?
I was applying an old forgotten stash to see if there were any edits in it I wanted to preserve, and my old changes to one file made no sense any more. I wanted to drop then all and keep the version in HEAD. I'd been using git reset after resolving conflicts, to leave the changes in the same un-staged state they were before the stash, so I tried using "git reset --hard crypto/842.c" to throw away my local changes. And I got fatal: Cannot do hard reset with paths. So I did "git reset " followed by "git checkout ", which achieved what I wanted. But what I don't understand is why git reset couldn't do it for me in one step. I understand that "git reset --soft" makes no sense with a path, but why not --hard? -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[BUG] rebase modify/delete conflict prints wrong SHA-1
I was rebasing my local kernel patches on top of v4.2 (using Debian git_1:2.5.1-1_amd64), and ran into the following when one of the files I modified got renamed in mainline: Applying: drivers/ntb/ntb_hw.c: Use prandom_u32_max() Using index info to reconstruct a base tree... A drivers/ntb/ntb_hw.c Falling back to patching base and 3-way merge... CONFLICT (modify/delete): drivers/ntb/ntb_hw.c deleted in 0ec6a07f518304248dca177405fa607822e4933d and modified in drivers/ntb/ntb_hw.c: Use prandom_u32_max(). Version drivers/ntb/ntb_hw.c: Use prandom_u32_max() of drivers/ntb/ntb_hw.c left in tree. Failed to merge in the changes. Patch failed at 0037 drivers/ntb/ntb_hw.c: Use prandom_u32_max() The copy of the patch that failed is found in: /usr/src/linux/.git/rebase-apply/patch The problem is that 0ec6a07f518304248dca177405fa607822e4933d is *my* patch. And it's not the conflicting patch, either, it's some nearby patch! The file was renamed in ec110bc7cc48d7806c9b65094e6afb19452d458f ("NTB: Move files in preparation for NTB abstraction"), which you can find in 4.2-rc1. It appears that there's a glitch in printing the SHA-1 in this case. I tried to reproduce it with the trivial case: create an initial commit with one file, delete it in one branch, modify it in another, and then rebase the second on top of the first. git rebase printed the right SHA-1. But if I have two commits on each branch, I get something similar: git init foo cd foo echo foo > foo echo bar > bar git add foo bar git commit -m "Initial commit" git rm foo git commit -m "Delete foo" git rm bar git commit -m "Delete bar" git checkout -b branch HEAD^^ echo baz >> foo git commit -m "Edit foo" foo echo baz >> bar git commit -m "Edit bar" bar git rebase master First, rewinding head to replay your work on top of it... Applying: Edit foo Using index info to reconstruct a base tree... A foo Falling back to patching base and 3-way merge... CONFLICT (modify/delete): foo deleted in 52e1cece1e48dc21b317d4bd671fa171c3a7abd3 and modified in Edit foo. Version Edit foo of foo left in tree. Failed to merge in the changes. Patch failed at 0001 Edit foo The copy of the patch that failed is found in: /tmp/foo/.git/rebase-apply/patch For me, commit 52e1cece is the patch that removes bar, not foo: $ git show 52e1cece commit 52e1cece1e48dc21b317d4bd671fa171c3a7abd3 Author: George Spelvin Date: Sun Aug 30 18:59:09 2015 -0400 Delete bar diff --git a/bar b/bar deleted file mode 100644 index 5716ca5..000 --- a/bar +++ /dev/null @@ -1 +0,0 @@ -bar -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2] userdiff: update Ada patterns
Looking at the grammar at http://www.adahome.com/rm95/rm9x-P.html and http://www.adaic.org/resources/add_content/standards/05rm/html/RM-2-4.html I see the following restrictions apply: - A number must begin and end with a digit. There must be at least one digit on either side of each underscore and decimal point. - There may be at most one decimal point in a number. - The base must be between 2 and 16, inclusive. [-+]?( [0-9](_?[0-9])*([.][0-9](_?[0-9])*)?| ([2-9]|1[0-6])#[0-9a-fA-F](_?[0-9a-fA-F])*([.][0-9a-fA-F](_?[0-9a-fA-F])*)?# )([eE][+-]?[0-9](_?[0-9])*)? If you want a slightly smaller version, we can drop the "only one decimal point" rule and get [-+]?( [0-9]([._]?[0-9])*| ([2-9]|1[0-6])#[0-9a-fA-F]([._]?[0-9a-fA-F])*# )([eE][+-]?[0-9](_?[0-9])*)? Ideally, for a based number, the range of acceptable digits would depend on the base. Which is possible for a finite-state machine since the number of bases is finite, but laeds to a bit of a state explosion. Here's an approximation that separates bases 2-9 and 10-16: [-+]?( [0-9](_?[0-9])*([.][0-9](_?[0-9])*)?| [2-9]#[0-8](_?[0-8])*([.][0-8](_?[0-8])*)?#| 1[0-6]#[0-9a-fA-F](_?[0-9a-fA-F])*([.][0-9a-fA-F](_?[0-9a-fA-F])*)?# )([eE][+-]?[0-9](_?[0-9])*)? because I think that this is overdoing it: [-+]?( [0-9](_?[0-9])*([.][0-9](_?[0-9])*)?| 2#[0-1](_?[0-1])*([.][0-1](_?[0-1])*)?#| 3#[0-2](_?[0-2])*([.][0-2](_?[0-2])*)?#| 4#[0-3](_?[0-3])*([.][0-3](_?[0-3])*)?#| 5#[0-4](_?[0-4])*([.][0-4](_?[0-4])*)?#| 6#[0-5](_?[0-5])*([.][0-5](_?[0-5])*)?#| 7#[0-5](_?[0-5])*([.][0-5](_?[0-5])*)?#| 8#[0-7](_?[0-7])*([.][0-7](_?[0-7])*)?#| 9#[0-8](_?[0-8])*([.][0-8](_?[0-8])*)?#| 10#[0-9](_?[0-9])*([.][0-9](_?[0-9])*)?#| 11#[0-9aA](_?[0-9aA])*([.][0-9aA](_?[0-9aA])*)?#| 12#[0-9abAB](_?[0-9abAB])*([.][0-9abAB](_?[0-9abAB])*)?#| 13#[0-9a-cA-C](_?[0-9a-cA-C])*([.][0-9a-cA-C](_?[0-9a-cA-C])*)?#| 14#[0-9a-dA-D](_?[0-9a-dA-D])*([.][0-9a-dA-D](_?[0-9a-dA-D])*)?#| 15#[0-9a-eA-E](_?[0-9a-eA-E])*([.][0-9a-eA-E](_?[0-9a-eA-E])*)?#| 16#[0-9a-fA-F](_?[0-9a-fA-F])*([.][0-9a-fA-F](_?[0-9a-fA-F])*)?#| )([eE][+-]?[0-9](_?[0-9])*)? Another point is that Ada doesn't actually include leading + or - signs in the syntax for "number", but rather makes them unary operators. This means that spaces are allowed, and whether you want to include them in the "number" pattern is a judgement call. -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Is there a way to cherry-pick a merge?
> In the meantime, "git commit --amend -C commit" would be a > workaround, I would guess. Ah! A useful feature I was not familiar with. Definitely helps a great deal. Thank you! -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Is there a way to cherry-pick a merge?
"George Spelvin" writes: >> Sometimes I'd like to repeat a previously performed merge, preserving >> the commit message. And, if possible, the conflict resolutions. > > Is it "git merge commit^2"? I suppose that was an obvious one to leave out of my alternatives list. This is what I've been doing, but it requires I cut and paste the commit message. Preserving timestamps, author, etc. is even more awkward. That's why I've been looking for an alternative. -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Is there a way to cherry-pick a merge?
Sometimes I'd like to repeat a previously performed merge, preserving the commit message. And, if possible, the conflict resolutions. "git cherry-pick -m 1 " gets me the changes, but makes an ordinary single-parent commit, not a merge. "git rebase -p --onto HEAD commit^ commit" does the right thing, but has two annoying properties: 1) It actually checks out "commit", then goes back to HEAD, thus forcing a lot of recompiltion of source files that experience no net change from the operation. 2) Because it's intended for multi-step use, it stops and waits for confirmation if there are rerere changes. I'd rather it just did the commit if there are no remaining conflict markers, and I'll reset or amend it if I'm not happy with the result. Does something like this exist already? Thank you! -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: git reflog delete HEAD@{1} HEAD@{2} caught me by surprise...
> I would actually call that behaviour a bug. Well, yes, that was my inclination, too. But writing documentation was easier than writing a code patch. :-) Even when it is fixed, a comment about when it was fixed and what the buggy version did should live in the BUGS section for a while, to warn people writing portable scripts. > Perhaps it should grab > all the command line arguments first, group them per the ref the > reflog entries are based on, and expire _all_ reflog entries from > the same reflog in one go? Two other options are to sort them in decreasing entry order (which you could do either per-reflog, or simply globally), or to remember previous deletions so you can adjust the numbers of later ones. One tricky point is whether it's possible for a reflog to have two names, via a symlink or something. That definitely complicates collision detection. > Until that happens, it may make sense to error it out when more than > one entries are given from the command line, at least for the same > ref. Detecting this seems like half the implementation work of fixing it, so I'm not sure it's worth bothering. Looking at the code (builtin/reflog.c), I notice that expire_reflog() takes a lock on the ref, but the previous count_reflog_ent code doesn't, so things aren't necessarily race-proof. I haven't figured out if the race is a problem (i.e. does expire_reflog do something nasty if the struct cmd_reflog_expire_cb holds stale data?), but I noticed... -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
git reflog delete HEAD@{1} HEAD@{2} caught me by surprise...
Try the following commands in an empty directory: (I'm using the bash extention for {1..5}.) git init for i in {1..5}; do git commit -m "Commit $i" --allow-empty; done git reflog bc93e06 HEAD@{0}: commit: Commit 5 e14f92d HEAD@{1}: commit: Commit 4 ac64d8e HEAD@{2}: commit: Commit 3 287602b HEAD@{3}: commit: Commit 2 183a378 HEAD@{4}: commit (initial): Commit 1 git reflog delete HEAD@{{1,2}} git reflog bc93e06 HEAD@{0}: commit: Commit 5 e14f92d HEAD@{1}: commit: Commit 3 287602b HEAD@{2}: commit (initial): Commit 1 Er...I meant to delete Commit 3 from the reflog, not Commit 2. In hindsight, it's obvious how this could happen, but it definitely took me by surprise when I was trying to delete the reference to a large and messy merge (that I didn't want and bloated my repository size) from the reflog. If this is, in fact, Working As Designed, could I request a paragraph in the man page clarifying it? something like: To delete single entries from the reflog, use the subcommand "delete" and specify the _exact_ entry (e.g. "`git reflog delete master@{2}`"). You may delete multiple reflog entries with one delete command, _however_ they are processed one at a time, so earlier deletes will cause renumbering that will affect later ones. To delete reflog entries @{2} and @{3}, the command would be either "`git reflog delete @{3} @{2}`", or "`git reflog delete @{2} @{2}`". -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Git feature request: --amend older commit
> Have you tried "git rebase --autosquash"? It does part of what you are > asking for and additionally allows multiple fixup commits to be queued > up and processed in a single rebase. No, I hadn't! It's not *quite* as simple as what I had hoped for, but definitely is progress in that direction. In particular, I can probably manage to use those to write a script that does what I want. Something that ends up with something like "EDITOR=/bin/true git rebase -i --autosquash $base" Thanks you! I apologize for my failure to (Re-) RTFM. I have done so numerous times, but the feature wasn't there last time I looked. -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Git feature request: --amend older commit
With git's "commit frequently" style, I often find that I end up with a commit that includes a typo in a comment or I forgot one call site when updating functions or something. And it's a few commits later before I notice the simple oops. This is of course fixable by making a commit, rebase -i HEAD~4 (or whatever), and marking the fixup for squashing into the previous commit. But it would be really handy if there were a one-step command for doing this. Something like "git commit --fixup HEAD~3", where "git commit --fixup HEAD" would be equivalent to "git commit --amend". It would be fine if it were implemented using rebase -i and you had to use "git rebase --continue" to recover from a conflict. And history had to be linear from the fixup point to HEAD. The only thing I'd wish for, that rebase -i doesn't support, is a commit with a dirty tree. (Because often the typo is noticed in the middle of further development.) But if I have to manually stash & pop, that would be good enough. Talking with some friends, they all say "yeah, I would really use that feature". So I figured I'd mention it here. -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html