Git development
 help / color / mirror / Atom feed
* Re: [PATCH] rebase -i: introduce the 'test' command
From: Johannes Schindelin @ 2018-12-04  9:13 UTC (permalink / raw)
  To: Jeff King; +Cc: Luc Van Oostenryck, Paul Morelle, Git Users
In-Reply-To: <20181203213134.GD8700@sigill.intra.peff.net>

Hi Peff,

On Mon, 3 Dec 2018, Jeff King wrote:

> On Mon, Dec 03, 2018 at 08:01:44PM +0100, Johannes Schindelin wrote:
> 
> > > In this sort of situation, I often whish to be able to do nested rebases.
> > > Even more because it happen relatively often that I forget that I'm
> > > working in a rebase and not on the head, and then it's quite natural
> > > to me to type things like 'git rebase -i @^^^' while already rebasing.
> > > But I suppose this has already been discussed.
> > 
> > Varieties of this have been discussed, but no, not nested rebases.
> > 
> > The closest we thought about was re-scheduling the latest <n> commits,
> > which is now harder because of the `--rebase-merges` mode.
> > 
> > But I think it would be doable. Your idea of a "nested" rebase actually
> > opens that door quite nicely. It would not *really* be a nested rebase,
> > and it would still only be possible in interactive mode, but I could
> > totally see
> > 
> > 	git rebase --nested -i HEAD~3
> > 
> > to generate and prepend the following lines to the `git-rebase-todo` file:
> > 
> > 	reset abcdef01 # This is HEAD~3
> > 	pick abcdef02 # This is HEAD~2
> > 	pick abcdef03 # This is HEAD~
> > 	pick abcdef04 # This is HEAD
> > 
> > (assuming that the latest 3 commits were non-merge commits; It would look
> > quite a bit more complicated in other situations.)
> 
> Yeah, I would probably use that if it existed.

I kind of use it, even if it does not exist ;-)

> It would be nicer to have real nested sequencer operations, I think, for
> other situations.

I agree. But for the moment, our data format is too married to the exact
layout of .git/, thanks to `git rebase`'s evolution from a Unix shell
script.

Alban has this really great patch series to work on the todo list
in-memory, and that paves the way to decouple the entire sequencer thing
from the file system.

The most notably thing that still would need to be encapsulated would be
the options: currently, there is a plethora of inconsistent options files
being saved into the state directory (for some, the mere presence
indicates `true`, some contain `true` or `false`, others contain text,
etc).

> E.g., cherry-picking a sequence of commits while you're in the middle of
> a rebase.

You will be delighted to learn that you can cherry-pick a sequence of
commits in the middle of a rebase already. I do `exec git cherry-pick
<range>` *all* the time.

> But I suspect getting that right would be _loads_ more work, and
> probably would involve some funky UI corner cases to handle the stack of
> operations (so truly aborting a rebase may mean an arbitrary number of
> "rebase --abort" calls to pop the stack). Your suggestion is probably a
> reasonable trick in the meantime.

You know what is an even more reasonable trick? Worktrees.

I only thought about that this morning, but I should have mentioned it
right away, as I use it quite frequently.

When I have tricky nested rebases to perform, I do use throw-away
worktrees where I check out unnamed branches, work on those, and then
integrate them back into the "outer rebase" via the `reset` command in the
todo list.

Ciao,
Dscho

^ permalink raw reply

* git-gui: Norwegian Bokmål translation
From: Petter Reinholdtsen @ 2018-12-04  9:29 UTC (permalink / raw)
  To: git; +Cc: Pat Thoyts, Fredrik Skolmli


From 9a7edd7f94b82335177917463cb334541b4d2cb0 Mon Sep 17 00:00:00 2001
From: Petter Reinholdtsen <pere@hungry.com>
Date: Mon, 3 Dec 2018 12:24:22 +0100
Subject: [PATCH] i18n: Update the nb translation of git-gui and start on
 glossary list.

Signed-off-by: Petter Reinholdtsen <pere@hungry.com>
---
 po/glossary/nb.po | 171 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 po/nb.po          |  57 ++++++++++++------
 2 files changed, 210 insertions(+), 18 deletions(-)
 create mode 100644 po/glossary/nb.po

diff --git a/po/glossary/nb.po b/po/glossary/nb.po
new file mode 100644
index 0000000..1a80451
--- /dev/null
+++ b/po/glossary/nb.po
@@ -0,0 +1,171 @@
+# Copyright (C) 2018 Free Software Foundation, Inc.
+#
+# Petter Reinholdtsen <pere@hungry.com>, 2018.
+msgid ""
+msgstr ""
+"Project-Id-Version: \n"
+"POT-Creation-Date: 2008-01-07 21:20+0100\n"
+"PO-Revision-Date: 2018-12-03 12:35+0100\n"
+"Last-Translator: Petter Reinholdtsen <pere@hungry.com>\n"
+"Language-Team: NorwegianBokmal <i18n-no@lister.ping.uio.no>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: ENCODING\n"
+"Language: nb\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Generator: Lokalize 2.0\n"
+
+#. "English Definition (Dear translator: This file will never be visible to the user! It should only serve as a tool for you, the translator. Nothing more.)"
+msgid ""
+"English Term (Dear translator: This file will never be visible to the user!)"
+msgstr ""
+
+#. ""
+msgid "amend"
+msgstr "legg til"
+
+#. ""
+msgid "annotate"
+msgstr "kommenter"
+
+#. "A 'branch' is an active line of development."
+msgid "branch [noun]"
+msgstr "gren [substantiv]"
+
+#. ""
+msgid "branch [verb]"
+msgstr ""
+
+#. ""
+msgid "checkout [noun]"
+msgstr "utsjekk [substantiv]"
+
+#. "The action of updating the working tree to a revision which was stored in the object database."
+msgid "checkout [verb]"
+msgstr "sjekk ut [verb]"
+
+#. ""
+msgid "clone [verb]"
+msgstr "klone [verb]"
+
+#. "A single point in the git history."
+msgid "commit [noun]"
+msgstr "endring [substantiv]"
+
+#. "The action of storing a new snapshot of the project's state in the git history."
+msgid "commit [verb]"
+msgstr "sjekk inn [verb]"
+
+#. ""
+msgid "diff [noun]"
+msgstr "forskjell [substantiv]"
+
+#. ""
+msgid "diff [verb]"
+msgstr ""
+
+#. "A fast-forward is a special type of merge where you have a revision and you are merging another branch's changes that happen to be a descendant of what you have."
+msgid "fast forward merge"
+msgstr ""
+
+#. "Fetching a branch means to get the branch's head from a remote repository, to find out which objects are missing from the local object database, and to get them, too."
+msgid "fetch"
+msgstr "hent"
+
+#. "One context of consecutive lines in a whole patch, which consists of many such hunks"
+msgid "hunk"
+msgstr ""
+
+#. "A collection of files. The index is a stored version of your working tree."
+msgid "index (in git-gui: staging area)"
+msgstr ""
+
+#. "A successful merge results in the creation of a new commit representing the result of the merge."
+msgid "merge [noun]"
+msgstr ""
+
+#. "To bring the contents of another branch into the current branch."
+msgid "merge [verb]"
+msgstr ""
+
+#. ""
+msgid "message"
+msgstr "melding"
+
+#. "Deletes all stale tracking branches under <name>. These stale branches have already been removed from the remote repository referenced by <name>, but are still locally available in 'remotes/<name>'."
+msgid "prune"
+msgstr ""
+
+#. "Pulling a branch means to fetch it and merge it."
+msgid "pull"
+msgstr "dra inn"
+
+#. "Pushing a branch means to get the branch's head ref from a remote repository, and ... (well, can someone please explain it for mere mortals?)"
+msgid "push"
+msgstr "skyv"
+
+#. ""
+msgid "redo"
+msgstr "gjør om"
+
+#. "An other repository ('remote'). One might have a set of remotes whose branches one tracks."
+msgid "remote"
+msgstr ""
+
+#. "A collection of refs (?) together with an object database containing all objects which are reachable from the refs... (oops, you've lost me here. Again, please an explanation for mere mortals?)"
+msgid "repository"
+msgstr "depot"
+
+#. ""
+msgid "reset"
+msgstr "nullstill"
+
+#. ""
+msgid "revert"
+msgstr ""
+
+#. "A particular state of files and directories which was stored in the object database."
+msgid "revision"
+msgstr ""
+
+#. ""
+msgid "sign off"
+msgstr ""
+
+#. ""
+msgid "staging area"
+msgstr ""
+
+#. ""
+msgid "status"
+msgstr "status"
+
+#. "A ref pointing to a tag or commit object"
+msgid "tag [noun]"
+msgstr "merkelapp [substantiv] "
+
+#. ""
+msgid "tag [verb]"
+msgstr "merk [verb]"
+
+#. "A regular git branch that is used to follow changes from another repository."
+msgid "tracking branch"
+msgstr ""
+
+#. ""
+msgid "undo"
+msgstr ""
+
+#. ""
+msgid "update"
+msgstr "oppdater"
+
+#. ""
+msgid "verify"
+msgstr ""
+
+#. "The tree of actual checked out files."
+msgid "working copy, working tree"
+msgstr ""
+
+
diff --git a/po/nb.po b/po/nb.po
index d66aa50..92a7f5d 100644
--- a/po/nb.po
+++ b/po/nb.po
@@ -2,19 +2,23 @@
 # Copyright (C) 2007-2008 Shawn Pearce, et al.
 # This file is distributed under the same license as the git-gui package.
 #
-# Fredrik Skolmli <fredrik@frsk.net>, 2008.
 #
+# Fredrik Skolmli <fredrik@frsk.net>, 2008.
+# Petter Reinholdtsen <pere@hungry.com>, 2018.
 msgid ""
 msgstr ""
 "Project-Id-Version: nb\n"
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2008-11-16 13:56-0800\n"
-"PO-Revision-Date: 2008-12-03 16:05+0100\n"
-"Last-Translator: Fredrik Skolmli <fredrik@frsk.net>\n"
-"Language-Team: Norwegian Bokmål\n"
+"PO-Revision-Date: 2018-12-03 12:23+0100\n"
+"Last-Translator: Petter Reinholdtsen <pere@hungry.com>\n"
+"Language-Team: NorwegianBokmal <i18n-no@lister.ping.uio.no>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: nb\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Generator: Lokalize 2.0\n"
 
 #: git-gui.sh:41 git-gui.sh:737 git-gui.sh:751 git-gui.sh:764 git-gui.sh:847
 #: git-gui.sh:866
@@ -71,7 +75,7 @@ msgstr "Kan ikke gå til toppen av arbeidskatalogen:"
 
 #: git-gui.sh:1076
 msgid "Cannot use funny .git directory:"
-msgstr ""
+msgstr "Kan ikke bruke merkelig .git-katalog:"
 
 #: git-gui.sh:1081
 msgid "No working directory"
@@ -87,11 +91,11 @@ msgstr "Søker etter endrede filer..."
 
 #: git-gui.sh:1367
 msgid "Calling prepare-commit-msg hook..."
-msgstr ""
+msgstr "Kjører kroken prepare-common-msg..."
 
 #: git-gui.sh:1384
 msgid "Commit declined by prepare-commit-msg hook."
-msgstr ""
+msgstr "Innsjekking avvist av kroken prepare-commit-msg."
 
 #: git-gui.sh:1542 lib/browser.tcl:246
 msgid "Ready."
@@ -516,6 +520,9 @@ msgid ""
 "This is due to a known issue with the\n"
 "Tcl binary distributed by Cygwin."
 msgstr ""
+"\n"
+"Dette kommer av et kjent problem med\n"
+"Tcl-binæren distribuert av Cygwin."
 
 #: git-gui.sh:3336
 #, tcl-format
@@ -527,6 +534,12 @@ msgid ""
 "user.email settings into your personal\n"
 "~/.gitconfig file.\n"
 msgstr ""
+"\n"
+"\n"
+"En god erstatning for %s\n"
+"er å legge inn verdier for innstillingene til\n"
+"user.name og user.email i din personlige\n"
+"~/.gitconfig-fil.\n"
 
 #: lib/about.tcl:26
 msgid "git-gui - a graphical user interface for Git."
@@ -558,7 +571,7 @@ msgstr "Vis historikkens innhold"
 
 #: lib/blame.tcl:291
 msgid "Blame Parent Commit"
-msgstr ""
+msgstr "Skyld på foreldreendring"
 
 #: lib/blame.tcl:450
 #, tcl-format
@@ -1516,14 +1529,16 @@ msgstr "Laster inn forskjellene av %s..."
 msgid ""
 "LOCAL: deleted\n"
 "REMOTE:\n"
-msgstr "LOKAL: slettet\n"
+msgstr ""
+"LOKAL: slettet\n"
 "FJERN:\n"
 
 #: lib/diff.tcl:125
 msgid ""
 "REMOTE: deleted\n"
 "LOCAL:\n"
-msgstr "FJERN: slettet\n"
+msgstr ""
+"FJERN: slettet\n"
 "LOKAL:\n"
 
 #: lib/diff.tcl:132
@@ -1662,7 +1677,8 @@ msgstr "Reverter endringene i disse %i filene?"
 
 #: lib/index.tcl:406
 msgid "Any unstaged changes will be permanently lost by the revert."
-msgstr "Endringer som ikke ligger i innsjekkingskøen vil bli tapt av denne "
+msgstr ""
+"Endringer som ikke ligger i innsjekkingskøen vil bli tapt av denne "
 "reverteringen"
 
 #: lib/index.tcl:409
@@ -1852,16 +1868,16 @@ msgstr "Konfliktfil eksisterer ikke"
 #: lib/mergetool.tcl:264
 #, tcl-format
 msgid "Not a GUI merge tool: '%s'"
-msgstr ""
+msgstr "Ikke et grafisk sammenslåingsverktøy: '%s'"
 
 #: lib/mergetool.tcl:268
 #, tcl-format
 msgid "Unsupported merge tool '%s'"
-msgstr ""
+msgstr "Ikke-støttet sammenlåingsverktøy '%s'"
 
 #: lib/mergetool.tcl:303
 msgid "Merge tool is already running, terminate it?"
-msgstr ""
+msgstr "Sammenslåingsverktøyet kjører allerede.  Stoppe det?"
 
 #: lib/mergetool.tcl:323
 #, tcl-format
@@ -1879,24 +1895,27 @@ msgid ""
 "\n"
 "%s"
 msgstr ""
+"Klarte ikke starte sammenslåingsverktøyet:\n"
+"\n"
+"%s"
 
 #: lib/mergetool.tcl:347
 msgid "Running merge tool..."
-msgstr ""
+msgstr "Kjører sammenslåingsverktøyet..."
 
 #: lib/mergetool.tcl:375 lib/mergetool.tcl:383
 msgid "Merge tool failed."
-msgstr ""
+msgstr "Sammenslåingsverktøyet feilet."
 
 #: lib/option.tcl:11
 #, tcl-format
 msgid "Invalid global encoding '%s'"
-msgstr ""
+msgstr "Ugyldig global enkoding '%s'"
 
 #: lib/option.tcl:19
 #, tcl-format
 msgid "Invalid repo encoding '%s'"
-msgstr ""
+msgstr "Ugyldig depot-enkoding '%s'"
 
 #: lib/option.tcl:117
 msgid "Restore Defaults"
@@ -2472,3 +2491,5 @@ msgstr "Bruk tynne pakker (for tregere nettverkstilkoblinger)"
 #: lib/transport.tcl:168
 msgid "Include tags"
 msgstr "Inkluder tagger"
+
+
-- 
2.11.0

^ permalink raw reply related

* [BUG REPORT] Git does not correctly replay bisect log
From: Lukáš Krejčí @ 2018-12-04  9:51 UTC (permalink / raw)
  To: git

Executing git bisect replay reaches a different commit than
the one that is obtained by running the commands from the bisect log manually.

Distribution: Arch Linux
git: 2.19.2-1
perl: 5.28.1-1
pcre2: 10.32-1
expat: 2.2.6-1
perl-error: 0.17027-1
grep: 3.1-2
bash: 4.4.023-1

