{"thread":{"id":"31806","subject":"git reflog delete HEAD@{1} HEAD@{2} caught me by surprise...","startedAt":"2012-10-13T22:08:55Z","lastAt":"2012-10-14T07:02:18Z","messageCount":3,"participants":["George Spelvin","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"201090","messageId":"20121013220855.24116.qmail@science.horizon.com","threadId":"31806","inReplyTo":null,"subject":"git reflog delete HEAD@{1} HEAD@{2} caught me by surprise...","fromName":"George Spelvin","fromEmail":"linux@horizon.com","sentAt":"2012-10-13T22:08:55Z","receivedAt":"2012-10-13T22:08:55Z","isPatch":false,"sender":{"key":"linux@horizon.com","avatar":null},"body":"Try the following commands in an empty directory:\n(I'm using the bash extention for {1..5}.)\n\ngit init\nfor i in {1..5}; do git commit -m \"Commit $i\" --allow-empty; done\ngit reflog\n\tbc93e06 HEAD@{0}: commit: Commit 5\n\te14f92d HEAD@{1}: commit: Commit 4\n\tac64d8e HEAD@{2}: commit: Commit 3\n\t287602b HEAD@{3}: commit: Commit 2\n\t183a378 HEAD@{4}: commit (initial): Commit 1\ngit reflog delete HEAD@{{1,2}}\ngit reflog\n\tbc93e06 HEAD@{0}: commit: Commit 5\n\te14f92d HEAD@{1}: commit: Commit 3\n\t287602b HEAD@{2}: commit (initial): Commit 1\n\nEr...I meant to delete Commit 3 from the reflog, not Commit 2.\n\nIn hindsight, it's obvious how this could happen, but it definitely\ntook me by surprise when I was trying to delete the reference to\na large and messy merge (that I didn't want and bloated my repository\nsize) from the reflog.\n\nIf this is, in fact, Working As Designed, could I request a paragraph\nin the man page clarifying it?  something like:\n\n\nTo delete single entries from the reflog, use the subcommand \"delete\"\nand specify the _exact_ entry (e.g. \"`git reflog delete master@{2}`\").\n\nYou may delete multiple reflog entries with one delete command,\n_however_ they are processed one at a time, so earlier deletes will cause\nrenumbering that will affect later ones.  To delete reflog entries @{2}\nand @{3}, the command would be either \"`git reflog delete @{3} @{2}`\",\nor \"`git reflog delete @{2} @{2}`\".\n"},{"id":"201118","messageId":"7vlif91wv6.fsf@alter.siamese.dyndns.org","threadId":"31806","inReplyTo":"20121013220855.24116.qmail@science.horizon.com","subject":"Re: git reflog delete HEAD@{1} HEAD@{2} caught me by surprise...","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-10-14T04:49:33Z","receivedAt":"2012-10-14T04:49:33Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"George Spelvin\" <linux@horizon.com> writes:\n\n> Try the following commands in an empty directory:\n> (I'm using the bash extention for {1..5}.)\n>\n> git init\n> for i in {1..5}; do git commit -m \"Commit $i\" --allow-empty; done\n> git reflog\n> \tbc93e06 HEAD@{0}: commit: Commit 5\n> \te14f92d HEAD@{1}: commit: Commit 4\n> \tac64d8e HEAD@{2}: commit: Commit 3\n> \t287602b HEAD@{3}: commit: Commit 2\n> \t183a378 HEAD@{4}: commit (initial): Commit 1\n> git reflog delete HEAD@{{1,2}}\n> git reflog\n> \tbc93e06 HEAD@{0}: commit: Commit 5\n> \te14f92d HEAD@{1}: commit: Commit 3\n> \t287602b HEAD@{2}: commit (initial): Commit 1\n>\n> Er...I meant to delete Commit 3 from the reflog, not Commit 2.\n\nYeah, I've never tried to delete more than one with one command,\nbut I am not surprised a naaïve implementation removes the first,\nand then removes the second in the resulting list.\n\n> To delete single entries from the reflog, use the subcommand \"delete\"\n> and specify the _exact_ entry (e.g. \"`git reflog delete master@{2}`\").\n>\n> You may delete multiple reflog entries with one delete command,\n> _however_ they are processed one at a time, so earlier deletes will cause\n> renumbering that will affect later ones.  To delete reflog entries @{2}\n> and @{3}, the command would be either \"`git reflog delete @{3} @{2}`\",\n> or \"`git reflog delete @{2} @{2}`\".\n\nI would actually call that behaviour a bug.  Perhaps it should grab\nall the command line arguments first, group them per the ref the\nreflog entries are based on, and expire _all_ reflog entries from\nthe same reflog in one go?\n\nUntil that happens, it may make sense to error it out when more than\none entries are given from the command line, at least for the same\nref.\n"},{"id":"201153","messageId":"20121014070218.16887.qmail@science.horizon.com","threadId":"31806","inReplyTo":"7vlif91wv6.fsf@alter.siamese.dyndns.org","subject":"Re: git reflog delete HEAD@{1} HEAD@{2} caught me by surprise...","fromName":"George Spelvin","fromEmail":"linux@horizon.com","sentAt":"2012-10-14T07:02:18Z","receivedAt":"2012-10-14T07:02:18Z","isPatch":false,"sender":{"key":"linux@horizon.com","avatar":null},"body":"> I would actually call that behaviour a bug.\n\nWell, yes, that was my inclination, too.  But writing documentation was\neasier than writing a code patch.  :-)\n\nEven when it is fixed, a comment about when it was fixed and what the\nbuggy version did should live in the BUGS section for a while, to warn\npeople writing portable scripts.\n\n> Perhaps it should grab\n> all the command line arguments first, group them per the ref the\n> reflog entries are based on, and expire _all_ reflog entries from\n> the same reflog in one go?\n\nTwo other options are to sort them in decreasing entry order (which you\ncould do either per-reflog, or simply globally), or to remember previous\ndeletions so you can adjust the numbers of later ones.\n\nOne tricky point is whether it's possible for a reflog to have two names,\nvia a symlink or something.  That definitely complicates collision\ndetection.\n\n> Until that happens, it may make sense to error it out when more than\n> one entries are given from the command line, at least for the same\n> ref.\n\nDetecting this seems like half the implementation work of fixing it,\nso I'm not sure it's worth bothering.\n\n\nLooking at the code (builtin/reflog.c), I notice that expire_reflog()\ntakes a lock on the ref, but the previous count_reflog_ent code doesn't,\nso things aren't necessarily race-proof.  I haven't figured out if the\nrace is a problem (i.e. does expire_reflog do something nasty if the\nstruct cmd_reflog_expire_cb holds stale data?), but I noticed...\n"}]}