no system /etc/gitconfig is present
tried with no ~/.gitconfig

$ cat .git/config
[core]
        repositoryformatversion = 0
        filemode = true
        bare = false
        logallrefupdates = true
[remote "origin"]
        url = git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
        fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
        remote = origin
        merge = refs/heads/master

$ git fsck
Checking object directories: 100% (256/256), done.
warning in tag 5dc01c595e6c6ec9ccda4f6f69c131c0dd945f8c:
missingTaggerEntry: invalid format - expected 'tagger' line
warning in tag 26791a8bcf0e6d33f43aef7682bdb555236d56de:
missingTaggerEntry: invalid format - expected 'tagger' line
warning in tag 9e734775f7c22d2f89943ad6c745571f1930105f:
missingTaggerEntry: invalid format - expected 'tagger' line
warning in tag 0397236d43e48e821cce5bbe6a80a1a56bb7cc3a:
missingTaggerEntry: invalid format - expected 'tagger' line
warning in tag ebb5573ea8beaf000d4833735f3e53acb9af844c:
missingTaggerEntry: invalid format - expected 'tagger' line
warning in tag 06f6d9e2f140466eeb41e494e14167f90210f89d:
missingTaggerEntry: invalid format - expected 'tagger' line
warning in tag 701d7ecec3e0c6b4ab9bb824fd2b34be4da63b7e:
missingTaggerEntry: invalid format - expected 'tagger' line
warning in tag 733ad933f62e82ebc92fed988c7f0795e64dea62:
missingTaggerEntry: invalid format - expected 'tagger' line
warning in tag c521cb0f10ef2bf28a18e1cc8adf378ccbbe5a19:
missingTaggerEntry: invalid format - expected 'tagger' line
warning in tag a339981ec18d304f9efeb9ccf01b1f04302edf32:
missingTaggerEntry: invalid format - expected 'tagger' line
Checking objects: 100% (6428247/6428247), done.
Checking connectivity: 6369862, done.

$ cat /var/tmp/git-bisect.log
git bisect start
# bad: [5b394b2ddf0347bef56e50c69a58773c94343ff3] Linux 4.19-rc1
git bisect bad 5b394b2ddf0347bef56e50c69a58773c94343ff3
# good: [94710cac0ef4ee177a63b5227664b38c95bbf703] Linux 4.18
git bisect good 94710cac0ef4ee177a63b5227664b38c95bbf703
# bad: [54dbe75bbf1e189982516de179147208e90b5e45] Merge tag
'drm-next-2018-08-15' of git://anongit.freedesktop.org/drm/drm
git bisect bad 54dbe75bbf1e189982516de179147208e90b5e45
# bad: [0a957467c5fd46142bc9c52758ffc552d4c5e2f7] x86: i8259: Add
missing include file
git bisect bad 0a957467c5fd46142bc9c52758ffc552d4c5e2f7
# good: [958f338e96f874a0d29442396d6adf9c1e17aa2d] Merge branch
'l1tf-final' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
git bisect good 958f338e96f874a0d29442396d6adf9c1e17aa2d
# bad: [2c20443ec221dcb76484b30933593e8ecd836bbd] Merge tag
'acpi-4.19-rc1' of
git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
git bisect bad 2c20443ec221dcb76484b30933593e8ecd836bbd
# bad: [c2fc71c9b74c1e87336a27dba1a5edc69d2690f1] Merge tag
'mtd/for-4.19' of git://git.infradead.org/linux-mtd
git bisect bad c2fc71c9b74c1e87336a27dba1a5edc69d2690f1
# bad: [b86d865cb1cae1e61527ea0b8977078bbf694328] blkcg: Make
blkg_root_lookup() work for queues in bypass mode
git bisect bad b86d865cb1cae1e61527ea0b8977078bbf694328
# bad: [1b0d274523df5ef1caedc834da055ff721e4d4f0] nvmet: don't use uuid_le type
git bisect bad 1b0d274523df5ef1caedc834da055ff721e4d4f0

$ git status
On branch master
Your branch is up to date with 'origin/master'.

nothing to commit, working tree clean

$ git log -1 --format=oneline
2595646791c319cadfdbf271563aac97d0843dc7 (HEAD -> master, tag:
v4.20-rc5, origin/master, origin/HEAD) Linux 4.20-rc5

$ git bisect replay /var/tmp/git-bisect.log
We are not bisecting.
Bisecting: a merge base must be tested
[d72e90f33aa4709ebecc5005562f52335e106a60] Linux 4.18-rc6

$ git log -1 --format=oneline
d72e90f33aa4709ebecc5005562f52335e106a60 (HEAD, tag: v4.18-rc6) Linux 4.18-rc6





Running the commands from the bisect log manually, however:

$ git bisect reset
Checking out files: 100% (18326/18326), done.
Previous HEAD position was d72e90f33aa4 Linux 4.18-rc6
Switched to branch 'master'
Your branch is up to date with 'origin/master'.

$ . /var/tmp/git-bisect.log
Bisecting: 6112 revisions left to test after this (roughly 13 steps)
[54dbe75bbf1e189982516de179147208e90b5e45] Merge tag
'drm-next-2018-08-15' of git://anongit.freedesktop.org/drm/drm
Bisecting: 3881 revisions left to test after this (roughly 12 steps)
[0a957467c5fd46142bc9c52758ffc552d4c5e2f7] x86: i8259: Add missing include file
Bisecting: 1595 revisions left to test after this (roughly 11 steps)
[958f338e96f874a0d29442396d6adf9c1e17aa2d] Merge branch 'l1tf-final'
of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Bisecting: 854 revisions left to test after this (roughly 10 steps)
[2c20443ec221dcb76484b30933593e8ecd836bbd] Merge tag 'acpi-4.19-rc1'
of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Bisecting: 352 revisions left to test after this (roughly 9 steps)
[c2fc71c9b74c1e87336a27dba1a5edc69d2690f1] Merge tag 'mtd/for-4.19' of
git://git.infradead.org/linux-mtd
Bisecting: 193 revisions left to test after this (roughly 8 steps)
[b86d865cb1cae1e61527ea0b8977078bbf694328] blkcg: Make
blkg_root_lookup() work for queues in bypass mode
Bisecting: 97 revisions left to test after this (roughly 7 steps)
[1b0d274523df5ef1caedc834da055ff721e4d4f0] nvmet: don't use uuid_le type
Bisecting: 47 revisions left to test after this (roughly 6 steps)
[6dad38d38f20c0c8a84b5ae4f23c62b2c8758ec5] null_blk: move shared
definitions to header file

$ git log -1 --format=oneline
6dad38d38f20c0c8a84b5ae4f23c62b2c8758ec5 (HEAD) null_blk: move shared
definitions to header file

^ permalink raw reply

* Re: How de-duplicate similar repositories with alternates
From: Ævar Arnfjörð Bjarmason @ 2018-12-04 10:43 UTC (permalink / raw)
  To: Jeff King; +Cc: git, Git for human beings, Christian Couder
In-Reply-To: <20181204065930.GA11010@sigill.intra.peff.net>


On Tue, Dec 04 2018, Jeff King wrote:

> On Thu, Nov 29, 2018 at 03:59:26PM +0100, Ævar Arnfjörð Bjarmason wrote:
>
>> This is the thing I was wrong about, in retrospect probably because I'd
>> been putting PATH_TO_REPO in objects/info/alternates, but we actually
>> need PATH_TO_REPO/objects, and "git gc" won't warn about this (or "git
>> fsck"). Probably a good idea to patch that at some point, i.e. whine
>> about paths in alternates that don't have objects, or at the very least
>> those that don't exist. #leftoverbits
>
> We do complain about missing directories; see alt_odb_usable().
> Pointing to a real directory that doesn't happen to contain any objects
> is harder. If there are no loose objects, there might not be any hashed
> object directories. For a "real" object database, there should always be
> a "pack/" directory. But technically the object storage directory does
> not even need to have that; it can just be a directory full of loose
> objects that happens not to have any at this moment.
>
> That said, I suspect if we issued a warning for "woah, it looks like
> this doesn't have any objects in it, nor does it even have a pack
> directory" that nobody would complain.

Yeah, although see my <87sgzjyif2.fsf@evledraar.gmail.com>, I also ran
into a different issue.

I think a warning (or even error) like this would be more useful:

    test ! -d $objdir && error... # current behavior
    test -d $objdir/objects && error "Did you mean $objdir/objects, silly?" # new error

I.e. I suspect I'm not the only one who's not read the documentation
carefully enough and thought it was a path to the root of the repo and
wondered why it silently didn't work.

^ permalink raw reply

* Re: [BUG REPORT] Git does not correctly replay bisect log
From: Christian Couder @ 2018-12-04 11:04 UTC (permalink / raw)
  To: lskrejci; +Cc: git
In-Reply-To: <CA+YJQx72dMybGWyzNMUcNcVZnpDTHoaONcC-AQdqt=C_8aEdXg@mail.gmail.com>

On Tue, Dec 4, 2018 at 10:53 AM Lukáš Krejčí <lskrejci@gmail.com> wrote:
>
> Executing git bisect replay reaches a different commit than
> the one that is obtained by running the commands from the bisect log manually.


> $ git bisect replay /var/tmp/git-bisect.log
> We are not bisecting.
> Bisecting: a merge base must be tested
> [d72e90f33aa4709ebecc5005562f52335e106a60] Linux 4.18-rc6

Merge bases are tested only when the good commit is not an ancestor of
the bad commit. If this didn't happen when the log was recorded, it
shouldn't happen when it is replayed.

Here it seems that this is happening at the beginning of the replay.
Perhaps git bisect replay is taking into account the current
branch/commit though it shouldn't.

I wonder if this would happen if the current branch/commit has the
good commit as an ancestor.

Could you try to check that? And first could you give us the output of:

git merge-base 5b394b2ddf0347bef56e50c69a58773c94343ff3
94710cac0ef4ee177a63b5227664b38c95bbf703

^ permalink raw reply

* Re: [BUG REPORT] Git does not correctly replay bisect log
From: Lukáš Krejčí @ 2018-12-04 11:20 UTC (permalink / raw)
  To: Christian Couder; +Cc: git
In-Reply-To: <CAP8UFD2xv6SK+qPXKr5hQ0ZctOR5K-BNg1wdBy5=fp2DVBZMHw@mail.gmail.com>

On Tue, 2018-12-04 at 12:04 +0100, Christian Couder wrote:
> 
> Could you try to check that? And first could you give us the output of:
> 
> git merge-base 5b394b2ddf0347bef56e50c69a58773c94343ff3
> 94710cac0ef4ee177a63b5227664b38c95bbf703

$ git merge-base 5b394b2ddf0347bef56e50c69a58773c94343ff3 94710cac0ef4ee177a63b5227664b38c95bbf703
94710cac0ef4ee177a63b5227664b38c95bbf703
$ git log -1 --format=oneline 94710cac0ef4ee177a63b5227664b38c95bbf703
94710cac0ef4ee177a63b5227664b38c95bbf703 (tag: v4.18) Linux 4.18


^ permalink raw reply

* Re: [BUG REPORT] Git does not correctly replay bisect log
From: Lukáš Krejčí @ 2018-12-04 10:57 UTC (permalink / raw)
  To: git
In-Reply-To: <CA+YJQx72dMybGWyzNMUcNcVZnpDTHoaONcC-AQdqt=C_8aEdXg@mail.gmail.com>

(I'm sorry about the formatting, here's the message again.)

Executing git bisect replay reaches a different commit than
the one that is obtained by running the commands from the bisect log manually.

Distribution: Arch Linux
git: 2.19.2-1
perl: 5.28.1-1
pcre2: 10.32-1
expat: 2.2.6-1
perl-error: 0.17027-1
grep: 3.1-2
bash: 4.4.023-1

no system /etc/gitconfig is present
tried with no ~/.gitconfig

$ cat .git/config 
[core]
        repositoryformatversion = 0
        filemode = true
        bare = false
        logallrefupdates = true
[remote "origin"]
        url = git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
        fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
        remote = origin
        merge = refs/heads/master

$ git fsck
Checking object directories: 100% (256/256), done.
warning in tag 5dc01c595e6c6ec9ccda4f6f69c131c0dd945f8c: missingTaggerEntry: invalid format - expected 'tagger' line
warning in tag 26791a8bcf0e6d33f43aef7682bdb555236d56de: missingTaggerEntry: invalid format - expected 'tagger' line
warning in tag 9e734775f7c22d2f89943ad6c745571f1930105f: missingTaggerEntry: invalid format - expected 'tagger' line
warning in tag 0397236d43e48e821cce5bbe6a80a1a56bb7cc3a: missingTaggerEntry: invalid format - expected 'tagger' line
warning in tag ebb5573ea8beaf000d4833735f3e53acb9af844c: missingTaggerEntry: invalid format - expected 'tagger' line
warning in tag 06f6d9e2f140466eeb41e494e14167f90210f89d: missingTaggerEntry: invalid format - expected 'tagger' line
warning in tag 701d7ecec3e0c6b4ab9bb824fd2b34be4da63b7e: missingTaggerEntry: invalid format - expected 'tagger' line
warning in tag 733ad933f62e82ebc92fed988c7f0795e64dea62: missingTaggerEntry: invalid format - expected 'tagger' line
warning in tag c521cb0f10ef2bf28a18e1cc8adf378ccbbe5a19: missingTaggerEntry: invalid format - expected 'tagger' line
warning in tag a339981ec18d304f9efeb9ccf01b1f04302edf32: missingTaggerEntry: invalid format - expected 'tagger' line
Checking objects: 100% (6428247/6428247), done.
Checking connectivity: 6369862, done.

$ cat /var/tmp/git-bisect.log
git bisect start
# bad: [5b394b2ddf0347bef56e50c69a58773c94343ff3] Linux 4.19-rc1
git bisect bad 5b394b2ddf0347bef56e50c69a58773c94343ff3
# good: [94710cac0ef4ee177a63b5227664b38c95bbf703] Linux 4.18
git bisect good 94710cac0ef4ee177a63b5227664b38c95bbf703
# bad: [54dbe75bbf1e189982516de179147208e90b5e45] Merge tag 'drm-next-2018-08-15' of git://anongit.freedesktop.org/drm/drm
git bisect bad 54dbe75bbf1e189982516de179147208e90b5e45
# bad: [0a957467c5fd46142bc9c52758ffc552d4c5e2f7] x86: i8259: Add missing include file
git bisect bad 0a957467c5fd46142bc9c52758ffc552d4c5e2f7
# good: [958f338e96f874a0d29442396d6adf9c1e17aa2d] Merge branch 'l1tf-final' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
git bisect good 958f338e96f874a0d29442396d6adf9c1e17aa2d
# bad: [2c20443ec221dcb76484b30933593e8ecd836bbd] Merge tag 'acpi-4.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
git bisect bad 2c20443ec221dcb76484b30933593e8ecd836bbd
# bad: [c2fc71c9b74c1e87336a27dba1a5edc69d2690f1] Merge tag 'mtd/for-4.19' of git://git.infradead.org/linux-mtd
git bisect bad c2fc71c9b74c1e87336a27dba1a5edc69d2690f1
# bad: [b86d865cb1cae1e61527ea0b8977078bbf694328] blkcg: Make blkg_root_lookup() work for queues in bypass mode
git bisect bad b86d865cb1cae1e61527ea0b8977078bbf694328
# bad: [1b0d274523df5ef1caedc834da055ff721e4d4f0] nvmet: don't use uuid_le type
git bisect bad 1b0d274523df5ef1caedc834da055ff721e4d4f0

$ git status
On branch master
Your branch is up to date with 'origin/master'.

nothing to commit, working tree clean

$ git log -1 --format=oneline
2595646791c319cadfdbf271563aac97d0843dc7 (HEAD -> master, tag: v4.20-rc5, origin/master, origin/HEAD) Linux 4.20-rc5

$ git bisect replay /var/tmp/git-bisect.log 
We are not bisecting.
Bisecting: a merge base must be tested
[d72e90f33aa4709ebecc5005562f52335e106a60] Linux 4.18-rc6

$ git log -1 --format=oneline
d72e90f33aa4709ebecc5005562f52335e106a60 (HEAD, tag: v4.18-rc6) Linux 4.18-rc6





# Running the commands from the bisect log manually, however:

$ git bisect reset
Checking out files: 100% (18326/18326), done.
Previous HEAD position was d72e90f33aa4 Linux 4.18-rc6
Switched to branch 'master'
Your branch is up to date with 'origin/master'.

$ . /var/tmp/git-bisect.log 
Bisecting: 6112 revisions left to test after this (roughly 13 steps)
[54dbe75bbf1e189982516de179147208e90b5e45] Merge tag 'drm-next-2018-08-15' of git://anongit.freedesktop.org/drm/drm
Bisecting: 3881 revisions left to test after this (roughly 12 steps)
[0a957467c5fd46142bc9c52758ffc552d4c5e2f7] x86: i8259: Add missing include file
Bisecting: 1595 revisions left to test after this (roughly 11 steps)
[958f338e96f874a0d29442396d6adf9c1e17aa2d] Merge branch 'l1tf-final' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Bisecting: 854 revisions left to test after this (roughly 10 steps)
[2c20443ec221dcb76484b30933593e8ecd836bbd] Merge tag 'acpi-4.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Bisecting: 352 revisions left to test after this (roughly 9 steps)
[c2fc71c9b74c1e87336a27dba1a5edc69d2690f1] Merge tag 'mtd/for-4.19' of git://git.infradead.org/linux-mtd
Bisecting: 193 revisions left to test after this (roughly 8 steps)
[b86d865cb1cae1e61527ea0b8977078bbf694328] blkcg: Make blkg_root_lookup() work for queues in bypass mode
Bisecting: 97 revisions left to test after this (roughly 7 steps)
[1b0d274523df5ef1caedc834da055ff721e4d4f0] nvmet: don't use uuid_le type
Bisecting: 47 revisions left to test after this (roughly 6 steps)
[6dad38d38f20c0c8a84b5ae4f23c62b2c8758ec5] null_blk: move shared definitions to header file

$ git log -1 --format=oneline
6dad38d38f20c0c8a84b5ae4f23c62b2c8758ec5 (HEAD) null_blk: move shared definitions to header file


^ permalink raw reply

* Re: [BUG REPORT] Git does not correctly replay bisect log
From: Christian Couder @ 2018-12-04 12:01 UTC (permalink / raw)
  To: lskrejci; +Cc: git
In-Reply-To: <f9f644daa705c78ef348a4a808d88bc01e7bdbd4.camel@gmail.com>

On Tue, Dec 4, 2018 at 12:20 PM Lukáš Krejčí <lskrejci@gmail.com> wrote:
>
> On Tue, 2018-12-04 at 12:04 +0100, Christian Couder wrote:
> >
> > Could you try to check that? And first could you give us the output of:
> >
> > git merge-base 5b394b2ddf0347bef56e50c69a58773c94343ff3
> > 94710cac0ef4ee177a63b5227664b38c95bbf703
>
> $ git merge-base 5b394b2ddf0347bef56e50c69a58773c94343ff3 94710cac0ef4ee177a63b5227664b38c95bbf703
> 94710cac0ef4ee177a63b5227664b38c95bbf703
> $ git log -1 --format=oneline 94710cac0ef4ee177a63b5227664b38c95bbf703
> 94710cac0ef4ee177a63b5227664b38c95bbf703 (tag: v4.18) Linux 4.18

94710cac0ef4ee177a63b5227664b38c95bbf703 is the good commit that was
initially given. This means that the good commit
94710cac0ef4ee177a63b5227664b38c95bbf703 is an ancestor of the bad
commit 5b394b2ddf0347bef56e50c69a58773c94343ff3 i and there should be
no reason to test a merge base when replaying.

After testing on my machine, it seems that the problem is not
happening at the beginning of the replay.

To debug I think it would be interesting to see the output of the
following commands just before we get different results:

git for-each-ref 'refs/bisect/*'

and

git log -1 --format=oneline

in the case we are using `git bisect replay` and in the case we are
running the commands from the bisect log manually.

(You might need to temporarily remove the last command from the bisect
log to do that.)

^ permalink raw reply

* Re: How de-duplicate similar repositories with alternates
From: Derrick Stolee @ 2018-12-04 12:07 UTC (permalink / raw)
  To: Jeff King, Stefan Beller
  Cc: Ævar Arnfjörð Bjarmason, git, git-users,
	Christian Couder
In-Reply-To: <20181204070602.GB11010@sigill.intra.peff.net>

On 12/4/2018 2:06 AM, Jeff King wrote:
> On Thu, Nov 29, 2018 at 10:55:49AM -0800, Stefan Beller wrote:
>
>> I view alternates as a historic artefact as the deduping
>> of objects client side can be done using worktrees, and on the
>> serverside - I think - most of the git hosters use namespaces
>> and put a fork network into the same repository and use pack islands.
> By contrast, object storage is pretty easy to share. It scales
> reasonably well, and the security model is much simpler due to the
> immutable nature of object names.

And for the client side, we use alternates as an important way to scale 
VFS for Git to multiple enlistments on the same machine. VFS for Git 
manages a "shared object cache" (the alternate) that is updated in the 
background (including multi-pack-index and commit-graph).

Using worktrees for the same effect would add complications to the user 
interactions, not only when creating an enlistment but the fact that two 
enlistments cannot check out the same ref will confuse users.

Thanks,
-Stolee

^ permalink raw reply

* [PATCH 1/3] sha1-file: test the error behavior of alt_odb_usable()
From: Ævar Arnfjörð Bjarmason @ 2018-12-04 13:27 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, Derrick Stolee, Christian Couder,
	Ævar Arnfjörð Bjarmason
In-Reply-To: <87tvjtvah0.fsf@evledraar.gmail.com>

Add a test for the error() case in alt_odb_usable() where an alternate
directory doesn't exist. This behavior has been the same since
26125f6b9b ("detect broken alternates.", 2006-02-22), but if that
error() was turned into die() the entire test suite would still pass.

Perhaps we should die() in that case, but let's start by adding a test
here to assert the long-standing existing behavior.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t5613-info-alternate.sh | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/t/t5613-info-alternate.sh b/t/t5613-info-alternate.sh
index 895f46bb91..d2964c57b7 100755
--- a/t/t5613-info-alternate.sh
+++ b/t/t5613-info-alternate.sh
@@ -136,4 +136,11 @@ test_expect_success CASE_INSENSITIVE_FS 'dup finding can be case-insensitive' '
 	test_cmp expect actual.alternates
 '
 
+test_expect_success 'print "error" on non-existing alternate' '
+	git init --bare I &&
+	echo DOES_NOT_EXIST >I/objects/info/alternates &&
+	git -C I fsck 2>stderr &&
+	test_i18ngrep "does not exist; check" stderr
+'
+
 test_done
-- 
2.20.0.rc2.403.gdbc3b29805


^ permalink raw reply related

* [PATCH 0/3] sha1-file: warn if alternate is a git repo (not object dir)
From: Ævar Arnfjörð Bjarmason @ 2018-12-04 13:27 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, Derrick Stolee, Christian Couder,
	Ævar Arnfjörð Bjarmason
In-Reply-To: <87tvjtvah0.fsf@evledraar.gmail.com>

This adds a warning for the issue discussed upthread. As noted in
these patches we've been emitting an "error" while not impacting the
exit code, should we die() instead? Maybe, but until there's consensus
on that let's change this to warning() while we're at it.

Ævar Arnfjörð Bjarmason (3):
  sha1-file: test the error behavior of alt_odb_usable()
  sha1-file: emit error if an alternate looks like a repository
  sha1-file: change alternate "error:" message to "warning:"

 sha1-file.c               | 16 ++++++++++++----
 t/t5613-info-alternate.sh | 21 +++++++++++++++++++++
 2 files changed, 33 insertions(+), 4 deletions(-)

-- 
2.20.0.rc2.403.gdbc3b29805


^ permalink raw reply

* [PATCH 2/3] sha1-file: emit error if an alternate looks like a repository
From: Ævar Arnfjörð Bjarmason @ 2018-12-04 13:27 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, Derrick Stolee, Christian Couder,
	Ævar Arnfjörð Bjarmason
In-Reply-To: <87tvjtvah0.fsf@evledraar.gmail.com>

Since 26125f6b9b ("detect broken alternates.", 2006-02-22) we've
emitted an error if the alternates directory doesn't exist, but not
for the common misstep of adding a path to another git repository as
an alternate, as opposed to its "objects" directory.

Let's check for this, i.e. whether X/objects or X/.git/objects exists
if the user supplies X and print an error (which as a commit leading
up to this one shows doesn't change the exit code, just "warns").

This check is intentionally not implemented by e.g. requiring that any
of X/?? exists or X/info or X/pack exists. It's a legitimate use-case
to point to an existing alternate that hasn't been populated yet, but
pointing to one where an "X/objects" or "X/.git/objects" directory
exists is definitely a mistake we should warn the user about.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 sha1-file.c               | 10 +++++++++-
 t/t5613-info-alternate.sh | 14 ++++++++++++++
 2 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/sha1-file.c b/sha1-file.c
index 5bd11c85bc..f142f81658 100644
--- a/sha1-file.c
+++ b/sha1-file.c
@@ -376,12 +376,20 @@ static int alt_odb_usable(struct raw_object_store *o,
 {
 	struct alternate_object_database *alt;
 
-	/* Detect cases where alternate disappeared */
 	if (!is_directory(path->buf)) {
+		/* Detect cases where alternate disappeared */
 		error(_("object directory %s does not exist; "
 			"check .git/objects/info/alternates"),
 		      path->buf);
 		return 0;
+	} else if (is_directory(mkpath("%s/objects", path->buf)) ||
+		   is_directory(mkpath("%s/.git/objects", path->buf))) {
+		/* Detect cases where alternate is a git repository */
+		error(_("object directory %s looks like a git repository; "
+			"alternates must point to the 'objects' directory. "
+			"check .git/objects/info/alternates"),
+		      path->buf);
+		return 0;
 	}
 
 	/*
diff --git a/t/t5613-info-alternate.sh b/t/t5613-info-alternate.sh
index d2964c57b7..b959e21421 100755
--- a/t/t5613-info-alternate.sh
+++ b/t/t5613-info-alternate.sh
@@ -143,4 +143,18 @@ test_expect_success 'print "error" on non-existing alternate' '
 	test_i18ngrep "does not exist; check" stderr
 '
 
+test_expect_success 'print "error" on alternate that looks like a git repository' '
+	git init --bare J &&
+	git init --bare K &&
+
+	# H is bare, G is not
+	echo ../../H >J/objects/info/alternates &&
+	echo ../../G >K/objects/info/alternates &&
+
+	git -C J fsck 2>stderr &&
+	test_i18ngrep "looks like a git repository; alternates must" stderr &&
+	git -C K fsck 2>stderr &&
+	test_i18ngrep "looks like a git repository; alternates must" stderr
+'
+
 test_done
-- 
2.20.0.rc2.403.gdbc3b29805


^ permalink raw reply related

* [PATCH 3/3] sha1-file: change alternate "error:" message to "warning:"
From: Ævar Arnfjörð Bjarmason @ 2018-12-04 13:27 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, Derrick Stolee, Christian Couder,
	Ævar Arnfjörð Bjarmason
In-Reply-To: <87tvjtvah0.fsf@evledraar.gmail.com>

Change the "error" message emitted by alt_odb_usable() to be a
"warning" instead. As noted in commits leading up to this one this has
never impacted the exit code ever since the check was initially added
in 26125f6b9b ("detect broken alternates.", 2006-02-22).

It's confusing to emit an "error" when e.g. "git fsck" will exit with
0, so let's emit a "warning:" instead.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 sha1-file.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/sha1-file.c b/sha1-file.c
index f142f81658..4b9b63bdcb 100644
--- a/sha1-file.c
+++ b/sha1-file.c
@@ -378,17 +378,17 @@ static int alt_odb_usable(struct raw_object_store *o,
 
 	if (!is_directory(path->buf)) {
 		/* Detect cases where alternate disappeared */
-		error(_("object directory %s does not exist; "
-			"check .git/objects/info/alternates"),
-		      path->buf);
+		warning(_("object directory %s does not exist; "
+			  "check .git/objects/info/alternates"),
+			path->buf);
 		return 0;
 	} else if (is_directory(mkpath("%s/objects", path->buf)) ||
 		   is_directory(mkpath("%s/.git/objects", path->buf))) {
 		/* Detect cases where alternate is a git repository */
-		error(_("object directory %s looks like a git repository; "
-			"alternates must point to the 'objects' directory. "
-			"check .git/objects/info/alternates"),
-		      path->buf);
+		warning(_("object directory %s looks like a git repository; "
+			  "alternates must point to the 'objects' directory. "
+			  "check .git/objects/info/alternates"),
+			path->buf);
 		return 0;
 	}
 
-- 
2.20.0.rc2.403.gdbc3b29805


^ permalink raw reply related

* Re: How de-duplicate similar repositories with alternates
From: Ævar Arnfjörð Bjarmason @ 2018-12-04 13:35 UTC (permalink / raw)
  To: git, Git for human beings; +Cc: Christian Couder, Derrick Stolee
In-Reply-To: <87zhtsx73l.fsf@evledraar.gmail.com>


On Thu, Nov 29 2018, Ævar Arnfjörð Bjarmason wrote:

> A co-worker asked me today how space could be saved when you have
> multiple checkouts of the same repository (at different revs) on the
> same machine. I said since these won't block-level de-duplicate well[1]
> one way to do this is with alternates.
>
> However, once you have an existing clone I didn't know how to get the
> gains without a full re-clone, but I hadn't looked deeply into it. As it
> turns out I'm wrong about that, which I found when writing the following
> test-case which shows that it works:
>
>     (
>         cd /tmp &&
>         rm -rf /tmp/git-{master,pu,pu-alt}.git &&
>
>         # Normal clones
>         git clone --bare --no-tags --single-branch --branch master https://github.com/git/git.git /tmp/git-master.git &&
>         git clone --bare --no-tags --single-branch --branch pu https://github.com/git/git.git /tmp/git-pu.git &&
>
>         # An 'alternate' clone using 'master' objects from another repo
>         git --bare init /tmp/git-pu-alt.git &&
>         for git in git-pu.git git-pu-alt.git
>         do
>             echo /tmp/git-master.git/objects >/tmp/$git/objects/info/alternates
>         done &&
>         git -C git-pu-alt.git fetch --no-tags https://github.com/git/git.git pu:pu
>
>         # Respective sizes, 'alternate' clone much smaller
>         du -shc /tmp/git-*.git &&
>
>         # GC them all. Compacts the git-pu.git to git-pu-alt.git's size
>         for repo in git-*.git
>         do
>             git -C $repo gc
>         done &&
>         du -shc /tmp/git-*.git
>
>         # Add another big history (GFW) to git-{pu,master}.git (in that order!)
>         for repo in $(ls -d /tmp/git-*.git | sort -r)
>         do
>             git -C $repo fetch --no-tags https://github.com/git-for-windows/git master:master-gfw
>         done &&
>         du -shc /tmp/git-*.git &&
>
>         # Another GC. The objects now in git-master.git will be de-duped by all
>         for repo in git-*.git
>         do
>             git -C $repo gc
>         done &&
>         du -shc /tmp/git-*.git
>     )
>
> This shows a scenario where we clone git.git at "master" and "pu" in
> different places. After clone the relevant sizes are:
>
>     108M    /tmp/git-master.git
>     3.2M    /tmp/git-pu-alt.git
>     109M    /tmp/git-pu.git
>     219M    total
>
> I.e. git-pu-alt.git is much smaller since it points via alternates to
> git-master.git, and the history of "pu" shares most of the objects with
> "master". But then how do you get those gains for git-pu.git? Turns out
> you just "git gc"
>
>     111M    /tmp/git-master.git
>     2.1M    /tmp/git-pu-alt.git
>     2.1M    /tmp/git-pu.git
>     115M    total
>
> This is the thing I was wrong about, in retrospect probably because I'd
> been putting PATH_TO_REPO in objects/info/alternates, but we actually
> need PATH_TO_REPO/objects, and "git gc" won't warn about this (or "git
> fsck"). Probably a good idea to patch that at some point, i.e. whine
> about paths in alternates that don't have objects, or at the very least
> those that don't exist. #leftoverbits
>
> Then when we fetch git-for-windows:master to all the repos they all grow
> by the amount git-for-windows has diverged:
>
>     144M    /tmp/git-master.git
>     36M     /tmp/git-pu-alt.git
>     36M     /tmp/git-pu.git
>     214M    total
>
> Note that the "sort -r" is critical here. If we fetched git-master.git
> first (at this point the alternate for git-pu*.git) we wouldn't get the
> duplication in the first place, but instead:
>
>     144M    /tmp/git-master.git
>     2.1M    /tmp/git-pu-alt.git
>     2.1M    /tmp/git-pu.git
>     148M    total
>
> This shows the importance of keeping such an 'alternate' repo
> up-to-date, i.e. we don't get the duplication in the first place, but
> regardless (this from a run with sort -r) a "git gc" will coalesce them:
>
>     131M    /tmp/git-master.git
>     2.1M    /tmp/git-pu-alt.git
>     2.2M    /tmp/git-pu.git
>     135M    total
>
> If you find this interesting make sure to read my
> https://public-inbox.org/git/87k1s3bomt.fsf@evledraar.gmail.com/ and
> https://public-inbox.org/git/87in7nbi5b.fsf@evledraar.gmail.com/ for the
> caveats, i.e. if this is something intended for users then no ref in the
> alternate can ever be rewound, that'll potentially result in repository
> corruption.
>
> 1. https://public-inbox.org/git/87bmhiykvw.fsf@evledraar.gmail.com/

Maybe this is useful to someone. Here's a cronjob I wrote since I wrote
this thread that runs in daily cron on some of our systems.

It expects repositories in /var/lib/git_tree-for-alternates like
/var/lib/git_tree-for-alternates/git/git.git to exist, then scours /home
and /etc/puppet/environments (which we had a lot of) for "config" files
with the string in git/git (this saves us some work) and then tries to
find a git repository relative to that "config" file with "rev-parse
--absolute-git-dir".

If there is one, we check if the repository has a SHA-1 that the history
of our /var/lib/git_tree-for-alternates/git/git.git started with (if >1
we pick the oldest), if so this is a repository that can benefit from
using /var/lib/git_tree-for-alternates/git/git.git/objects as an
alternate, and we add the appropriate alternate info, unset
gc.bigPackThreshold so GC will actually do its work, and run "git gc"
sudo'd as the the user who owns the thing.

One one server the .git directories in /home went from ~2TB to ~100GB
using this script. On another from ~250G to ~5G. The leftover space
spent is the commit-grah (not de-duped like objects are), and whatever
accumulated divergence (topic branches mainly) exist in those repos
different than what the alternate store has in the HEAD branch.

#!/bin/bash

set -euo pipefail

ALTERNATES_STORE=/var/lib/git_tree-for-alternates

if ! test -d $ALTERNATES_STORE
then
    echo 'We have no alternates repositories here to point to!' >&2
    exit 0
fi


find_owning_user() {
    path=$1
    case $path in
        /home/*|/etc/puppet/environments/*)
            who=$(echo $path | perl -pe 's[^
                (?:
                    /home
                    |
                    /etc/puppet/environments
                )
                /
                ([^/]+)
                /
                .*
            ][$1]gx')
            if getent passwd $who >/dev/null
            then
                echo $who
            else
                echo "Know how to get user from path '$path', but '$who' is not a valid user!" >&2
            fi
            ;;
        *)
            echo "Don't know how to get user from path '$path' yet!" >&2
            ;;
    esac
}

find $ALTERNATES_STORE -type d -name '*.git' -printf "%P\n" |
while read alternate
do
    alternate_no_git=$(echo $alternate | sed 's/\.git//')
    ALTERNATES_STORE_OBJECTS=$ALTERNATES_STORE/$alternate/objects

    # If these repositories we're finding don't share a root commit
    # with the repo we have this is not going to work and we have the
    # wrong match. Note that we can have more than one root commit
    # and try to find the oldest one. Pretty sure bet that that's
    # the "real" root.
    root_commit=$(git -C $ALTERNATES_STORE/$alternate log --max-parents=0 --date-order --reverse --pretty=format:%H | head -n 1)
    echo "> Finding repositories on the system that share the $root_commit commit with $alternate" >&2

    find \
        /home \
        $(if test -d /etc/puppet/environments; then echo /etc/puppet/environments; fi) \
        -type f -name 'config' -exec grep -Hl $alternate_no_git {} \; 2>/dev/null |
    while read config
    do
        dirname=$(dirname $config)
        echo ">> Checking if $dirname is in a $alternate git repository..." >&2
        if git_dir=$(git -C $dirname rev-parse --absolute-git-dir) &&
                git -C $git_dir cat-file -e $root_commit
        then
            echo ">>> ...Yes it was, at $git_dir" >&2
            echo ">>>> Is it already migrated?..." >&2
            if test -e $git_dir/objects/info/alternates &&
                    grep -x -F -q $ALTERNATES_STORE_OBJECTS $git_dir/objects/info/alternates
            then
                echo ">>>> ...yes, nothing to do here" >&2
                continue
            else
                echo ">>>> ...no, doing migration" >&2

                who=$(find_owning_user $git_dir)
                if test -z "$who"
                then
                    echo ">>>>> unable to find who owns $git_dir" >&2
                    continue
                else
                    echo ">>>>> found that $who owns $git_dir" >&2
                fi

                if test "$DRY_RUN" = "1"
                then
                    echo ">>>>>> Would have ran commands migrating $git_dir"
                else
                    if ! sudo -u $who stat $git_dir >/dev/null 2>&1
                    then
                        echo ">>>>>> The '$who' user can't access his own '$git_dir'. Could be e.g. ex-employee. Using 'root'"
                        who=root
                    fi

                    echo ">>>>>> Migrating $git_dir is now $(sudo -u $who du -sh $git_dir | cut -f1)"
                    sudo -u $who git -C $git_dir config gc.bigPackThreshold 0
                    echo $ALTERNATES_STORE_OBJECTS | sudo tee -a $git_dir/objects/info/alternates >/dev/null
                    sudo -u $who git -C $git_dir gc
                    echo ">>>>>> Migrated $git_dir is now $(sudo -u $who du -sh $git_dir | cut -f1)"
                fi
            fi
        else
            echo ">>> No it isn't. Skipping it" >&2
            continue
        fi
    done
done

^ permalink raw reply

* Re: [BUG REPORT] Git does not correctly replay bisect log
From: Lukáš Krejčí @ 2018-12-04 13:36 UTC (permalink / raw)
  To: Christian Couder; +Cc: git
In-Reply-To: <CAP8UFD3cD5KtvPJK5WkWGVUT6grbL=xL2MV1YWNJGpOjD3uRiQ@mail.gmail.com>

On Tue, 2018-12-04 at 13:01 +0100, Christian Couder wrote:
> To debug I think it would be interesting to see the output of the
> following commands just before we get different results:
> 
> git for-each-ref 'refs/bisect/*'
> 
> and
> 
> git log -1 --format=oneline
> 

I placed the following snippet at the end of the loop in bisect_replay():
echo "COMMAND: '$git' '$bisect' '$command' '$rev'"		
git for-each-ref 'refs/bisect/*'
echo "current HEAD: $(git log -1 --format=oneline)"
echo "---"

$ env GIT_TRACE=0 git bisect replay /var/tmp/git-bisect.log 

We are not bisecting.
COMMAND: 'git' 'bisect' 'start' ''
current HEAD: 2595646791c319cadfdbf271563aac97d0843dc7 Linux 4.20-rc5
---
COMMAND: 'git' 'bisect' 'bad' '5b394b2ddf0347bef56e50c69a58773c94343ff3'
5b394b2ddf0347bef56e50c69a58773c94343ff3 commit refs/bisect/bad
current HEAD: 2595646791c319cadfdbf271563aac97d0843dc7 Linux 4.20-rc5
---
COMMAND: 'git' 'bisect' 'good' '94710cac0ef4ee177a63b5227664b38c95bbf703'
5b394b2ddf0347bef56e50c69a58773c94343ff3 commit refs/bisect/bad
94710cac0ef4ee177a63b5227664b38c95bbf703 commit refs/bisect/good-94710cac0ef4ee177a63b5227664b38c95bbf703
current HEAD: 2595646791c319cadfdbf271563aac97d0843dc7 Linux 4.20-rc5
---
COMMAND: 'git' 'bisect' 'bad' '54dbe75bbf1e189982516de179147208e90b5e45'
54dbe75bbf1e189982516de179147208e90b5e45 commit refs/bisect/bad
94710cac0ef4ee177a63b5227664b38c95bbf703 commit refs/bisect/good-94710cac0ef4ee177a63b5227664b38c95bbf703
current HEAD: 2595646791c319cadfdbf271563aac97d0843dc7 Linux 4.20-rc5
---
COMMAND: 'git' 'bisect' 'bad' '0a957467c5fd46142bc9c52758ffc552d4c5e2f7'
0a957467c5fd46142bc9c52758ffc552d4c5e2f7 commit refs/bisect/bad
94710cac0ef4ee177a63b5227664b38c95bbf703 commit refs/bisect/good-94710cac0ef4ee177a63b5227664b38c95bbf703
current HEAD: 2595646791c319cadfdbf271563aac97d0843dc7 Linux 4.20-rc5
---
COMMAND: 'git' 'bisect' 'good' '958f338e96f874a0d29442396d6adf9c1e17aa2d'
0a957467c5fd46142bc9c52758ffc552d4c5e2f7 commit refs/bisect/bad
94710cac0ef4ee177a63b5227664b38c95bbf703 commit refs/bisect/good-94710cac0ef4ee177a63b5227664b38c95bbf703
958f338e96f874a0d29442396d6adf9c1e17aa2d commit refs/bisect/good-958f338e96f874a0d29442396d6adf9c1e17aa2d
current HEAD: 2595646791c319cadfdbf271563aac97d0843dc7 Linux 4.20-rc5
---
COMMAND: 'git' 'bisect' 'bad' '2c20443ec221dcb76484b30933593e8ecd836bbd'
2c20443ec221dcb76484b30933593e8ecd836bbd commit refs/bisect/bad
94710cac0ef4ee177a63b5227664b38c95bbf703 commit refs/bisect/good-94710cac0ef4ee177a63b5227664b38c95bbf703
958f338e96f874a0d29442396d6adf9c1e17aa2d commit refs/bisect/good-958f338e96f874a0d29442396d6adf9c1e17aa2d
current HEAD: 2595646791c319cadfdbf271563aac97d0843dc7 Linux 4.20-rc5
---
COMMAND: 'git' 'bisect' 'bad' 'c2fc71c9b74c1e87336a27dba1a5edc69d2690f1'
c2fc71c9b74c1e87336a27dba1a5edc69d2690f1 commit refs/bisect/bad
94710cac0ef4ee177a63b5227664b38c95bbf703 commit refs/bisect/good-94710cac0ef4ee177a63b5227664b38c95bbf703
958f338e96f874a0d29442396d6adf9c1e17aa2d commit refs/bisect/good-958f338e96f874a0d29442396d6adf9c1e17aa2d
current HEAD: 2595646791c319cadfdbf271563aac97d0843dc7 Linux 4.20-rc5
---
COMMAND: 'git' 'bisect' 'bad' 'b86d865cb1cae1e61527ea0b8977078bbf694328'
b86d865cb1cae1e61527ea0b8977078bbf694328 commit refs/bisect/bad
94710cac0ef4ee177a63b5227664b38c95bbf703 commit refs/bisect/good-94710cac0ef4ee177a63b5227664b38c95bbf703
958f338e96f874a0d29442396d6adf9c1e17aa2d commit refs/bisect/good-958f338e96f874a0d29442396d6adf9c1e17aa2d
current HEAD: 2595646791c319cadfdbf271563aac97d0843dc7 Linux 4.20-rc5
---
COMMAND: 'git' 'bisect' 'bad' '1b0d274523df5ef1caedc834da055ff721e4d4f0'
1b0d274523df5ef1caedc834da055ff721e4d4f0 commit refs/bisect/bad
94710cac0ef4ee177a63b5227664b38c95bbf703 commit refs/bisect/good-94710cac0ef4ee177a63b5227664b38c95bbf703
958f338e96f874a0d29442396d6adf9c1e17aa2d commit refs/bisect/good-958f338e96f874a0d29442396d6adf9c1e17aa2d
current HEAD: 2595646791c319cadfdbf271563aac97d0843dc7 Linux 4.20-rc5
---
Bisecting: a merge base must be tested
[1e4b044d22517cae7047c99038abb444423243ca] Linux 4.18-rc4







# I placed git for-each-ref 'refs/bisect/*' after each command in the file:

$ . /var/tmp/git-bisect.log 
5b394b2ddf0347bef56e50c69a58773c94343ff3 commit refs/bisect/bad
Bisecting: 6112 revisions left to test after this (roughly 13 steps)
[54dbe75bbf1e189982516de179147208e90b5e45] Merge tag 'drm-next-2018-08-15' of git://anongit.freedesktop.org/drm/drm
5b394b2ddf0347bef56e50c69a58773c94343ff3 commit refs/bisect/bad
94710cac0ef4ee177a63b5227664b38c95bbf703 commit refs/bisect/good-94710cac0ef4ee177a63b5227664b38c95bbf703
Bisecting: 3881 revisions left to test after this (roughly 12 steps)
[0a957467c5fd46142bc9c52758ffc552d4c5e2f7] x86: i8259: Add missing include file
54dbe75bbf1e189982516de179147208e90b5e45 commit refs/bisect/bad
94710cac0ef4ee177a63b5227664b38c95bbf703 commit refs/bisect/good-94710cac0ef4ee177a63b5227664b38c95bbf703
Bisecting: 1595 revisions left to test after this (roughly 11 steps)
[958f338e96f874a0d29442396d6adf9c1e17aa2d] Merge branch 'l1tf-final' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
0a957467c5fd46142bc9c52758ffc552d4c5e2f7 commit refs/bisect/bad
94710cac0ef4ee177a63b5227664b38c95bbf703 commit refs/bisect/good-94710cac0ef4ee177a63b5227664b38c95bbf703
Bisecting: 854 revisions left to test after this (roughly 10 steps)
[2c20443ec221dcb76484b30933593e8ecd836bbd] Merge tag 'acpi-4.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
0a957467c5fd46142bc9c52758ffc552d4c5e2f7 commit refs/bisect/bad
94710cac0ef4ee177a63b5227664b38c95bbf703 commit refs/bisect/good-94710cac0ef4ee177a63b5227664b38c95bbf703
958f338e96f874a0d29442396d6adf9c1e17aa2d commit refs/bisect/good-958f338e96f874a0d29442396d6adf9c1e17aa2d
Bisecting: 352 revisions left to test after this (roughly 9 steps)
[c2fc71c9b74c1e87336a27dba1a5edc69d2690f1] Merge tag 'mtd/for-4.19' of git://git.infradead.org/linux-mtd
2c20443ec221dcb76484b30933593e8ecd836bbd commit refs/bisect/bad
94710cac0ef4ee177a63b5227664b38c95bbf703 commit refs/bisect/good-94710cac0ef4ee177a63b5227664b38c95bbf703
958f338e96f874a0d29442396d6adf9c1e17aa2d commit refs/bisect/good-958f338e96f874a0d29442396d6adf9c1e17aa2d
Bisecting: 193 revisions left to test after this (roughly 8 steps)
[b86d865cb1cae1e61527ea0b8977078bbf694328] blkcg: Make blkg_root_lookup() work for queues in bypass mode
c2fc71c9b74c1e87336a27dba1a5edc69d2690f1 commit refs/bisect/bad
94710cac0ef4ee177a63b5227664b38c95bbf703 commit refs/bisect/good-94710cac0ef4ee177a63b5227664b38c95bbf703
958f338e96f874a0d29442396d6adf9c1e17aa2d commit refs/bisect/good-958f338e96f874a0d29442396d6adf9c1e17aa2d
Bisecting: 97 revisions left to test after this (roughly 7 steps)
[1b0d274523df5ef1caedc834da055ff721e4d4f0] nvmet: don't use uuid_le type
b86d865cb1cae1e61527ea0b8977078bbf694328 commit refs/bisect/bad
94710cac0ef4ee177a63b5227664b38c95bbf703 commit refs/bisect/good-94710cac0ef4ee177a63b5227664b38c95bbf703
958f338e96f874a0d29442396d6adf9c1e17aa2d commit refs/bisect/good-958f338e96f874a0d29442396d6adf9c1e17aa2d
Bisecting: 47 revisions left to test after this (roughly 6 steps)
[6dad38d38f20c0c8a84b5ae4f23c62b2c8758ec5] null_blk: move shared definitions to header file
1b0d274523df5ef1caedc834da055ff721e4d4f0 commit refs/bisect/bad
94710cac0ef4ee177a63b5227664b38c95bbf703 commit refs/bisect/good-94710cac0ef4ee177a63b5227664b38c95bbf703
958f338e96f874a0d29442396d6adf9c1e17aa2d commit refs/bisect/good-958f338e96f874a0d29442396d6adf9c1e17aa2d








Here is the output of the first command with GIT_TRACE on.

$ env GIT_TRACE=1 git bisect replay /var/tmp/git-bisect.log 
14:30:26.859355 git.c:659               trace: exec: git-bisect replay /var/tmp/git-bisect.log
14:30:26.859422 run-command.c:643       trace: run_command: git-bisect replay /var/tmp/git-bisect.log
14:30:26.893410 git.c:415               trace: built-in: git rev-parse --git-dir
14:30:26.898676 git.c:415               trace: built-in: git rev-parse --show-cdup
14:30:26.906487 git.c:415               trace: built-in: git rev-parse --git-path objects
We are not bisecting.
14:30:26.928736 git.c:415               trace: built-in: git rev-parse --sq-quote
14:30:26.935080 git.c:415               trace: built-in: git rev-parse --is-bare-repository
14:30:26.941601 git.c:415               trace: built-in: git symbolic-ref -q HEAD
14:30:26.949947 git.c:415               trace: built-in: git bisect--helper --bisect-clean-state
14:30:26.961001 git.c:415               trace: built-in: git rev-parse --sq-quote
14:30:26.970945 git.c:415               trace: built-in: git show-ref -q --verify refs/bisect/bad
14:30:26.979838 git.c:415               trace: built-in: git for-each-ref 'refs/bisect/good-*'
COMMAND: 'git' 'bisect' 'start' ''
14:30:26.989878 git.c:415               trace: built-in: git for-each-ref 'refs/bisect/*'
14:30:26.997573 git.c:415               trace: built-in: git log -1 --format=oneline
current HEAD: 2595646791c319cadfdbf271563aac97d0843dc7 Linux 4.20-rc5
---
14:30:27.012658 git.c:415               trace: built-in: git bisect--helper --write-terms bad good
14:30:27.021663 git.c:415               trace: built-in: git update-ref refs/bisect/bad 5b394b2ddf0347bef56e50c69a58773c94343ff3
14:30:27.032023 git.c:415               trace: built-in: git show-branch 5b394b2ddf0347bef56e50c69a58773c94343ff3
COMMAND: 'git' 'bisect' 'bad' '5b394b2ddf0347bef56e50c69a58773c94343ff3'
14:30:27.045300 git.c:415               trace: built-in: git for-each-ref 'refs/bisect/*'
5b394b2ddf0347bef56e50c69a58773c94343ff3 commit refs/bisect/bad
14:30:27.055905 git.c:415               trace: built-in: git log -1 --format=oneline
current HEAD: 2595646791c319cadfdbf271563aac97d0843dc7 Linux 4.20-rc5
---
14:30:27.069302 git.c:415               trace: built-in: git update-ref refs/bisect/good-94710cac0ef4ee177a63b5227664b38c95bbf703 94710cac0ef4ee177a63b5227664b38c95bbf703
14:30:27.080205 git.c:415               trace: built-in: git show-branch 94710cac0ef4ee177a63b5227664b38c95bbf703
COMMAND: 'git' 'bisect' 'good' '94710cac0ef4ee177a63b5227664b38c95bbf703'
14:30:27.091229 git.c:415               trace: built-in: git for-each-ref 'refs/bisect/*'
5b394b2ddf0347bef56e50c69a58773c94343ff3 commit refs/bisect/bad
94710cac0ef4ee177a63b5227664b38c95bbf703 commit refs/bisect/good-94710cac0ef4ee177a63b5227664b38c95bbf703
14:30:27.101268 git.c:415               trace: built-in: git log -1 --format=oneline
current HEAD: 2595646791c319cadfdbf271563aac97d0843dc7 Linux 4.20-rc5
---
14:30:27.108474 git.c:415               trace: built-in: git update-ref refs/bisect/bad 54dbe75bbf1e189982516de179147208e90b5e45
14:30:27.117641 git.c:415               trace: built-in: git show-branch 54dbe75bbf1e189982516de179147208e90b5e45
COMMAND: 'git' 'bisect' 'bad' '54dbe75bbf1e189982516de179147208e90b5e45'
14:30:27.126344 git.c:415               trace: built-in: git for-each-ref 'refs/bisect/*'
54dbe75bbf1e189982516de179147208e90b5e45 commit refs/bisect/bad
94710cac0ef4ee177a63b5227664b38c95bbf703 commit refs/bisect/good-94710cac0ef4ee177a63b5227664b38c95bbf703
14:30:27.135195 git.c:415               trace: built-in: git log -1 --format=oneline
current HEAD: 2595646791c319cadfdbf271563aac97d0843dc7 Linux 4.20-rc5
---
14:30:27.143550 git.c:415               trace: built-in: git update-ref refs/bisect/bad 0a957467c5fd46142bc9c52758ffc552d4c5e2f7
14:30:27.151005 git.c:415               trace: built-in: git show-branch 0a957467c5fd46142bc9c52758ffc552d4c5e2f7
COMMAND: 'git' 'bisect' 'bad' '0a957467c5fd46142bc9c52758ffc552d4c5e2f7'
14:30:27.157688 git.c:415               trace: built-in: git for-each-ref 'refs/bisect/*'
0a957467c5fd46142bc9c52758ffc552d4c5e2f7 commit refs/bisect/bad
94710cac0ef4ee177a63b5227664b38c95bbf703 commit refs/bisect/good-94710cac0ef4ee177a63b5227664b38c95bbf703
14:30:27.163749 git.c:415               trace: built-in: git log -1 --format=oneline
current HEAD: 2595646791c319cadfdbf271563aac97d0843dc7 Linux 4.20-rc5
---
14:30:27.171138 git.c:415               trace: built-in: git update-ref refs/bisect/good-958f338e96f874a0d29442396d6adf9c1e17aa2d 958f338e96f874a0d29442396d6adf9c1e17aa2d
14:30:27.177118 git.c:415               trace: built-in: git show-branch 958f338e96f874a0d29442396d6adf9c1e17aa2d
COMMAND: 'git' 'bisect' 'good' '958f338e96f874a0d29442396d6adf9c1e17aa2d'
14:30:27.186531 git.c:415               trace: built-in: git for-each-ref 'refs/bisect/*'
0a957467c5fd46142bc9c52758ffc552d4c5e2f7 commit refs/bisect/bad
94710cac0ef4ee177a63b5227664b38c95bbf703 commit refs/bisect/good-94710cac0ef4ee177a63b5227664b38c95bbf703
958f338e96f874a0d29442396d6adf9c1e17aa2d commit refs/bisect/good-958f338e96f874a0d29442396d6adf9c1e17aa2d
14:30:27.199439 git.c:415               trace: built-in: git log -1 --format=oneline
current HEAD: 2595646791c319cadfdbf271563aac97d0843dc7 Linux 4.20-rc5
---
14:30:27.210832 git.c:415               trace: built-in: git update-ref refs/bisect/bad 2c20443ec221dcb76484b30933593e8ecd836bbd
14:30:27.219812 git.c:415               trace: built-in: git show-branch 2c20443ec221dcb76484b30933593e8ecd836bbd
COMMAND: 'git' 'bisect' 'bad' '2c20443ec221dcb76484b30933593e8ecd836bbd'
14:30:27.228918 git.c:415               trace: built-in: git for-each-ref 'refs/bisect/*'
2c20443ec221dcb76484b30933593e8ecd836bbd commit refs/bisect/bad
94710cac0ef4ee177a63b5227664b38c95bbf703 commit refs/bisect/good-94710cac0ef4ee177a63b5227664b38c95bbf703
958f338e96f874a0d29442396d6adf9c1e17aa2d commit refs/bisect/good-958f338e96f874a0d29442396d6adf9c1e17aa2d
14:30:27.237583 git.c:415               trace: built-in: git log -1 --format=oneline
current HEAD: 2595646791c319cadfdbf271563aac97d0843dc7 Linux 4.20-rc5
---
14:30:27.246265 git.c:415               trace: built-in: git update-ref refs/bisect/bad c2fc71c9b74c1e87336a27dba1a5edc69d2690f1
14:30:27.257213 git.c:415               trace: built-in: git show-branch c2fc71c9b74c1e87336a27dba1a5edc69d2690f1
COMMAND: 'git' 'bisect' 'bad' 'c2fc71c9b74c1e87336a27dba1a5edc69d2690f1'
14:30:27.268181 git.c:415               trace: built-in: git for-each-ref 'refs/bisect/*'
c2fc71c9b74c1e87336a27dba1a5edc69d2690f1 commit refs/bisect/bad
94710cac0ef4ee177a63b5227664b38c95bbf703 commit refs/bisect/good-94710cac0ef4ee177a63b5227664b38c95bbf703
958f338e96f874a0d29442396d6adf9c1e17aa2d commit refs/bisect/good-958f338e96f874a0d29442396d6adf9c1e17aa2d
14:30:27.279037 git.c:415               trace: built-in: git log -1 --format=oneline
current HEAD: 2595646791c319cadfdbf271563aac97d0843dc7 Linux 4.20-rc5
---
14:30:27.287349 git.c:415               trace: built-in: git update-ref refs/bisect/bad b86d865cb1cae1e61527ea0b8977078bbf694328
14:30:27.293680 git.c:415               trace: built-in: git show-branch b86d865cb1cae1e61527ea0b8977078bbf694328
COMMAND: 'git' 'bisect' 'bad' 'b86d865cb1cae1e61527ea0b8977078bbf694328'
14:30:27.301385 git.c:415               trace: built-in: git for-each-ref 'refs/bisect/*'
b86d865cb1cae1e61527ea0b8977078bbf694328 commit refs/bisect/bad
94710cac0ef4ee177a63b5227664b38c95bbf703 commit refs/bisect/good-94710cac0ef4ee177a63b5227664b38c95bbf703
958f338e96f874a0d29442396d6adf9c1e17aa2d commit refs/bisect/good-958f338e96f874a0d29442396d6adf9c1e17aa2d
14:30:27.307179 git.c:415               trace: built-in: git log -1 --format=oneline
current HEAD: 2595646791c319cadfdbf271563aac97d0843dc7 Linux 4.20-rc5
---
14:30:27.312767 git.c:415               trace: built-in: git update-ref refs/bisect/bad 1b0d274523df5ef1caedc834da055ff721e4d4f0
14:30:27.318559 git.c:415               trace: built-in: git show-branch 1b0d274523df5ef1caedc834da055ff721e4d4f0
COMMAND: 'git' 'bisect' 'bad' '1b0d274523df5ef1caedc834da055ff721e4d4f0'
14:30:27.323911 git.c:415               trace: built-in: git for-each-ref 'refs/bisect/*'
1b0d274523df5ef1caedc834da055ff721e4d4f0 commit refs/bisect/bad
94710cac0ef4ee177a63b5227664b38c95bbf703 commit refs/bisect/good-94710cac0ef4ee177a63b5227664b38c95bbf703
958f338e96f874a0d29442396d6adf9c1e17aa2d commit refs/bisect/good-958f338e96f874a0d29442396d6adf9c1e17aa2d
14:30:27.329725 git.c:415               trace: built-in: git log -1 --format=oneline
current HEAD: 2595646791c319cadfdbf271563aac97d0843dc7 Linux 4.20-rc5
---
14:30:27.332326 git.c:415               trace: built-in: git show-ref -q --verify refs/bisect/bad
14:30:27.342139 git.c:415               trace: built-in: git for-each-ref 'refs/bisect/good-*'
14:30:27.348466 git.c:415               trace: built-in: git show-ref -q --verify refs/bisect/bad
14:30:27.355160 git.c:415               trace: built-in: git for-each-ref 'refs/bisect/good-*'
14:30:27.364281 git.c:415               trace: built-in: git bisect--helper --next-all
Bisecting: a merge base must be tested
14:30:27.491498 run-command.c:643       trace: run_command: git checkout -q 1e4b044d22517cae7047c99038abb444423243ca --
14:30:27.497822 git.c:415               trace: built-in: git checkout -q 1e4b044d22517cae7047c99038abb444423243ca --
14:30:55.290141 run-command.c:643       trace: run_command: git show-branch 1e4b044d22517cae7047c99038abb444423243ca
14:30:55.292168 git.c:415               trace: built-in: git show-branch 1e4b044d22517cae7047c99038abb444423243ca
[1e4b044d22517cae7047c99038abb444423243ca] Linux 4.18-rc4


^ permalink raw reply

* Re: How de-duplicate similar repositories with alternates
From: Derrick Stolee @ 2018-12-04 14:17 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason, git, Git for human beings
  Cc: Christian Couder
In-Reply-To: <87sgzdv2gz.fsf@evledraar.gmail.com>

On 12/4/2018 8:35 AM, Ævar Arnfjörð Bjarmason wrote:
>   The leftover space
> spent is the commit-grah (not de-duped like objects are), and...

The commit-graph could be shared, as the commits in each enlistment can 
be parsed from local with GENERATION_NUMBER_INFINITY, giving us similar 
speedups.

The issue is: who updates the file? As the commit-graph gets behind, 
performance will degrade. But it seems like you'd need similar 
maintenance on the alternate object store, anyway.

Thanks,
-Stolee

^ permalink raw reply

* Re: [PATCH 5/5] test-lib: add support for GIT_TODO_TESTS
From: SZEDER Gábor @ 2018-12-04 14:46 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason; +Cc: git, Junio C Hamano
In-Reply-To: <20181127225445.30045-5-avarab@gmail.com>

On Tue, Nov 27, 2018 at 11:54:45PM +0100, Ævar Arnfjörð Bjarmason wrote:
> As noted in the updated t/README documentation being added here
> setting this new GIT_TODO_TESTS variable is usually better than
> GIT_SKIP_TESTS.

I don't see why this is "usually better".  I get how it can help your
particular use-case described below, but that doesn't mean that it's
"usually better".

> My use-case for this is to get feedback from the CI infrastructure[1]
> about which tests are passing due to fixes that have trickled into
> git.git.
> 
> With the GIT_SKIP_TESTS variable this use-case is painful, you need to
> do an occasional manual run without GIT_SKIP_TESTS set. It's much
> better to use GIT_TODO_TESTS and get a report of passing TODO tests
> from prove(1) at the bottom of the test output. Once those passing
> TODO tests have trickled down to 'master' the relevant glob (set for
> all of master/next/pu) can be removed.

Neither from the commit message nor from the documentation is it clear
to me what the result of 'make test' will be when a test listed in
GIT_TODO_TESTS fails.

> As seen in the "GIT_TODO_TESTS mixed failure" test the lack of
> interaction with existing tests marked as TODO by the test suite
> itself is intentional. There's no need to print out something saying
> they matched GIT_TODO_TESTS if they're already TODO tests.
> 
> 1. https://public-inbox.org/git/875zwm15k2.fsf@evledraar.gmail.com/
> 
> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
> ---
>  ci/lib-travisci.sh |  2 +-
>  t/README           | 18 +++++++++--
>  t/t0000-basic.sh   | 81 +++++++++++++++++++++++++++++++++++++++-------
>  t/test-lib.sh      | 31 +++++++++++++++---
>  4 files changed, 112 insertions(+), 20 deletions(-)
> 
> diff --git a/ci/lib-travisci.sh b/ci/lib-travisci.sh
> index 69dff4d1ec..ad8290bfdb 100755
> --- a/ci/lib-travisci.sh
> +++ b/ci/lib-travisci.sh
> @@ -121,7 +121,7 @@ osx-clang|osx-gcc)
>  	# t9810 occasionally fails on Travis CI OS X
>  	# t9816 occasionally fails with "TAP out of sequence errors" on
>  	# Travis CI OS X
> -	export GIT_SKIP_TESTS="t9810 t9816"
> +	export GIT_TODO_TESTS="t9810 t9816"

This change is not mentioned in the commit message.

As noted in the hunk's context, these test scripts are not skipped
because they don't work on OSX at all, but because they are flaky.
Consequently, reporting them as "maybe should be un-TODO'd" when they
happen to succeed is pointless and will just lead to confusion, so
this seems to be a case when GIT_TODO_TESTS is actually worse than
GIT_SKIP_TESTS.

If a failing test in GIT_TODO_TESTS makes the whole 'make test' fail,
then this should be most definitely left as GIT_SKIP_TESTS.

>  	;;
>  GIT_TEST_GETTEXT_POISON)
>  	export GIT_TEST_GETTEXT_POISON=YesPlease
> diff --git a/t/README b/t/README
> index c03b268813..922b4fb3bf 100644
> --- a/t/README
> +++ b/t/README
> @@ -207,8 +207,19 @@ ideally be reported as bugs and fixed, or guarded by a prerequisite
>  (see "Using test prerequisites" below). But until then they can be
>  skipped.
>  
> -To skip tests, set the GIT_SKIP_TESTS variable. Individual tests can
> -be skipped:
> +To skip tests, set either the GIT_SKIP_TESTS or GIT_TODO_TESTS
> +variables. The difference is that with SKIP the tests won't be run at
> +all, whereas they will be run with TODO, but in success or failure
> +annotated as a TODO test.

This is confusing.  "To skip" a test means that the test is not run at
all.  Now, if GIT_TODO_TESTS were to run the listed tests, then it
definitely won't skip them, so this sentence contradicts the previous
one.

What does "annotated as a TODO test" mean?  Something similar to how
'test_expect_failure' works?

> +It's usually preferrable to use TODO, since the test suite will report
> +those tests that unexpectedly succeed, which may indicate that
> +whatever bug broke the test in the past has been fixed, and the test
> +should be un-TODO'd. There's no such feedback loop with
> +GIT_SKIP_TESTS.
> +
> +The GIT_SKIP_TESTS and GIT_TODO_TESTS take the same values. Individual
> +tests can be skipped:
>  
>      $ GIT_SKIP_TESTS=t9200.8 sh ./t9200-git-cvsexport-commit.sh
>  
> @@ -223,7 +234,8 @@ patterns that tells which tests to skip, and either can match the
>  
>  For an individual test suite --run could be used to specify that
>  only some tests should be run or that some tests should be
> -excluded from a run.
> +excluded from a run. The --run option is a shorthand for setting
> +a GIT_SKIP_TESTS pattern.
>  
>  The argument for --run is a list of individual test numbers or
>  ranges with an optional negation prefix that define what tests in

^ permalink raw reply

* Re: [PATCH v3 07/14] checkout: split into switch-branch and restore-files
From: Duy Nguyen @ 2018-12-04 16:21 UTC (permalink / raw)
  To: Elijah Newren
  Cc: Ævar Arnfjörð Bjarmason, Git Mailing List,
	Junio C Hamano, Stefan Beller, Thomas Gummerer, Stefan Xenos
In-Reply-To: <CABPp-BHQ68pkvO8yXYuy=0D6ne8u=5CUMDqiN0jtRrxCL55n2g@mail.gmail.com>

Thanks for all the comments! There are still some I haven't replied
(either I'll agree and do it anyway, or I'll need some more time to
digest)

On Tue, Dec 4, 2018 at 1:45 AM Elijah Newren <newren@gmail.com> wrote:
> > +'git restore-files' [--from=<tree-ish>] <pathspec>...
>
> Isn't this already inferred by the previous line?  Or was the
> inclusion of --from on the previous line in error?  Looking at the
> git-checkout manpage, it looks like you may have just been copying an
> existing weirdness, but it needs to be fixed.  ;-)

Hehe.

> > +'git restore-files' (-p|--patch) [--from=<tree-ish>] [<pathspec>...]
> > +
> > +DESCRIPTION
> > +-----------
> > +Updates files in the working tree to match the version in the index
> > +or the specified tree.
> > +
> > +'git restore-files' [--from=<tree-ish>] <pathspec>...::
>
> <tree-ish> and <pathspec>?  I understand <commit-ish> and <pathspec>,
> or <tree-ish> but have no clue why it'd be okay to specify <tree-ish>
> and <pathspec> together.  What does that even mean?
>
> Also, rather than fixing from <tree-ish> to <commit-ish> or <commit>,
> perhaps we should just use <revision> here?  (I'm thinking of git
> rev-parse's "Specifying revisions", which suggests "revisions" as a
> good substitute for "commit-ish" that isn't quite so weird for new
> users.)

tree-ish is technically more accurate. But I'm ok with just
<revision>. If you give it a blob oid then you should get a nice
explanation what you're doing wrong anyway.


> > +       Overwrite paths in the working tree by replacing with the
> > +       contents in the index or in the <tree-ish> (most often a
> > +       commit).  When a <tree-ish> is given, the paths that
> > +       match the <pathspec> are updated both in the index and in
> > +       the working tree.
>
> Is that the default we really want for this command?  Why do we
> automatically assume these files are ready for commit?  I understand
> that it's what checkout did, but I'd find it more natural to only
> affect the working tree by default.  We can give it an option for
> affecting the index instead (or perhaps in addition).

Yeah, that behavior of updating the index always bothers me when I use
it but I seemed to forget when working on this.

> > +--ours::
> > +--theirs::
> > +       Check out stage #2 ('ours') or #3 ('theirs') for unmerged
> > +       paths.
> > ++
> > +Note that during `git rebase` and `git pull --rebase`, 'ours' and
> > +'theirs' may appear swapped; `--ours` gives the version from the
> > +branch the changes are rebased onto, while `--theirs` gives the
> > +version from the branch that holds your work that is being rebased.
> > ++
> > +This is because `rebase` is used in a workflow that treats the
> > +history at the remote as the shared canonical one, and treats the
> > +work done on the branch you are rebasing as the third-party work to
> > +be integrated, and you are temporarily assuming the role of the
> > +keeper of the canonical history during the rebase.  As the keeper of
> > +the canonical history, you need to view the history from the remote
> > +as `ours` (i.e. "our shared canonical history"), while what you did
> > +on your side branch as `theirs` (i.e. "one contributor's work on top
> > +of it").
>
> Total aside because I'm not sure what you could change here, but man
> do I hate this.

Uh it's actually documented? I'm always confused by this too. --ours
and --theirs at this point are pretty much tied to stage 2 and 3.
Nothing I can do about it. But if you could come up with some other
option names, then we could make "new ours" to be stage 3 during
rebase, for example.

> > +Part of the linkgit:git[1] suite
>
>
> My single biggest worry about this whole series is that I'm worried
> you're perpetuating and even further ingraining one of the biggest
> usability problems with checkout: people suggest and use it for
> reverting/restoring paths to a previous version, but it doesn't do
> that:
>
> git restore-files --from master~10 Documentation/
> <edit some non-documentation files>
> git add -u
> git commit -m "Rationale for changing files including reverting Documentation/"
>
> In particular, now you have a mixture of files in Documentation/ from
> master~10 (er, now likely master~11) and HEAD~1; any files and
> sub-directories that existed in HEAD~1 still remain and are mixed with
> all other files in Documentation/ from the older commit.
>
> You may think this is a special case, but this particular issue
> results in some pretty bad surprises.  Also, it was pretty surprising
> to me just how difficult it was to implement an svn-like revert in
> EasyGit, in large part because of this 'oversight' in git.  git
> checkout -- <paths> to me has always been fundamentally wrong, but I
> just wasn't sure if I wanted to fight the backward compatibility
> battle and suggest changing it.  With a new command, we definitely
> shouldn't be reinforcing this error.  (And maybe we should consider
> taking the time to fix git checkout too.)

What would be the right behavior for

 git restore-files --from=master~10 Documentation/

then? Consider it an error? I often use "git checkout HEAD" and "git
checkout HEAD^" (usually with -p) but not very far back like
master~10.

> > +If the branch exists in multiple remotes and one of them is named by
> > +the `checkout.defaultRemote` configuration variable, we'll use that
> > +one for the purposes of disambiguation, even if the `<branch>` isn't
> > +unique across all remotes. Set it to
> > +e.g. `checkout.defaultRemote=origin` to always checkout remote
> > +branches from there if `<branch>` is ambiguous but exists on the
> > +'origin' remote. See also `checkout.defaultRemote` in
> > +linkgit:git-config[1].
>
> So switch-branch will be controlled by checkout.* config variables?
> That probably makes the most sense, but it does dilute the advantage
> of adding these simpler commands.
>
> Also, the fact that we're trying to make a simpler command makes me
> think that removing the auto-vivify behavior from the default and
> adding a simple flag which users can pass to request will allow this
> part of the documentation to be hidden behind the appropriate flag,
> which may make it easier for users to compartmentalize the command and
> it's options, enabling them to learn as they go.

Sounds good. I don't know a good name for this new option though so
unless anybody comes up with some suggestion, I'll just disable
checkout.defaultRemote in switch-branch. If it comes back as a new
option, it can always be added later.

> > +'git switch-branch' -c|-C <new_branch> [<start_point>]::
> > +
> > +       Specifying `-c` causes a new branch to be created as if
> > +       linkgit:git-branch[1] were called and then switched to. In
> > +       this case you can use the `--track` or `--no-track` options,
> > +       which will be passed to 'git branch'.  As a convenience,
> > +       `--track` without `-c` implies branch creation; see the
> > +       description of `--track` below.
>
> Can we get rid of --track/--no-track and just provide a flag (which
> takes no arguments) for the user to use?  Problems with --track:
>   * it's not even in your synopsis
>   * user has to repeat themselves (e.g. 'next' in two places from '-c
> next --track origin/next'); this repetition is BOTH laborious AND
> error-prone
>   * it's rather inconsistent: --track is the default due to
> auto-vivify when the user specifies nothing but a branch name that
> doesn't exist yet, but when the user realizes the branch doesn't exist
> yet and asks to have it created then suddenly tracking is not the
> default??

I don't think --track is default anymore (maybe I haven't updated the
man page correctly). The dwim behavior is only activated in
switch-branch when you specify --guess to reduce the amount of magic
we throw at the user. With that in mind, do we still hide
--track/--no-track from switch-branch?

> I'm not sure what's best, but here's some food for thought:
>
>
>    git switch-branch <branch>
> switches to <branch>, if it exists.  Error cases:
>   * If <branch> isn't actually a branch but a <tag> or
> <remote-tracking-branch> or <revision>, error out and suggest using
> --detach.
>   * If <branch> isn't actually a branch but there is a similarly named
> <remote-tracking-branch> (e.g. origin/<branch>), then suggest using
> -c.

I would make these advice so I can hide them. Or if I manage to make
all these hints one line then I'll make it unconditional.

>   git switch-branch -c <branch>
> creates <branch> and, if a relevant-remote-tracking branch exists,
> base the branch on that revision and set the new branch up to track

Hmm.. this is a bit magical and could be surprising. If I create (and
switch to) a new branch foo, I don't necessarily mean tracking
origin/foo (I may not even think about origin/foo when I type the
command). So tentatively no.

> > +If `-C` is given, <new_branch> is created if it doesn't exist;
> > +otherwise, it is reset. This is the transactional equivalent of
> > ++
> > +------------
> > +$ git branch -f <branch> [<start_point>]
> > +$ git switch-branch <branch>
> > +------------
> > ++
> > +that is to say, the branch is not reset/created unless "git
> > +switch-branch" is successful.
>
> ...and when exactly would it fail?  Reading this, it looks like the
> only possible error condition was removed due saying we'll reset the
> branch if it already exists, so it's rather confusing.

Yeah probably just scrape it. The atomic nature is not worth highlighting.


> > +'git switch-branch' --detach [<commit>]::
> > +
> > +       Prepare to work on a unnamed branch on top of <commit> (see
> > +       "DETACHED HEAD" section), and updating the index and the files
> > +       in the working tree.  Local modifications to the files in the
> > +       working tree are kept, so that the resulting working tree will
> > +       be the state recorded in the commit plus the local
> > +       modifications.
> > ++
> > +When the <commit> argument is a branch name, the `--detach` option can
> > +be used to detach HEAD at the tip of the branch (`git switch-branch
> > +<branch>` would check out that branch without detaching HEAD).
> > ++
> > +Omitting <commit> detaches HEAD at the tip of the current branch.
> > +
> > +OPTIONS
> > +-------
> > +-q::
> > +--quiet::
> > +       Quiet, suppress feedback messages.
> > +
> > +--[no-]progress::
> > +       Progress status is reported on the standard error stream
> > +       by default when it is attached to a terminal, unless `--quiet`
> > +       is specified. This flag enables progress reporting even if not
> > +       attached to a terminal, regardless of `--quiet`.
> > +
> > +-f::
> > +--force::
> > +       Proceed even if the index or the working tree differs from
> > +       HEAD.  This is used to throw away local changes.
>
> Haven't thought through this thoroughly, but do we really need an
> option for that instead of telling users to 'git reset --hard HEAD'
> before switching branches if they want their stuff thrown away?

For me it's just a bit more convenient. Hit an error when switching
branch? Recall the command from bash history, stick -f in it and run.
Elsewhere I think both Junio and Thomas (or maybe only Junio) suggests
moving the "git reset" functionality without moving HEAD to one of
these commands, which goes the opposite direction...

> > +-c <new_branch>::
> > +--create <new_branch>::
> > +       Create a new branch named <new_branch> and start it at
> > +       <start_point>; see linkgit:git-branch[1] for details.
> > +
> > +-C <new_branch>::
> > +--force-create <new_branch>::
> > +       Creates the branch <new_branch> and start it at <start_point>;
> > +       if it already exists, then reset it to <start_point>. This is
> > +       equivalent to running "git branch" with "-f"; see
> > +       linkgit:git-branch[1] for details.
>
> Makes sense, but let's get the -b/-B vs. -c/-C consistent.

Another option I'm considering is -n/-N (for _new_ branch). Maybe
-c/-C is good enough.

> > +-l::
> > +       Create the new branch's reflog; see linkgit:git-branch[1] for
> > +       details.
>
> ??  Jettison this.

Yep. It looks weird to me too. reflog is just behind the scene these
days. Nobody need to explicitly ask for reflog anymore.

> > +--orphan <new_branch>::
> > +       Create a new 'orphan' branch, named <new_branch>, started from
> > +       <start_point> and switch to it.  The first commit made on this
>
> What??  started from <start_point>?  The whole point of --orphan is
> you have no parent, i.e. no start point.  Also, why does the
> explanation reference an argument that wasn't in the immediately
> preceding synopsis?

I guess bad phrasing. It should be "switch to <start_point> first,
then prepare the worktree so that the first commit will have no
parent". Or something along that line.

You should really review git-checkout.txt btw ;-)

> > +       new branch will have no parents and it will be the root of a new
> > +       history totally disconnected from all the other branches and
> > +       commits.
> > ++
> > +The index and the working tree are adjusted as if you had previously run
> > +"git checkout <start_point>".  This allows you to start a new history
> > +that records a set of paths similar to <start_point> by easily running
> > +"git commit -a" to make the root commit.
> > ++
> > +This can be useful when you want to publish the tree from a commit
> > +without exposing its full history. You might want to do this to publish
> > +an open source branch of a project whose current tree is "clean", but
> > +whose full history contains proprietary or otherwise encumbered bits of
> > +code.
> > ++
> > +If you want to start a disconnected history that records a set of paths
> > +that is totally different from the one of <start_point>, then you should
> > +clear the index and the working tree right after creating the orphan
> > +branch by running "git rm -rf ." from the top level of the working tree.
> > +Afterwards you will be ready to prepare your new files, repopulating the
> > +working tree, by copying them from elsewhere, extracting a tarball, etc.
>
> Ick.  Seems overly complex.  I'd rather that --orphan defaulted to
> clearing the index and working tree, and that one would need to pass
> HEAD for <start_point> if you wanted to start out with all those other
> files.  That would certainly make the explanation a little clearer to
> users, and more natural when they start experimenting with it.
>
> However, --orphan is pretty special case.  Do we perhaps want to leave
> it out of this new command and only include it in checkout?

I started this by simply splitting git-checkout in two commands that,
combined, can do everything git-checkout can. Then suggestions to have
better default came in and I think we started to drift further to
_removing_ options and falling back to git-checkout.

I think we could still keep "complicated" options as long as they are
clearly described and don't surprise users until they figure them out.
That way I don't have to go back to git-checkout and deal with all the
ambiguation it creates.

> > +-m::
> > +--merge::
> > +       If you have local modifications to one or more files that are
> > +       different between the current branch and the branch to which
> > +       you are switching, the command refuses to switch branches in
> > +       order to preserve your modifications in context.  However,
> > +       with this option, a three-way merge between the current
> > +       branch, your working tree contents, and the new branch is
> > +       done, and you will be on the new branch.
> > ++
> > +When a merge conflict happens, the index entries for conflicting
> > +paths are left unmerged, and you need to resolve the conflicts
> > +and mark the resolved paths with `git add` (or `git rm` if the merge
> > +should result in deletion of the path).
> > +
> > +--conflict=<style>::
> > +       The same as --merge option above, but changes the way the
> > +       conflicting hunks are presented, overriding the
> > +       merge.conflictStyle configuration variable.  Possible values are
> > +       "merge" (default) and "diff3" (in addition to what is shown by
> > +       "merge" style, shows the original contents).
> > +
> > +--ignore-other-worktrees::
> > +       `git switch-branch` refuses when the wanted ref is already
> > +       checked out by another worktree. This option makes it check
> > +       the ref out anyway. In other words, the ref can be held by
> > +       more than one worktree.
>
> seems rather dangerous...is the goal to be an easier-to-use suggestion
> for new users while checkout continues to exist, or is this command
> meant to handle all branch switching functionality that checkout has?

As explained above. I'm still thinking the latter, but with fewer
surprises and confusion. Though I guess I could be convinced to go
with the former (the problem with the former is, even as a
no-longer-new user, I still find git-checkout not that pleasant to use
and want a better replacement)

> > +<branch>::
> > +       Branch to checkout; if it refers to a branch (i.e., a name that,
> > +       when prepended with "refs/heads/", is a valid ref), then that
> > +       branch is checked out. Otherwise, if it refers to a valid
> > +       commit, your HEAD becomes "detached" and you are no longer on
> > +       any branch (see below for details).
>
> I thought we requiring --detach in order to detach.  Does this
> paragraph need updating?  Also, if we require --detach when we'll be
> detaching HEAD, then this paragraph gets a LOT simpler.

Yep. I really need to read through the document and update all of it.

> > +You can use the `"@{-N}"` syntax to refer to the N-th last
> > +branch/commit checked out using "git checkout" operation. You may
> > +also specify `-` which is synonymous to `"@{-1}`.
> > ++
> > +As a special case, you may use `"A...B"` as a shortcut for the
> > +merge base of `A` and `B` if there is exactly one merge base. You can
> > +leave out at most one of `A` and `B`, in which case it defaults to `HEAD`.
>
> I actually didn't know about the A...B special case for checkout.
> Interesting...but I'm starting to wonder if this is too much info for
> a "simplified command".

I could just hint about A...B and send the user to git-checkout.txt if
they need to know more. They can learn about git-checkout that way
too.
-- 
Duy

^ permalink raw reply

* Re: [PATCH/RFC v3 00/14] Introduce new commands switch-branch and restore-files
From: Duy Nguyen @ 2018-12-04 16:27 UTC (permalink / raw)
  To: Elijah Newren
  Cc: Ævar Arnfjörð Bjarmason, Git Mailing List,
	Junio C Hamano, Stefan Beller, Thomas Gummerer, Stefan Xenos
In-Reply-To: <CABPp-BGsw3cxU4Y+-UMcwk=skyuvgU_Rfkyh0o1rRPwOv_LDDA@mail.gmail.com>

On Tue, Dec 4, 2018 at 2:29 AM Elijah Newren <newren@gmail.com> wrote:
>
> On Thu, Nov 29, 2018 at 2:01 PM Nguyễn Thái Ngọc Duy <pclouds@gmail.com> wrote:
> >
> > v3 sees switch-branch go back to switch-branch (in v2 it was
> > checkout-branch). checkout-files is also renamed restore-files (v1 was
> > restore-paths). Hopefully we won't see another rename.
>
> I started reading through the patches.  I also tried to apply them
> locally, but they had conflicts or missing base file version on both
> master and next.  What version did you base it on?

I think nd/checkout-dwim-fix because of a non-trivial conflict there
(but I don't remember when I noticed it and rebased on that). Anyway
you can get the whole series at

https://gitlab.com/pclouds/git/tree/switch-branch-and-checkout-files

It fixes some of your comments already, a couple of bug fixes here and
there and in a good-enough shape that I start actually using it.

> > - Two more fancy features (the "git checkout --index" being the
> >   default mode and the backup log for accidental overwrites) are of
> >   course still missing. But they are coming.
> >
> > I did not go replace "detached HEAD" with "unnamed branch" (or "no
> > branch") everywhere because I think a unique term is still good to
> > refer to this concept. Or maybe "no branch" is good enough. I dunno.
>
> I personally like "unnamed branch", but "no branch" would still be
> better than "detached HEAD".

Haven't really worked on killing the term "detached HEAD" yet. But I
noticed the other day that git-branch reports

* (HEAD detached from 703266f6e4)

and I didn't know how to rephrase that. I guess "unnamed branch from
703266f6e4" is probably good enough but my old-timer brain screams no.
-- 
Duy

^ permalink raw reply

* [RFC PATCH 0/3] test-lib: add the '--stress' option to help reproduce occasional failures in flaky tests
From: SZEDER Gábor @ 2018-12-04 16:34 UTC (permalink / raw)
  To: git; +Cc: Jeff King, SZEDER Gábor

Inspired by Peff's 'stress' script mentioned in:

  https://public-inbox.org/git/20181122161722.GC28192@sigill.intra.peff.net/

the last patch in this series brings that functionality to our test
library to help to reproduce failures in flaky tests.  So

  ./t1234-foo --stress
  
will run that test script repeatedly in multiple parallel invocations,
in the hope that the increased load creates enough variance in the
timing of the test's commands that a failure is evenually triggered.


SZEDER Gábor (3):
  test-lib: consolidate naming of test-results paths
  test-lib-functions: introduce the 'test_set_port' helper function
  test-lib: add the '--stress' option to run a test repeatedly under
    load

 t/README                 | 13 +++++-
 t/lib-git-daemon.sh      |  2 +-
 t/lib-git-p4.sh          |  9 +---
 t/lib-git-svn.sh         |  2 +-
 t/lib-httpd.sh           |  2 +-
 t/t0410-partial-clone.sh |  1 -
 t/t5512-ls-remote.sh     |  2 +-
 t/test-lib-functions.sh  | 39 ++++++++++++++++
 t/test-lib.sh            | 99 +++++++++++++++++++++++++++++++++++-----
 9 files changed, 143 insertions(+), 26 deletions(-)

-- 
2.20.0.rc2.156.g5a9fd2ce9c


^ permalink raw reply

* [PATCH 1/3] test-lib: consolidate naming of test-results paths
From: SZEDER Gábor @ 2018-12-04 16:34 UTC (permalink / raw)
  To: git; +Cc: Jeff King, SZEDER Gábor
In-Reply-To: <20181204163457.15717-1-szeder.dev@gmail.com>

There are two places where we strip off any leading path components
and the '.sh' suffix from the test script's pathname, and there are
two places where we construct the filename of test output files in
't/test-results/'.  The last patch in this series will add even more.

Factor these out into helper variables to avoid repeating ourselves.

Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
---
 t/test-lib.sh | 21 ++++++++++-----------
 1 file changed, 10 insertions(+), 11 deletions(-)

diff --git a/t/test-lib.sh b/t/test-lib.sh
index 0f1faa24b2..49e4563405 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -71,6 +71,9 @@ then
 	exit 1
 fi
 
+TEST_NAME="$(basename "$0" .sh)"
+TEST_RESULTS_BASE="$TEST_OUTPUT_DIRECTORY/test-results/$TEST_NAME"
+
 # if --tee was passed, write the output not only to the terminal, but
 # additionally to the file test-results/$BASENAME.out, too.
 case "$GIT_TEST_TEE_STARTED, $* " in
@@ -78,12 +81,11 @@ done,*)
 	# do not redirect again
 	;;
 *' --tee '*|*' --va'*|*' -V '*|*' --verbose-log '*)
-	mkdir -p "$TEST_OUTPUT_DIRECTORY/test-results"
-	BASE="$TEST_OUTPUT_DIRECTORY/test-results/$(basename "$0" .sh)"
+	mkdir -p "$(dirname "$TEST_RESULTS_BASE")"
 
 	# Make this filename available to the sub-process in case it is using
 	# --verbose-log.
-	GIT_TEST_TEE_OUTPUT_FILE=$BASE.out
+	GIT_TEST_TEE_OUTPUT_FILE=$TEST_RESULTS_BASE.out
 	export GIT_TEST_TEE_OUTPUT_FILE
 
 	# Truncate before calling "tee -a" to get rid of the results
@@ -91,8 +93,8 @@ done,*)
 	>"$GIT_TEST_TEE_OUTPUT_FILE"
 
 	(GIT_TEST_TEE_STARTED=done ${TEST_SHELL_PATH} "$0" "$@" 2>&1;
-	 echo $? >"$BASE.exit") | tee -a "$GIT_TEST_TEE_OUTPUT_FILE"
-	test "$(cat "$BASE.exit")" = 0
+	 echo $? >"$TEST_RESULTS_BASE.exit") | tee -a "$GIT_TEST_TEE_OUTPUT_FILE"
+	test "$(cat "$TEST_RESULTS_BASE.exit")" = 0
 	exit
 	;;
 esac
@@ -818,12 +820,9 @@ test_done () {
 
 	if test -z "$HARNESS_ACTIVE"
 	then
-		test_results_dir="$TEST_OUTPUT_DIRECTORY/test-results"
-		mkdir -p "$test_results_dir"
-		base=${0##*/}
-		test_results_path="$test_results_dir/${base%.sh}.counts"
+		mkdir -p "$(dirname "$TEST_RESULTS_BASE")"
 
-		cat >"$test_results_path" <<-EOF
+		cat >"$TEST_RESULTS_BASE.counts" <<-EOF
 		total $test_count
 		success $test_success
 		fixed $test_fixed
@@ -1029,7 +1028,7 @@ then
 fi
 
 # Test repository
-TRASH_DIRECTORY="trash directory.$(basename "$0" .sh)"
+TRASH_DIRECTORY="trash directory.$TEST_NAME"
 test -n "$root" && TRASH_DIRECTORY="$root/$TRASH_DIRECTORY"
 case "$TRASH_DIRECTORY" in
 /*) ;; # absolute path is good
-- 
2.20.0.rc2.156.g5a9fd2ce9c


^ permalink raw reply related

* [PATCH 2/3] test-lib-functions: introduce the 'test_set_port' helper function
From: SZEDER Gábor @ 2018-12-04 16:34 UTC (permalink / raw)
  To: git; +Cc: Jeff King, SZEDER Gábor
In-Reply-To: <20181204163457.15717-1-szeder.dev@gmail.com>

Several test scripts run daemons like 'git-daemon' or Apache, and
communicate with them through TCP sockets.  To have unique ports where
these daemons are accessible, the ports are usually the number of the
corresponding test scripts, unless the user overrides them via
environment variables, and thus all those tests and test libs contain
more or less the same bit of one-liner boilerplate code to find out
the port.  The last patch in this series will make this a bit more
complicated.

Factor out finding the port for a daemon into the common helper
function 'test_set_port' to avoid repeating ourselves.

Take special care of test scripts with "low" numbers:

  - Test numbers below 1024 would result in a port that's only usable
    as root, so set their port to '10000 + test-nr' to make sure it
    doesn't interfere with other tests in the test suite.  This makes
    the hardcoded port number in 't0410-partial-clone.sh' unnecessary,
    remove it.

  - The shell's arithmetic evaluation interprets numbers with leading
    zeros as octal values, which means that test number below 1000 and
    containing the digits 8 or 9 will trigger an error.  Remove all
    leading zeros from the test numbers to prevent this.

Note that the Perforce tests are unlike the other tests involving
daemons in that:

  - 'lib-git-p4.sh' doesn't use the test's number for unique port as
    is, but does a bit of additional arithmetic on top [1].

  - The port is not overridable via an environment variable.

With this patch even Perforce tests will use the test's number as
default port, and it will be overridable via the P4DPORT environment
variable.

[1] Commit fc00233071 (git-p4 tests: refactor and cleanup, 2011-08-22)
    introduced that "unusual" unique port computation without
    explaining why it was necessary (as opposed to simply using the
    test number as is).  It seems to be just unnecessary complication,
    and in any case that commit came way before the "test nr as unique
    port" got "standardized" for other daemons in commits c44132fcf3
    (tests: auto-set git-daemon port, 2014-02-10), 3bb486e439 (tests:
    auto-set LIB_HTTPD_PORT from test name, 2014-02-10), and
    bf9d7df950 (t/lib-git-svn.sh: improve svnserve tests with parallel
    make test, 2017-12-01).

Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
---
 t/lib-git-daemon.sh      |  2 +-
 t/lib-git-p4.sh          |  9 +--------
 t/lib-git-svn.sh         |  2 +-
 t/lib-httpd.sh           |  2 +-
 t/t0410-partial-clone.sh |  1 -
 t/t5512-ls-remote.sh     |  2 +-
 t/test-lib-functions.sh  | 36 ++++++++++++++++++++++++++++++++++++
 7 files changed, 41 insertions(+), 13 deletions(-)

diff --git a/t/lib-git-daemon.sh b/t/lib-git-daemon.sh
index f98de95c15..41eb1e3ae8 100644
--- a/t/lib-git-daemon.sh
+++ b/t/lib-git-daemon.sh
@@ -28,7 +28,7 @@ then
 	test_skip_or_die $GIT_TEST_GIT_DAEMON "file system does not support FIFOs"
 fi
 
-LIB_GIT_DAEMON_PORT=${LIB_GIT_DAEMON_PORT-${this_test#t}}
+test_set_port LIB_GIT_DAEMON_PORT
 
 GIT_DAEMON_PID=
 GIT_DAEMON_DOCUMENT_ROOT_PATH="$PWD"/repo
diff --git a/t/lib-git-p4.sh b/t/lib-git-p4.sh
index c27599474c..b3be3ba011 100644
--- a/t/lib-git-p4.sh
+++ b/t/lib-git-p4.sh
@@ -53,14 +53,7 @@ time_in_seconds () {
 	(cd / && "$PYTHON_PATH" -c 'import time; print(int(time.time()))')
 }
 
-# Try to pick a unique port: guess a large number, then hope
-# no more than one of each test is running.
-#
-# This does not handle the case where somebody else is running the
-# same tests and has chosen the same ports.
-testid=${this_test#t}
-git_p4_test_start=9800
-P4DPORT=$((10669 + ($testid - $git_p4_test_start)))
+test_set_port P4DPORT
 
 P4PORT=localhost:$P4DPORT
 P4CLIENT=client
diff --git a/t/lib-git-svn.sh b/t/lib-git-svn.sh
index a8130f9119..f3b478c307 100644
--- a/t/lib-git-svn.sh
+++ b/t/lib-git-svn.sh
@@ -13,6 +13,7 @@ fi
 GIT_DIR=$PWD/.git
 GIT_SVN_DIR=$GIT_DIR/svn/refs/remotes/git-svn
 SVN_TREE=$GIT_SVN_DIR/svn-tree
+test_set_port SVNSERVE_PORT
 
 svn >/dev/null 2>&1
 if test $? -ne 1
@@ -119,7 +120,6 @@ require_svnserve () {
 }
 
 start_svnserve () {
-	SVNSERVE_PORT=${SVNSERVE_PORT-${this_test#t}}
 	svnserve --listen-port $SVNSERVE_PORT \
 		 --root "$rawsvnrepo" \
 		 --listen-once \
diff --git a/t/lib-httpd.sh b/t/lib-httpd.sh
index a8729f8232..e465116ef9 100644
--- a/t/lib-httpd.sh
+++ b/t/lib-httpd.sh
@@ -82,7 +82,7 @@ case $(uname) in
 esac
 
 LIB_HTTPD_PATH=${LIB_HTTPD_PATH-"$DEFAULT_HTTPD_PATH"}
-LIB_HTTPD_PORT=${LIB_HTTPD_PORT-${this_test#t}}
+test_set_port LIB_HTTPD_PORT
 
 TEST_PATH="$TEST_DIRECTORY"/lib-httpd
 HTTPD_ROOT_PATH="$PWD"/httpd
diff --git a/t/t0410-partial-clone.sh b/t/t0410-partial-clone.sh
index ba3887f178..0aca8d7588 100755
--- a/t/t0410-partial-clone.sh
+++ b/t/t0410-partial-clone.sh
@@ -480,7 +480,6 @@ test_expect_success 'gc stops traversal when a missing but promised object is re
 	! grep "$TREE_HASH" out
 '
 
-LIB_HTTPD_PORT=12345  # default port, 410, cannot be used as non-root
 . "$TEST_DIRECTORY"/lib-httpd.sh
 start_httpd
 
diff --git a/t/t5512-ls-remote.sh b/t/t5512-ls-remote.sh
index 32e722db2e..cd9e60632d 100755
--- a/t/t5512-ls-remote.sh
+++ b/t/t5512-ls-remote.sh
@@ -260,7 +260,7 @@ test_lazy_prereq GIT_DAEMON '
 # This test spawns a daemon, so run it only if the user would be OK with
 # testing with git-daemon.
 test_expect_success PIPE,JGIT,GIT_DAEMON 'indicate no refs in standards-compliant empty remote' '
-	JGIT_DAEMON_PORT=${JGIT_DAEMON_PORT-${this_test#t}} &&
+	test_set_port JGIT_DAEMON_PORT &&
 	JGIT_DAEMON_PID= &&
 	git init --bare empty.git &&
 	>empty.git/git-daemon-export-ok &&
diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh
index 6b3bbf99e4..d9a602cd0f 100644
--- a/t/test-lib-functions.sh
+++ b/t/test-lib-functions.sh
@@ -1263,3 +1263,39 @@ test_oid () {
 	fi &&
 	eval "printf '%s' \"\${$var}\""
 }
+
+# Choose a port number based on the test script's number and store it in
+# the given variable name, unless that variable already contains a number.
+test_set_port () {
+	local var=$1 port
+
+	if test $# -ne 1 || test -z "$var"
+	then
+		BUG "test_set_port requires a variable name"
+	fi
+
+	eval port=\"\${$var}\"
+	case "$port" in
+	"")
+		# No port is set in the given env var, use the test
+		# number as port number instead.
+		# Remove not only the leading 't', but all leading zeros
+		# as well, so the arithmetic below won't (mis)interpret
+		# a test number like '0123' as an octal value.
+		port=${this_test#${this_test%%[1-9]*}}
+		if test "${port:-0}" -lt 1024
+		then
+			# root-only port, use a larger one instead.
+			port=$(($port + 10000))
+		fi
+
+		eval $var=$port
+		;;
+	*[^0-9]*)
+		error >&7 "invalid port number: $port"
+		;;
+	*)
+		# The user has specified the port.
+		;;
+	esac
+}
-- 
2.20.0.rc2.156.g5a9fd2ce9c


^ permalink raw reply related

* [RFC PATCH 3/3] test-lib: add the '--stress' option to run a test repeatedly under load
From: SZEDER Gábor @ 2018-12-04 16:34 UTC (permalink / raw)
  To: git; +Cc: Jeff King, SZEDER Gábor
In-Reply-To: <20181204163457.15717-1-szeder.dev@gmail.com>

Unfortunately, we have a few flaky tests, whose failures tend to be
hard to reproduce.  We've found that the best we can do to reproduce
such a failure is to run the test repeatedly while the machine is
under load, and wait in the hope that the load creates enough variance
in the timing of the test's commands that a failure is evenually
triggered.  I have a command to do that, and I noticed that two other
contributors have rolled their own scripts to do the same, all
choosing slightly different approaches.

To help reproduce failures in flaky tests, introduce the '--stress'
option to run a test script repeatedly in multiple parallel
invocations until one of them fails, thereby using the test script
itself to increase the load on the machine.

The number of parallel invocations is determined by, in order of
precedence: the number specified as '--stress=<N>', or the value of
the GIT_TEST_STRESS_LOAD environment variable, or twice the number of
available processors in '/proc/cpuinfo', or 8.

To prevent the several parallel invocations of the same test from
interfering with each other:

  - Include the parallel job's number in the name of the trash
    directory and the various output files under 't/test-results/' as
    a '.stress-<Nr>' suffix.

  - Add the parallel job's number to the port number specified by the
    user or to the test number, so even tests involving daemons
    listening on a TCP socket can be stressed.

  - Make '--stress' imply '--verbose-log' and discard the test's
    standard ouput and error; dumping the output of several parallel
    tests to the terminal would create a big ugly mess.

'wait' for all parallel jobs before exiting (either because a failure
was found or because the user lost patience and aborted the stress
test), allowing the still running tests to finish.  Otherwise the "OK
X.Y" progress output from the last iteration would likely arrive after
the user got back the shell prompt, interfering with typing in the
next command.  OTOH, this waiting might induce a considerable delay
between hitting ctrl-C and the test actually exiting; I'm not sure
this is the right tradeoff.

Based on Jeff King's 'stress' script.

Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
---
 t/README                | 13 ++++++-
 t/test-lib-functions.sh |  7 +++-
 t/test-lib.sh           | 82 +++++++++++++++++++++++++++++++++++++++--
 3 files changed, 96 insertions(+), 6 deletions(-)

diff --git a/t/README b/t/README
index 28711cc508..9851de25c2 100644
--- a/t/README
+++ b/t/README
@@ -186,6 +186,16 @@ appropriately before running "make".
 	this feature by setting the GIT_TEST_CHAIN_LINT environment
 	variable to "1" or "0", respectively.
 
+--stress::
+--stress=<N>::
+	Run the test script repeatedly in multiple parallel
+	invocations until one of them fails.  Useful for reproducing
+	rare failures in flaky tests.  The number of parallel
+	invocations is, in order of precedence: <N>, or the value of
+	the GIT_TEST_STRESS_LOAD environment variable, or twice the
+	number of available processors in '/proc/cpuinfo', or 8.
+	Implies `--verbose-log`.
+
 You can also set the GIT_TEST_INSTALLED environment variable to
 the bindir of an existing git installation to test that installation.
 You still need to have built this git sandbox, from which various
@@ -425,7 +435,8 @@ This test harness library does the following things:
  - Creates an empty test directory with an empty .git/objects database
    and chdir(2) into it.  This directory is 't/trash
    directory.$test_name_without_dotsh', with t/ subject to change by
-   the --root option documented above.
+   the --root option documented above, and a '.stress-<N>' suffix
+   appended by the --stress option.
 
  - Defines standard test helper functions for your scripts to
    use.  These functions are designed to make all scripts behave
diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh
index d9a602cd0f..9af11e3eed 100644
--- a/t/test-lib-functions.sh
+++ b/t/test-lib-functions.sh
@@ -1288,8 +1288,6 @@ test_set_port () {
 			# root-only port, use a larger one instead.
 			port=$(($port + 10000))
 		fi
-
-		eval $var=$port
 		;;
 	*[^0-9]*)
 		error >&7 "invalid port number: $port"
@@ -1298,4 +1296,9 @@ test_set_port () {
 		# The user has specified the port.
 		;;
 	esac
+
+	# Make sure that parallel '--stress' test jobs get different
+	# ports.
+	port=$(($port + ${GIT_TEST_STRESS_JOB_NR:-0}))
+	eval $var=$port
 }
diff --git a/t/test-lib.sh b/t/test-lib.sh
index 49e4563405..9b7f687396 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -71,8 +71,81 @@ then
 	exit 1
 fi
 
+TEST_STRESS_SFX="${GIT_TEST_STRESS_JOB_NR:+.stress-$GIT_TEST_STRESS_JOB_NR}"
 TEST_NAME="$(basename "$0" .sh)"
-TEST_RESULTS_BASE="$TEST_OUTPUT_DIRECTORY/test-results/$TEST_NAME"
+TEST_RESULTS_BASE="$TEST_OUTPUT_DIRECTORY/test-results/$TEST_NAME$TEST_STRESS_SFX"
+
+# If --stress was passed, run this test repeatedly in several parallel loops.
+case "$GIT_TEST_STRESS_STARTED, $* " in
+done,*)
+	# Don't stress test again.
+	;;
+*' --stress '*|*' '--stress=*' '*)
+	job_count=${*##*--stress=}
+	if test "$job_count" != "$*"
+	then
+		job_count=${job_count%% *}
+	elif test -n "$GIT_TEST_STRESS_LOAD"
+	then
+		job_count="$GIT_TEST_STRESS_LOAD"
+	elif test -r /proc/cpuinfo
+	then
+		job_count=$((2 * $(grep -c ^processor /proc/cpuinfo)))
+	else
+		job_count=8
+	fi
+
+	mkdir -p "$(dirname "$TEST_RESULTS_BASE")"
+	stressfail="$TEST_RESULTS_BASE.stress-failed"
+	rm -f "$stressfail"
+	trap 'echo aborted >"$stressfail"' TERM INT HUP
+
+	job_nr=0
+	while test $job_nr -lt "$job_count"
+	do
+		(
+			GIT_TEST_STRESS_STARTED=done
+			GIT_TEST_STRESS_JOB_NR=$job_nr
+			export GIT_TEST_STRESS_STARTED GIT_TEST_STRESS_JOB_NR
+
+			cnt=0
+			while ! test -e "$stressfail"
+			do
+				if $TEST_SHELL_PATH "$0" "$@" >/dev/null 2>&1
+				then
+					printf >&2 "OK   %2d.%d\n" $GIT_TEST_STRESS_JOB_NR $cnt
+				elif test -f "$stressfail" &&
+				     test "$(cat "$stressfail")" = "aborted"
+				then
+					printf >&2 "ABORTED %2d.%d\n" $GIT_TEST_STRESS_JOB_NR $cnt
+				else
+					printf >&2 "FAIL %2d.%d\n" $GIT_TEST_STRESS_JOB_NR $cnt
+					echo $GIT_TEST_STRESS_JOB_NR >>"$stressfail"
+				fi
+				cnt=$(($cnt + 1))
+			done
+		) &
+		job_nr=$(($job_nr + 1))
+	done
+
+	job_nr=0
+	while test $job_nr -lt "$job_count"
+	do
+		wait
+		job_nr=$(($job_nr + 1))
+	done
+
+	if test -f "$stressfail" && test "$(cat "$stressfail")" != "aborted"
+	then
+		echo "Log(s) of failed test run(s) be found in:"
+		for f in $(cat "$stressfail")
+		do
+			echo "  $TEST_RESULTS_BASE.stress-$f.out"
+		done
+	fi
+	exit
+	;;
+esac
 
 # if --tee was passed, write the output not only to the terminal, but
 # additionally to the file test-results/$BASENAME.out, too.
@@ -80,7 +153,7 @@ case "$GIT_TEST_TEE_STARTED, $* " in
 done,*)
 	# do not redirect again
 	;;
-*' --tee '*|*' --va'*|*' -V '*|*' --verbose-log '*)
+*' --tee '*|*' --va'*|*' -V '*|*' --verbose-log '*|*' --stress '*|*' '--stress=*' '*)
 	mkdir -p "$(dirname "$TEST_RESULTS_BASE")"
 
 	# Make this filename available to the sub-process in case it is using
@@ -341,6 +414,9 @@ do
 	-V|--verbose-log)
 		verbose_log=t
 		shift ;;
+	--stress|--stress=*)
+		verbose_log=t
+		shift ;;
 	*)
 		echo "error: unknown test option '$1'" >&2; exit 1 ;;
 	esac
@@ -1028,7 +1104,7 @@ then
 fi
 
 # Test repository
-TRASH_DIRECTORY="trash directory.$TEST_NAME"
+TRASH_DIRECTORY="trash directory.$TEST_NAME$TEST_STRESS_SFX"
 test -n "$root" && TRASH_DIRECTORY="$root/$TRASH_DIRECTORY"
 case "$TRASH_DIRECTORY" in
 /*) ;; # absolute path is good
-- 
2.20.0.rc2.156.g5a9fd2ce9c


^ permalink raw reply related

* Re: [RFC PATCH 3/3] test-lib: add the '--stress' option to run a test repeatedly under load
From: Ævar Arnfjörð Bjarmason @ 2018-12-04 17:04 UTC (permalink / raw)
  To: SZEDER Gábor; +Cc: git, Jeff King
In-Reply-To: <20181204163457.15717-4-szeder.dev@gmail.com>


On Tue, Dec 04 2018, SZEDER Gábor wrote:

> The number of parallel invocations is determined by, in order of
> precedence: the number specified as '--stress=<N>', or the value of
> the GIT_TEST_STRESS_LOAD environment variable, or twice the number of
> available processors in '/proc/cpuinfo', or 8.

With this series we have at least 3 ways to get this number. First
online_cpus() in the C code, then Peff's recent `getconf
_NPROCESSORS_ONLN` in doc-diff, and now this /proc/cpuinfo parsing.

Perhaps it makes sense to split online_cpus() into a helper to use from
the shellscripts instead?

^ permalink raw reply

* Re: [RFC PATCH 3/3] test-lib: add the '--stress' option to run a test repeatedly under load
From: SZEDER Gábor @ 2018-12-04 17:37 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason; +Cc: git, Jeff King
In-Reply-To: <87o9a1z0j5.fsf@evledraar.gmail.com>

On Tue, Dec 04, 2018 at 06:04:14PM +0100, Ævar Arnfjörð Bjarmason wrote:
> 
> On Tue, Dec 04 2018, SZEDER Gábor wrote:
> 
> > The number of parallel invocations is determined by, in order of
> > precedence: the number specified as '--stress=<N>', or the value of
> > the GIT_TEST_STRESS_LOAD environment variable, or twice the number of
> > available processors in '/proc/cpuinfo', or 8.
> 
> With this series we have at least 3 ways to get this number. First
> online_cpus() in the C code, then Peff's recent `getconf
> _NPROCESSORS_ONLN` in doc-diff, and now this /proc/cpuinfo parsing.
> 
> Perhaps it makes sense to split online_cpus() into a helper to use from
> the shellscripts instead?

I don't think so, but I will update this patch to use 'getconf'
instead.


^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox