* [PATCH v4 4/8] test-lib: parse command line options earlier
From: SZEDER Gábor @ 2019-01-05 1:08 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Jeff King, git, SZEDER Gábor
In-Reply-To: <20190105010859.11031-1-szeder.dev@gmail.com>
'test-lib.sh' looks for the presence of certain options like '--tee'
and '--verbose-log', so it can execute the test script again to save
its standard output and error. It looks for '--valgrind' as well, to
set up some Valgrind-specific stuff. These all happen before the
actual option parsing loop, and the conditions looking for these
options look a bit odd, too. They are not completely correct, either,
because in a bogus invocation like './t1234-foo.sh -r --tee' they
recognize '--tee', although it should be handled as the required
argument of the '-r' option. This patch series will add two more
options to look out for early, and, in addition, will have to extract
these options' stuck arguments (i.e. '--opt=arg') as well.
So let's move the option parsing loop and the couple of related
conditions following it earlier in 'test-lib.sh', before the place
where the test script is executed again for '--tee' and its friends.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
---
t/test-lib.sh | 233 +++++++++++++++++++++++++++-----------------------
1 file changed, 124 insertions(+), 109 deletions(-)
diff --git a/t/test-lib.sh b/t/test-lib.sh
index 3cf59a92f0..14ccb60838 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -71,13 +71,102 @@ then
exit 1
fi
+# Parse options while taking care to leave $@ intact, so we will still
+# have all the original command line options when executing the test
+# script again for '--tee' and '--verbose-log' below.
+store_arg_to=
+prev_opt=
+for opt
+do
+ if test -n "$store_arg_to"
+ then
+ eval $store_arg_to=\$opt
+ store_arg_to=
+ prev_opt=
+ continue
+ fi
+
+ case "$opt" in
+ -d|--d|--de|--deb|--debu|--debug)
+ debug=t ;;
+ -i|--i|--im|--imm|--imme|--immed|--immedi|--immedia|--immediat|--immediate)
+ immediate=t ;;
+ -l|--l|--lo|--lon|--long|--long-|--long-t|--long-te|--long-tes|--long-test|--long-tests)
+ GIT_TEST_LONG=t; export GIT_TEST_LONG ;;
+ -r)
+ store_arg_to=run_list
+ ;;
+ --run=*)
+ run_list=${opt#--*=} ;;
+ -h|--h|--he|--hel|--help)
+ help=t ;;
+ -v|--v|--ve|--ver|--verb|--verbo|--verbos|--verbose)
+ verbose=t ;;
+ --verbose-only=*)
+ verbose_only=${opt#--*=}
+ ;;
+ -q|--q|--qu|--qui|--quie|--quiet)
+ # Ignore --quiet under a TAP::Harness. Saying how many tests
+ # passed without the ok/not ok details is always an error.
+ test -z "$HARNESS_ACTIVE" && quiet=t ;;
+ --with-dashes)
+ with_dashes=t ;;
+ --no-color)
+ color= ;;
+ --va|--val|--valg|--valgr|--valgri|--valgrin|--valgrind)
+ valgrind=memcheck
+ tee=t
+ ;;
+ --valgrind=*)
+ valgrind=${opt#--*=}
+ tee=t
+ ;;
+ --valgrind-only=*)
+ valgrind_only=${opt#--*=}
+ tee=t
+ ;;
+ --tee)
+ tee=t ;;
+ --root=*)
+ root=${opt#--*=} ;;
+ --chain-lint)
+ GIT_TEST_CHAIN_LINT=1 ;;
+ --no-chain-lint)
+ GIT_TEST_CHAIN_LINT=0 ;;
+ -x)
+ trace=t ;;
+ -V|--verbose-log)
+ verbose_log=t
+ tee=t
+ ;;
+ *)
+ echo "error: unknown test option '$opt'" >&2; exit 1 ;;
+ esac
+
+ prev_opt=$opt
+done
+if test -n "$store_arg_to"
+then
+ echo "error: $prev_opt requires an argument" >&2
+ exit 1
+fi
+
+if test -n "$valgrind_only"
+then
+ test -z "$valgrind" && valgrind=memcheck
+ test -z "$verbose" && verbose_only="$valgrind_only"
+elif test -n "$valgrind"
+then
+ test -z "$verbose_log" && verbose=t
+fi
+
# 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
-done,*)
- # do not redirect again
- ;;
-*' --tee '*|*' --va'*|*' -V '*|*' --verbose-log '*)
+if test "$GIT_TEST_TEE_STARTED" = "done"
+then
+ : # do not redirect again
+elif test -n "$tee"
+then
mkdir -p "$TEST_OUTPUT_DIRECTORY/test-results"
BASE="$TEST_OUTPUT_DIRECTORY/test-results/$(basename "$0" .sh)"
@@ -94,8 +183,35 @@ done,*)
echo $? >"$BASE.exit") | tee -a "$GIT_TEST_TEE_OUTPUT_FILE"
test "$(cat "$BASE.exit")" = 0
exit
- ;;
-esac
+fi
+
+if test -n "$trace" && test -n "$test_untraceable"
+then
+ # '-x' tracing requested, but this test script can't be reliably
+ # traced, unless it is run with a Bash version supporting
+ # BASH_XTRACEFD (introduced in Bash v4.1).
+ #
+ # Perform this version check _after_ the test script was
+ # potentially re-executed with $TEST_SHELL_PATH for '--tee' or
+ # '--verbose-log', so the right shell is checked and the
+ # warning is issued only once.
+ if test -n "$BASH_VERSION" && eval '
+ test ${BASH_VERSINFO[0]} -gt 4 || {
+ test ${BASH_VERSINFO[0]} -eq 4 &&
+ test ${BASH_VERSINFO[1]} -ge 1
+ }
+ '
+ then
+ : Executed by a Bash version supporting BASH_XTRACEFD. Good.
+ else
+ echo >&2 "warning: ignoring -x; '$0' is untraceable without BASH_XTRACEFD"
+ trace=
+ fi
+fi
+if test -n "$trace" && test -z "$verbose_log"
+then
+ verbose=t
+fi
# For repeatability, reset the environment to known value.
# TERM is sanitized below, after saving color control sequences.
@@ -193,7 +309,7 @@ fi
# Add libc MALLOC and MALLOC_PERTURB test
# only if we are not executing the test with valgrind
-if expr " $GIT_TEST_OPTS " : ".* --valgrind " >/dev/null ||
+if test -n "$valgrind" ||
test -n "$TEST_NO_MALLOC_CHECK"
then
setup_malloc_check () {
@@ -264,107 +380,6 @@ test "x$TERM" != "xdumb" && (
) &&
color=t
-store_arg_to=
-prev_opt=
-for opt
-do
- if test -n "$store_arg_to"
- then
- eval $store_arg_to=\$opt
- store_arg_to=
- prev_opt=
- continue
- fi
-
- case "$opt" in
- -d|--d|--de|--deb|--debu|--debug)
- debug=t ;;
- -i|--i|--im|--imm|--imme|--immed|--immedi|--immedia|--immediat|--immediate)
- immediate=t ;;
- -l|--l|--lo|--lon|--long|--long-|--long-t|--long-te|--long-tes|--long-test|--long-tests)
- GIT_TEST_LONG=t; export GIT_TEST_LONG ;;
- -r)
- store_arg_to=run_list
- ;;
- --run=*)
- run_list=${opt#--*=} ;;
- -h|--h|--he|--hel|--help)
- help=t ;;
- -v|--v|--ve|--ver|--verb|--verbo|--verbos|--verbose)
- verbose=t ;;
- --verbose-only=*)
- verbose_only=${opt#--*=}
- ;;
- -q|--q|--qu|--qui|--quie|--quiet)
- # Ignore --quiet under a TAP::Harness. Saying how many tests
- # passed without the ok/not ok details is always an error.
- test -z "$HARNESS_ACTIVE" && quiet=t ;;
- --with-dashes)
- with_dashes=t ;;
- --no-color)
- color= ;;
- --va|--val|--valg|--valgr|--valgri|--valgrin|--valgrind)
- valgrind=memcheck ;;
- --valgrind=*)
- valgrind=${opt#--*=} ;;
- --valgrind-only=*)
- valgrind_only=${opt#--*=} ;;
- --tee)
- ;; # was handled already
- --root=*)
- root=${opt#--*=} ;;
- --chain-lint)
- GIT_TEST_CHAIN_LINT=1 ;;
- --no-chain-lint)
- GIT_TEST_CHAIN_LINT=0 ;;
- -x)
- trace=t ;;
- -V|--verbose-log)
- verbose_log=t ;;
- *)
- echo "error: unknown test option '$opt'" >&2; exit 1 ;;
- esac
-
- prev_opt=$opt
-done
-if test -n "$store_arg_to"
-then
- echo "error: $prev_opt requires an argument" >&2
- exit 1
-fi
-
-if test -n "$valgrind_only"
-then
- test -z "$valgrind" && valgrind=memcheck
- test -z "$verbose" && verbose_only="$valgrind_only"
-elif test -n "$valgrind"
-then
- test -z "$verbose_log" && verbose=t
-fi
-
-if test -n "$trace" && test -n "$test_untraceable"
-then
- # '-x' tracing requested, but this test script can't be reliably
- # traced, unless it is run with a Bash version supporting
- # BASH_XTRACEFD (introduced in Bash v4.1).
- if test -n "$BASH_VERSION" && eval '
- test ${BASH_VERSINFO[0]} -gt 4 || {
- test ${BASH_VERSINFO[0]} -eq 4 &&
- test ${BASH_VERSINFO[1]} -ge 1
- }
- '
- then
- : Executed by a Bash version supporting BASH_XTRACEFD. Good.
- else
- echo >&2 "warning: ignoring -x; '$0' is untraceable without BASH_XTRACEFD"
- trace=
- fi
-fi
-if test -n "$trace" && test -z "$verbose_log"
-then
- verbose=t
-fi
-
if test -n "$color"
then
# Save the color control sequences now rather than run tput
--
2.20.1.151.gec613c4b75
^ permalink raw reply related
* [PATCH v4 5/8] test-lib: consolidate naming of test-results paths
From: SZEDER Gábor @ 2019-01-05 1:08 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Jeff King, git, SZEDER Gábor
In-Reply-To: <20190105010859.11031-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
four places where we construct the name of the 't/test-results'
directory or the name of various test-specific files in there. 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 | 22 +++++++++++-----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/t/test-lib.sh b/t/test-lib.sh
index 14ccb60838..5720292641 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -160,6 +160,10 @@ then
test -z "$verbose_log" && verbose=t
fi
+TEST_NAME="$(basename "$0" .sh)"
+TEST_RESULTS_DIR="$TEST_OUTPUT_DIRECTORY/test-results"
+TEST_RESULTS_BASE="$TEST_RESULTS_DIR/$TEST_NAME"
+
# if --tee was passed, write the output not only to the terminal, but
# additionally to the file test-results/$BASENAME.out, too.
if test "$GIT_TEST_TEE_STARTED" = "done"
@@ -167,12 +171,11 @@ then
: # do not redirect again
elif test -n "$tee"
then
- mkdir -p "$TEST_OUTPUT_DIRECTORY/test-results"
- BASE="$TEST_OUTPUT_DIRECTORY/test-results/$(basename "$0" .sh)"
+ mkdir -p "$TEST_RESULTS_DIR"
# 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
@@ -180,8 +183,8 @@ then
>"$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
fi
@@ -840,12 +843,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 "$TEST_RESULTS_DIR"
- cat >"$test_results_path" <<-EOF
+ cat >"$TEST_RESULTS_BASE.counts" <<-EOF
total $test_count
success $test_success
fixed $test_fixed
@@ -1051,7 +1051,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.1.151.gec613c4b75
^ permalink raw reply related
* [PATCH v4 6/8] test-lib: set $TRASH_DIRECTORY earlier
From: SZEDER Gábor @ 2019-01-05 1:08 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Jeff King, git, SZEDER Gábor
In-Reply-To: <20190105010859.11031-1-szeder.dev@gmail.com>
A later patch in this series will need to know the path to the trash
directory early in 'test-lib.sh', but $TRASH_DIRECTORY is set much
later.
Set $TRASH_DIRECTORY earlier, where the other test-specific path
variables are set.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
---
t/test-lib.sh | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/t/test-lib.sh b/t/test-lib.sh
index 5720292641..0e9ac9118d 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -163,6 +163,12 @@ fi
TEST_NAME="$(basename "$0" .sh)"
TEST_RESULTS_DIR="$TEST_OUTPUT_DIRECTORY/test-results"
TEST_RESULTS_BASE="$TEST_RESULTS_DIR/$TEST_NAME"
+TRASH_DIRECTORY="trash directory.$TEST_NAME"
+test -n "$root" && TRASH_DIRECTORY="$root/$TRASH_DIRECTORY"
+case "$TRASH_DIRECTORY" in
+/*) ;; # absolute path is good
+ *) TRASH_DIRECTORY="$TEST_OUTPUT_DIRECTORY/$TRASH_DIRECTORY" ;;
+esac
# if --tee was passed, write the output not only to the terminal, but
# additionally to the file test-results/$BASENAME.out, too.
@@ -1051,12 +1057,6 @@ then
fi
# Test repository
-TRASH_DIRECTORY="trash directory.$TEST_NAME"
-test -n "$root" && TRASH_DIRECTORY="$root/$TRASH_DIRECTORY"
-case "$TRASH_DIRECTORY" in
-/*) ;; # absolute path is good
- *) TRASH_DIRECTORY="$TEST_OUTPUT_DIRECTORY/$TRASH_DIRECTORY" ;;
-esac
rm -fr "$TRASH_DIRECTORY" || {
GIT_EXIT_OK=t
echo >&5 "FATAL: Cannot prepare test area"
--
2.20.1.151.gec613c4b75
^ permalink raw reply related
* [PATCH v4 8/8] test-lib: add the '--stress' option to run a test repeatedly under load
From: SZEDER Gábor @ 2019-01-05 1:08 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Jeff King, git, SZEDER Gábor
In-Reply-To: <20190105010859.11031-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 script 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 jobs until
one of them fails, thereby using the test script itself to increase
the load on the machine.
The number of parallel jobs 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 (as reported by the 'getconf' utility), or 8.
Make '--stress' imply '--verbose -x --immediate' to get the most
information about rare failures; there is really no point in spending
all the extra effort to reproduce such a failure, and then not know
which command failed and why.
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.
- Redirect each parallel test run's verbose output to
't/test-results/$TEST_NAME.stress-<nr>.out', because dumping the
output of several parallel running tests to the terminal would
create a big ugly mess.
For convenience, print the output of the failed test job at the end,
and rename its trash directory to end with the '.stress-failed'
suffix, so it's easy to find in a predictable path (OTOH, all absolute
paths recorded in the trash directory become invalid; we'll see
whether this causes any issues in practice). If, in an unlikely case,
more than one jobs were to fail nearly at the same time, then print
the output of all failed jobs, and rename the trash directory of only
the last one (i.e. with the highest job number), as it is the trash
directory of the test whose output will be at the bottom of the user's
terminal.
Based on Jeff King's 'stress' script.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
---
t/README | 19 ++++++-
t/test-lib-functions.sh | 7 ++-
t/test-lib.sh | 109 +++++++++++++++++++++++++++++++++++++++-
3 files changed, 130 insertions(+), 5 deletions(-)
diff --git a/t/README b/t/README
index 28711cc508..11ce7675e3 100644
--- a/t/README
+++ b/t/README
@@ -186,6 +186,22 @@ 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 jobs until
+ one of them fails. Useful for reproducing rare failures in
+ flaky tests. The number of parallel jobs is, in order of
+ precedence: <N>, or the value of the GIT_TEST_STRESS_LOAD
+ environment variable, or twice the number of available
+ processors (as shown by the 'getconf' utility), or 8.
+ Implies `--verbose -x --immediate` to get the most information
+ about the failure. Note that the verbose output of each test
+ job is saved to 't/test-results/$TEST_NAME.stress-<nr>.out',
+ and only the output of the failed test job is shown on the
+ terminal. The names of the trash directories get a
+ '.stress-<nr>' suffix, and the trash directory of the failed
+ test job is renamed to end with a '.stress-failed' suffix.
+
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 +441,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 4459bdda13..92cf8f812c 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]*|0*)
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 0e9ac9118d..a1abb1177a 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -139,6 +139,19 @@ do
verbose_log=t
tee=t
;;
+ --stress)
+ stress=t ;;
+ --stress=*)
+ stress=${opt#--*=}
+ case "$stress" in
+ *[^0-9]*|0*|"")
+ echo "error: --stress=<N> requires the number of jobs to run" >&2
+ exit 1
+ ;;
+ *) # Good.
+ ;;
+ esac
+ ;;
*)
echo "error: unknown test option '$opt'" >&2; exit 1 ;;
esac
@@ -160,16 +173,108 @@ then
test -z "$verbose_log" && verbose=t
fi
+if test -n "$stress"
+then
+ verbose=t
+ trace=t
+ immediate=t
+fi
+
+TEST_STRESS_JOB_SFX="${GIT_TEST_STRESS_JOB_NR:+.stress-$GIT_TEST_STRESS_JOB_NR}"
TEST_NAME="$(basename "$0" .sh)"
TEST_RESULTS_DIR="$TEST_OUTPUT_DIRECTORY/test-results"
-TEST_RESULTS_BASE="$TEST_RESULTS_DIR/$TEST_NAME"
-TRASH_DIRECTORY="trash directory.$TEST_NAME"
+TEST_RESULTS_BASE="$TEST_RESULTS_DIR/$TEST_NAME$TEST_STRESS_JOB_SFX"
+TRASH_DIRECTORY="trash directory.$TEST_NAME$TEST_STRESS_JOB_SFX"
test -n "$root" && TRASH_DIRECTORY="$root/$TRASH_DIRECTORY"
case "$TRASH_DIRECTORY" in
/*) ;; # absolute path is good
*) TRASH_DIRECTORY="$TEST_OUTPUT_DIRECTORY/$TRASH_DIRECTORY" ;;
esac
+# If --stress was passed, run this test repeatedly in several parallel loops.
+if test "$GIT_TEST_STRESS_STARTED" = "done"
+then
+ : # Don't stress test again.
+elif test -n "$stress"
+then
+ if test "$stress" != t
+ then
+ job_count=$stress
+ elif test -n "$GIT_TEST_STRESS_LOAD"
+ then
+ job_count="$GIT_TEST_STRESS_LOAD"
+ elif job_count=$(getconf _NPROCESSORS_ONLN 2>/dev/null) &&
+ test -n "$job_count"
+ then
+ job_count=$((2 * $job_count))
+ else
+ job_count=8
+ fi
+
+ mkdir -p "$TEST_RESULTS_DIR"
+ stressfail="$TEST_RESULTS_BASE.stress-failed"
+ rm -f "$stressfail"
+
+ stress_exit=0
+ trap '
+ kill $job_pids 2>/dev/null
+ wait
+ stress_exit=1
+ ' TERM INT HUP
+
+ job_pids=
+ 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
+
+ trap '
+ kill $test_pid 2>/dev/null
+ wait
+ exit 1
+ ' TERM INT
+
+ cnt=0
+ while ! test -e "$stressfail"
+ do
+ $TEST_SHELL_PATH "$0" "$@" >"$TEST_RESULTS_BASE.stress-$job_nr.out" 2>&1 &
+ test_pid=$!
+
+ if wait $test_pid
+ then
+ printf "OK %2d.%d\n" $GIT_TEST_STRESS_JOB_NR $cnt
+ else
+ echo $GIT_TEST_STRESS_JOB_NR >>"$stressfail"
+ printf "FAIL %2d.%d\n" $GIT_TEST_STRESS_JOB_NR $cnt
+ fi
+ cnt=$(($cnt + 1))
+ done
+ ) &
+ job_pids="$job_pids $!"
+ job_nr=$(($job_nr + 1))
+ done
+
+ wait
+
+ if test -f "$stressfail"
+ then
+ echo "Log(s) of failed test run(s):"
+ for failed_job_nr in $(sort -n "$stressfail")
+ do
+ echo "Contents of '$TEST_RESULTS_BASE.stress-$failed_job_nr.out':"
+ cat "$TEST_RESULTS_BASE.stress-$failed_job_nr.out"
+ done
+ rm -rf "$TRASH_DIRECTORY.stress-failed"
+ # Move the last one.
+ mv "$TRASH_DIRECTORY.stress-$failed_job_nr" "$TRASH_DIRECTORY.stress-failed"
+ fi
+
+ exit $stress_exit
+fi
+
# if --tee was passed, write the output not only to the terminal, but
# additionally to the file test-results/$BASENAME.out, too.
if test "$GIT_TEST_TEE_STARTED" = "done"
--
2.20.1.151.gec613c4b75
^ permalink raw reply related
* [PATCH v4 7/8] test-lib-functions: introduce the 'test_set_port' helper function
From: SZEDER Gábor @ 2019-01-05 1:08 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Jeff King, git, SZEDER Gábor
In-Reply-To: <20190105010859.11031-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 'git p4' 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 'git p4' 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..4459bdda13 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]*|0*)
+ error >&7 "invalid port number: $port"
+ ;;
+ *)
+ # The user has specified the port.
+ ;;
+ esac
+}
--
2.20.1.151.gec613c4b75
^ permalink raw reply related
* How DELTA objects values work and are calculated
From: Farhan Khan @ 2019-01-05 2:48 UTC (permalink / raw)
To: git
Hi all,
I'm having trouble understanding how OBJ_REF_DELTA and OBJ_REF_DELTA
(deltas) work in git. Where does git calculate the sha1 hash values
when doing "git index-pack" in builtin/index-pack.c. I think my lack
of understanding of the code is compounded the fact that I do not
understand what the two object types are.
From tracing the code starting from index-pack, all non-delta object
type hashes are calculated in index-pack.c:1131 (parse_pack_objects).
However, when the function ends, the delta objects hash values are set
to all 0's.
My questions are:
A) How do Delta objects work?
B) Where and how are the sha1 values calculated?
I have read Documentation/technical/pack-format.txt, but am still not clear.
Thank you!
--
Farhan Khan
PGP Fingerprint: B28D 2726 E2BC A97E 3854 5ABE 9A9F 00BC D525 16EE
^ permalink raw reply
* Re: How DELTA objects values work and are calculated
From: Duy Nguyen @ 2019-01-05 4:46 UTC (permalink / raw)
To: Farhan Khan; +Cc: Git Mailing List
In-Reply-To: <CAFd4kYBX+HrLxbga=VJgC5WjyeDZEznm2UCL+HF8A1YKVo3Trw@mail.gmail.com>
On Sat, Jan 5, 2019 at 9:49 AM Farhan Khan <khanzf@gmail.com> wrote:
>
> Hi all,
>
> I'm having trouble understanding how OBJ_REF_DELTA and OBJ_REF_DELTA
> (deltas) work in git. Where does git calculate the sha1 hash values
> when doing "git index-pack" in builtin/index-pack.c. I think my lack
> of understanding of the code is compounded the fact that I do not
> understand what the two object types are.
>
> From tracing the code starting from index-pack, all non-delta object
> type hashes are calculated in index-pack.c:1131 (parse_pack_objects).
> However, when the function ends, the delta objects hash values are set
> to all 0's.
Delta objects depend on other objects (and even delta ones). To
calculate its sha1 values we may need to recursively calculate sha1
values of its base objects. This is why we do it in a separate phase
because the calculation is more complicated than non-delta objects.
> My questions are:
> A) How do Delta objects work?
A delta object consists of a reference to the base object (either an
sha1 value, or the offset to where the object is) and a "delta" to be
applied on (it's basically a binary diff).
> B) Where and how are the sha1 values calculated?
Start at threaded_second_pass() in index-pack.c, we go through all
delta objects here and try to calculate their sha1 values. Eventually
you'll hit resolve_delta(), where the delta is actually applied to the
base object in the patch_delta() call, and the sha1 value calculated
in the following hash_object_file() call.
>
> I have read Documentation/technical/pack-format.txt, but am still not clear.
>
> Thank you!
> --
> Farhan Khan
> PGP Fingerprint: B28D 2726 E2BC A97E 3854 5ABE 9A9F 00BC D525 16EE
--
Duy
^ permalink raw reply
* [PATCH v3] worktree: allow to (re)move worktrees with uninitialized submodules
From: Nguyễn Thái Ngọc Duy @ 2019-01-05 5:08 UTC (permalink / raw)
To: pclouds; +Cc: git, sunshine, Junio C Hamano
In-Reply-To: <20181216144657.31181-1-pclouds@gmail.com>
Uninitialized submodules have nothing valueable for us to be worried
about. They are just SHA-1. Let "worktree remove" and "worktree move"
continue in this case so that people can still use multiple worktrees
on repos with optional submodules that are never populated, like
sha1collisiondetection in git.git when checked out by doc-diff script.
Note that for "worktree remove", it is possible that a user
initializes a submodule (*), makes some commits (but not push), then
deinitializes it. At that point, the submodule is unpopulated, but the
precious new commits are still in
$GIT_COMMON_DIR/worktrees/<worktree>/modules/<submodule>
directory and we should not allow removing the worktree or we lose
those commits forever. The new directory check is added to prevent
this.
(*) yes they are screwed anyway by doing this since "git submodule"
would add submodule.* in $GIT_COMMON_DIR/config, which is shared
across multiple worktrees. But it does not mean we let them be
screwed even more.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
v3 adds tests. This test file is being renamed by
tg/checkout-no-overlay but it seems rename is handled correctly, no
merge conflicts on 'pu'.
builtin/worktree.c | 29 +++++++++++++++++++++++------
t/t2028-worktree-move.sh | 37 +++++++++++++++++++++++++++++++++++++
2 files changed, 60 insertions(+), 6 deletions(-)
diff --git a/builtin/worktree.c b/builtin/worktree.c
index 5e84026177..3f9907fcc9 100644
--- a/builtin/worktree.c
+++ b/builtin/worktree.c
@@ -9,6 +9,7 @@
#include "refs.h"
#include "run-command.h"
#include "sigchain.h"
+#include "submodule.h"
#include "refs.h"
#include "utf8.h"
#include "worktree.h"
@@ -724,20 +725,36 @@ static int unlock_worktree(int ac, const char **av, const char *prefix)
static void validate_no_submodules(const struct worktree *wt)
{
struct index_state istate = { NULL };
+ struct strbuf path = STRBUF_INIT;
int i, found_submodules = 0;
- if (read_index_from(&istate, worktree_git_path(wt, "index"),
- get_worktree_git_dir(wt)) > 0) {
+ if (is_directory(worktree_git_path(wt, "modules"))) {
+ /*
+ * There could be false positives, e.g. the "modules"
+ * directory exists but is empty. But it's a rare case and
+ * this simpler check is probably good enough for now.
+ */
+ found_submodules = 1;
+ } else if (read_index_from(&istate, worktree_git_path(wt, "index"),
+ get_worktree_git_dir(wt)) > 0) {
for (i = 0; i < istate.cache_nr; i++) {
struct cache_entry *ce = istate.cache[i];
+ int err;
- if (S_ISGITLINK(ce->ce_mode)) {
- found_submodules = 1;
- break;
- }
+ if (!S_ISGITLINK(ce->ce_mode))
+ continue;
+
+ strbuf_reset(&path);
+ strbuf_addf(&path, "%s/%s", wt->path, ce->name);
+ if (!is_submodule_populated_gently(path.buf, &err))
+ continue;
+
+ found_submodules = 1;
+ break;
}
}
discard_index(&istate);
+ strbuf_release(&path);
if (found_submodules)
die(_("working trees containing submodules cannot be moved or removed"));
diff --git a/t/t2028-worktree-move.sh b/t/t2028-worktree-move.sh
index 33c0337733..939d18d728 100755
--- a/t/t2028-worktree-move.sh
+++ b/t/t2028-worktree-move.sh
@@ -112,6 +112,26 @@ test_expect_success 'move locked worktree (force)' '
git worktree move --force --force flump ploof
'
+test_expect_success 'move a repo with uninitialized submodule' '
+ git init withsub &&
+ (
+ cd withsub &&
+ test_commit initial &&
+ git submodule add "$PWD"/.git sub &&
+ git commit -m withsub &&
+ git worktree add second HEAD &&
+ git worktree move second third
+ )
+'
+
+test_expect_success 'not move a repo with initialized submodule' '
+ (
+ cd withsub &&
+ git -C third submodule update &&
+ test_must_fail git worktree move third forth
+ )
+'
+
test_expect_success 'remove main worktree' '
test_must_fail git worktree remove .
'
@@ -185,4 +205,21 @@ test_expect_success 'remove cleans up .git/worktrees when empty' '
)
'
+test_expect_success 'remove a repo with uninitialized submodule' '
+ (
+ cd withsub &&
+ git worktree add to-remove HEAD &&
+ git worktree remove to-remove
+ )
+'
+
+test_expect_success 'not remove a repo with initialized submodule' '
+ (
+ cd withsub &&
+ git worktree add to-remove HEAD &&
+ git -C to-remove submodule update &&
+ test_must_fail git worktree remove to-remove
+ )
+'
+
test_done
--
2.20.0.482.g66447595a7
^ permalink raw reply related
* [PATCH 00/10] Remove the_index, the final part
From: Nguyễn Thái Ngọc Duy @ 2019-01-05 5:51 UTC (permalink / raw)
To: git; +Cc: Nguyễn Thái Ngọc Duy
This completely removes the_index outside builtin/. The macro
NO_THE_INDEX_COMPATIBILITY_MACROS is replaced with
USE_THE_INDEX_COMPATIBILITY_MACROS, which means by default you don't
have access to the_index any more. And USE_THE_... should only be
defined in builtin/
There's one easy conflict in builtin/rebase.c when merging this to 'pu'.
builtin/stash.c also needs to define USE_THE_... to build, but I think
that could be part of the builtin stash topic when it's rerolled.
Nguyễn Thái Ngọc Duy (10):
notes-utils.c: remove the_repository references
repository.c: replace hold_locked_index() with repo_hold_locked_index()
checkout: avoid the_index when possible
read-cache.c: kill read_index()
read-cache.c: replace update_index_if_able with repo_&
sha1-name.c: remove implicit dependency on the_index
merge-recursive.c: remove implicit dependency on the_index
merge-recursive.c: remove implicit dependency on the_repository
read-cache.c: remove the_* from index_has_changes()
cache.h: flip NO_THE_INDEX_COMPATIBILITY_MACROS switch
apply.c | 5 +-
attr.c | 1 -
blame.c | 4 +-
builtin/add.c | 1 +
builtin/am.c | 13 +-
builtin/blame.c | 3 +-
builtin/cat-file.c | 7 +-
builtin/check-attr.c | 1 +
builtin/check-ignore.c | 1 +
builtin/checkout-index.c | 1 +
builtin/checkout.c | 5 +-
builtin/clean.c | 1 +
builtin/clone.c | 1 +
builtin/commit.c | 7 +-
builtin/describe.c | 3 +-
builtin/diff-files.c | 1 +
builtin/diff-index.c | 1 +
builtin/diff-tree.c | 3 +-
builtin/diff.c | 3 +-
builtin/difftool.c | 1 +
builtin/fsck.c | 1 +
builtin/grep.c | 4 +-
builtin/hash-object.c | 3 +-
builtin/log.c | 4 +-
builtin/ls-files.c | 1 -
builtin/merge-index.c | 1 +
builtin/merge-ours.c | 1 +
builtin/merge-recursive.c | 2 +-
builtin/merge-tree.c | 4 +-
builtin/merge.c | 3 +-
builtin/mv.c | 1 +
builtin/notes.c | 21 +--
builtin/pack-objects.c | 2 +-
builtin/pull.c | 1 +
builtin/read-tree.c | 1 +
builtin/rebase--interactive.c | 1 +
builtin/rebase.c | 14 +-
builtin/replace.c | 2 +-
builtin/reset.c | 1 +
builtin/rev-parse.c | 4 +-
builtin/rm.c | 1 +
builtin/submodule--helper.c | 1 +
builtin/update-index.c | 1 +
builtin/write-tree.c | 1 +
cache-tree.h | 2 +-
cache.h | 35 ++---
convert.c | 1 -
dir.c | 1 -
git.c | 4 +-
list-objects-filter-options.c | 2 +-
merge-recursive.c | 191 +++++++++++++++------------
merge-recursive.h | 6 +-
merge.c | 4 +-
name-hash.c | 1 -
notes-merge.c | 4 +-
notes-utils.c | 17 ++-
notes-utils.h | 11 +-
pathspec.c | 1 -
preload-index.c | 11 +-
read-cache.c | 44 +++---
repository.c | 9 ++
repository.h | 16 +++
rerere.c | 8 +-
revision.c | 12 +-
sequencer.c | 41 +++---
sequencer.h | 3 +-
sha1-name.c | 56 ++++----
submodule.c | 1 -
t/helper/test-dump-fsmonitor.c | 4 +-
t/helper/test-dump-untracked-cache.c | 1 +
t/helper/test-tool.h | 1 +
tree.c | 1 -
unpack-trees.c | 1 -
wt-status.c | 4 +-
74 files changed, 359 insertions(+), 273 deletions(-)
--
2.20.0.482.g66447595a7
^ permalink raw reply
* [PATCH 01/10] notes-utils.c: remove the_repository references
From: Nguyễn Thái Ngọc Duy @ 2019-01-05 5:51 UTC (permalink / raw)
To: git; +Cc: Nguyễn Thái Ngọc Duy
In-Reply-To: <20190105055153.3256-1-pclouds@gmail.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
builtin/am.c | 2 +-
builtin/commit.c | 2 +-
builtin/notes.c | 21 +++++++++++++--------
notes-merge.c | 4 ++--
notes-utils.c | 17 ++++++++++-------
notes-utils.h | 11 ++++++++---
sequencer.c | 7 ++++---
sequencer.h | 3 ++-
8 files changed, 41 insertions(+), 26 deletions(-)
diff --git a/builtin/am.c b/builtin/am.c
index 95370313b6..d32044545d 100644
--- a/builtin/am.c
+++ b/builtin/am.c
@@ -527,7 +527,7 @@ static int copy_notes_for_rebase(const struct am_state *state)
}
finish:
- finish_copy_notes_for_rewrite(c, msg);
+ finish_copy_notes_for_rewrite(the_repository, c, msg);
fclose(fp);
strbuf_release(&sb);
return ret;
diff --git a/builtin/commit.c b/builtin/commit.c
index 004b816635..e29fb5e3eb 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -1674,7 +1674,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
run_command_v_opt(argv_gc_auto, RUN_GIT_CMD);
run_commit_hook(use_editor, get_index_file(), "post-commit", NULL);
if (amend && !no_post_rewrite) {
- commit_post_rewrite(current_head, &oid);
+ commit_post_rewrite(the_repository, current_head, &oid);
}
if (!quiet) {
unsigned int flags = 0;
diff --git a/builtin/notes.c b/builtin/notes.c
index 4996a670f7..02e97f55c5 100644
--- a/builtin/notes.c
+++ b/builtin/notes.c
@@ -330,10 +330,10 @@ static int notes_copy_from_stdin(int force, const char *rewrite_cmd)
}
if (!rewrite_cmd) {
- commit_notes(t, msg);
+ commit_notes(the_repository, t, msg);
free_notes(t);
} else {
- finish_copy_notes_for_rewrite(c, msg);
+ finish_copy_notes_for_rewrite(the_repository, c, msg);
}
strbuf_release(&buf);
return ret;
@@ -469,12 +469,14 @@ static int add(int argc, const char **argv, const char *prefix)
write_note_data(&d, &new_note);
if (add_note(t, &object, &new_note, combine_notes_overwrite))
BUG("combine_notes_overwrite failed");
- commit_notes(t, "Notes added by 'git notes add'");
+ commit_notes(the_repository, t,
+ "Notes added by 'git notes add'");
} else {
fprintf(stderr, _("Removing note for object %s\n"),
oid_to_hex(&object));
remove_note(t, object.hash);
- commit_notes(t, "Notes removed by 'git notes add'");
+ commit_notes(the_repository, t,
+ "Notes removed by 'git notes add'");
}
free_note_data(&d);
@@ -552,7 +554,8 @@ static int copy(int argc, const char **argv, const char *prefix)
if (add_note(t, &object, from_note, combine_notes_overwrite))
BUG("combine_notes_overwrite failed");
- commit_notes(t, "Notes added by 'git notes copy'");
+ commit_notes(the_repository, t,
+ "Notes added by 'git notes copy'");
out:
free_notes(t);
return retval;
@@ -636,7 +639,7 @@ static int append_edit(int argc, const char **argv, const char *prefix)
remove_note(t, object.hash);
logmsg = xstrfmt("Notes removed by 'git notes %s'", argv[0]);
}
- commit_notes(t, logmsg);
+ commit_notes(the_repository, t, logmsg);
free(logmsg);
free_note_data(&d);
@@ -937,7 +940,8 @@ static int remove_cmd(int argc, const char **argv, const char *prefix)
strbuf_release(&sb);
}
if (!retval)
- commit_notes(t, "Notes removed by 'git notes remove'");
+ commit_notes(the_repository, t,
+ "Notes removed by 'git notes remove'");
free_notes(t);
return retval;
}
@@ -965,7 +969,8 @@ static int prune(int argc, const char **argv, const char *prefix)
prune_notes(t, (verbose ? NOTES_PRUNE_VERBOSE : 0) |
(show_only ? NOTES_PRUNE_VERBOSE|NOTES_PRUNE_DRYRUN : 0) );
if (!show_only)
- commit_notes(t, "Notes removed by 'git notes prune'");
+ commit_notes(the_repository, t,
+ "Notes removed by 'git notes prune'");
free_notes(t);
return 0;
}
diff --git a/notes-merge.c b/notes-merge.c
index 72688d301b..280aa8e6c1 100644
--- a/notes-merge.c
+++ b/notes-merge.c
@@ -649,7 +649,7 @@ int notes_merge(struct notes_merge_options *o,
struct commit_list *parents = NULL;
commit_list_insert(remote, &parents); /* LIFO order */
commit_list_insert(local, &parents);
- create_notes_commit(local_tree, parents, o->commit_msg.buf,
+ create_notes_commit(o->repo, local_tree, parents, o->commit_msg.buf,
o->commit_msg.len, result_oid);
}
@@ -724,7 +724,7 @@ int notes_merge_commit(struct notes_merge_options *o,
strbuf_setlen(&path, baselen);
}
- create_notes_commit(partial_tree, partial_commit->parents, msg,
+ create_notes_commit(o->repo, partial_tree, partial_commit->parents, msg,
strlen(msg), result_oid);
unuse_commit_buffer(partial_commit, buffer);
if (o->verbosity >= 4)
diff --git a/notes-utils.c b/notes-utils.c
index 14ea03178e..a819410698 100644
--- a/notes-utils.c
+++ b/notes-utils.c
@@ -5,7 +5,9 @@
#include "notes-utils.h"
#include "repository.h"
-void create_notes_commit(struct notes_tree *t, struct commit_list *parents,
+void create_notes_commit(struct repository *r,
+ struct notes_tree *t,
+ struct commit_list *parents,
const char *msg, size_t msg_len,
struct object_id *result_oid)
{
@@ -20,8 +22,7 @@ void create_notes_commit(struct notes_tree *t, struct commit_list *parents,
/* Deduce parent commit from t->ref */
struct object_id parent_oid;
if (!read_ref(t->ref, &parent_oid)) {
- struct commit *parent = lookup_commit(the_repository,
- &parent_oid);
+ struct commit *parent = lookup_commit(r, &parent_oid);
if (parse_commit(parent))
die("Failed to find/parse commit %s", t->ref);
commit_list_insert(parent, &parents);
@@ -34,7 +35,7 @@ void create_notes_commit(struct notes_tree *t, struct commit_list *parents,
die("Failed to commit notes tree to database");
}
-void commit_notes(struct notes_tree *t, const char *msg)
+void commit_notes(struct repository *r, struct notes_tree *t, const char *msg)
{
struct strbuf buf = STRBUF_INIT;
struct object_id commit_oid;
@@ -50,7 +51,7 @@ void commit_notes(struct notes_tree *t, const char *msg)
strbuf_addstr(&buf, msg);
strbuf_complete_line(&buf);
- create_notes_commit(t, NULL, buf.buf, buf.len, &commit_oid);
+ create_notes_commit(r, t, NULL, buf.buf, buf.len, &commit_oid);
strbuf_insert(&buf, 0, "notes: ", 7); /* commit message starts at index 7 */
update_ref(buf.buf, t->update_ref, &commit_oid, NULL, 0,
UPDATE_REFS_DIE_ON_ERR);
@@ -171,11 +172,13 @@ int copy_note_for_rewrite(struct notes_rewrite_cfg *c,
return ret;
}
-void finish_copy_notes_for_rewrite(struct notes_rewrite_cfg *c, const char *msg)
+void finish_copy_notes_for_rewrite(struct repository *r,
+ struct notes_rewrite_cfg *c,
+ const char *msg)
{
int i;
for (i = 0; c->trees[i]; i++) {
- commit_notes(c->trees[i], msg);
+ commit_notes(r, c->trees[i], msg);
free_notes(c->trees[i]);
}
free(c->trees);
diff --git a/notes-utils.h b/notes-utils.h
index 5408306528..d9b3c09eaf 100644
--- a/notes-utils.h
+++ b/notes-utils.h
@@ -5,6 +5,7 @@
struct commit_list;
struct object_id;
+struct repository;
/*
* Create new notes commit from the given notes tree
@@ -17,11 +18,13 @@ struct object_id;
*
* The resulting commit SHA1 is stored in result_sha1.
*/
-void create_notes_commit(struct notes_tree *t, struct commit_list *parents,
+void create_notes_commit(struct repository *r,
+ struct notes_tree *t,
+ struct commit_list *parents,
const char *msg, size_t msg_len,
struct object_id *result_oid);
-void commit_notes(struct notes_tree *t, const char *msg);
+void commit_notes(struct repository *r, struct notes_tree *t, const char *msg);
enum notes_merge_strategy {
NOTES_MERGE_RESOLVE_MANUAL = 0,
@@ -45,6 +48,8 @@ int parse_notes_merge_strategy(const char *v, enum notes_merge_strategy *s);
struct notes_rewrite_cfg *init_copy_notes_for_rewrite(const char *cmd);
int copy_note_for_rewrite(struct notes_rewrite_cfg *c,
const struct object_id *from_obj, const struct object_id *to_obj);
-void finish_copy_notes_for_rewrite(struct notes_rewrite_cfg *c, const char *msg);
+void finish_copy_notes_for_rewrite(struct repository *r,
+ struct notes_rewrite_cfg *c,
+ const char *msg);
#endif
diff --git a/sequencer.c b/sequencer.c
index b68bca0bef..1a92a5d678 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -1115,7 +1115,8 @@ static int run_rewrite_hook(const struct object_id *oldoid,
return finish_command(&proc);
}
-void commit_post_rewrite(const struct commit *old_head,
+void commit_post_rewrite(struct repository *r,
+ const struct commit *old_head,
const struct object_id *new_head)
{
struct notes_rewrite_cfg *cfg;
@@ -1124,7 +1125,7 @@ void commit_post_rewrite(const struct commit *old_head,
if (cfg) {
/* we are amending, so old_head is not NULL */
copy_note_for_rewrite(cfg, &old_head->object.oid, new_head);
- finish_copy_notes_for_rewrite(cfg, "Notes added by 'git commit --amend'");
+ finish_copy_notes_for_rewrite(r, cfg, "Notes added by 'git commit --amend'");
}
run_rewrite_hook(&old_head->object.oid, new_head);
}
@@ -1405,7 +1406,7 @@ static int try_to_commit(struct repository *r,
}
if (flags & AMEND_MSG)
- commit_post_rewrite(current_head, oid);
+ commit_post_rewrite(r, current_head, oid);
out:
free_commit_extra_headers(extra);
diff --git a/sequencer.h b/sequencer.h
index 9d83f0f3e9..2caecd550b 100644
--- a/sequencer.h
+++ b/sequencer.h
@@ -124,7 +124,8 @@ int update_head_with_reflog(const struct commit *old_head,
const struct object_id *new_head,
const char *action, const struct strbuf *msg,
struct strbuf *err);
-void commit_post_rewrite(const struct commit *current_head,
+void commit_post_rewrite(struct repository *r,
+ const struct commit *current_head,
const struct object_id *new_head);
int prepare_branch_to_be_rebased(struct replay_opts *opts, const char *commit);
--
2.20.0.482.g66447595a7
^ permalink raw reply related
* [PATCH 02/10] repository.c: replace hold_locked_index() with repo_hold_locked_index()
From: Nguyễn Thái Ngọc Duy @ 2019-01-05 5:51 UTC (permalink / raw)
To: git; +Cc: Nguyễn Thái Ngọc Duy
In-Reply-To: <20190105055153.3256-1-pclouds@gmail.com>
hold_locked_index() assumes the index path at $GIT_DIR/index. This is
not good for places that take an arbitrary index_state instead of
the_index, which is basically everywhere except builtin/.
Replace it with repo_hold_locked_index(). hold_locked_index() remains
as a wrapper around repo_hold_locked_index() to reduce changes in builtin/
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
apply.c | 3 ++-
builtin/clone.c | 1 +
cache.h | 2 +-
merge-recursive.c | 2 +-
merge.c | 2 +-
read-cache.c | 5 -----
repository.c | 8 ++++++++
repository.h | 4 ++++
rerere.c | 2 +-
sequencer.c | 10 +++++-----
wt-status.c | 2 +-
11 files changed, 25 insertions(+), 16 deletions(-)
diff --git a/apply.c b/apply.c
index 01793d6126..08cde3c4bf 100644
--- a/apply.c
+++ b/apply.c
@@ -4712,7 +4712,8 @@ static int apply_patch(struct apply_state *state,
state->index_file,
LOCK_DIE_ON_ERROR);
else
- hold_locked_index(&state->lock_file, LOCK_DIE_ON_ERROR);
+ repo_hold_locked_index(state->repo, &state->lock_file,
+ LOCK_DIE_ON_ERROR);
}
if (state->check_index && read_apply_cache(state) < 0) {
diff --git a/builtin/clone.c b/builtin/clone.c
index 7c7f98c72c..ddb3230d21 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -8,6 +8,7 @@
* Clone a repository into a different directory that does not yet exist.
*/
+#define USE_THE_INDEX_COMPATIBILITY_MACROS
#include "builtin.h"
#include "config.h"
#include "lockfile.h"
diff --git a/cache.h b/cache.h
index ca36b44ee0..634c9ce325 100644
--- a/cache.h
+++ b/cache.h
@@ -433,6 +433,7 @@ void validate_cache_entries(const struct index_state *istate);
#define unmerge_cache_entry_at(at) unmerge_index_entry_at(&the_index, at)
#define unmerge_cache(pathspec) unmerge_index(&the_index, pathspec)
#define read_blob_data_from_cache(path, sz) read_blob_data_from_index(&the_index, (path), (sz))
+#define hold_locked_index(lock_file, flags) repo_hold_locked_index(the_repository, (lock_file), (flags))
#endif
#define TYPE_BITS 3
@@ -833,7 +834,6 @@ extern struct cache_entry *refresh_cache_entry(struct index_state *, struct cach
*/
extern void update_index_if_able(struct index_state *, struct lock_file *);
-extern int hold_locked_index(struct lock_file *, int);
extern void set_alternate_index_output(const char *);
extern int verify_index_checksum;
diff --git a/merge-recursive.c b/merge-recursive.c
index ecf8db0b71..8dba939d8f 100644
--- a/merge-recursive.c
+++ b/merge-recursive.c
@@ -3643,7 +3643,7 @@ int merge_recursive_generic(struct merge_options *o,
}
}
- hold_locked_index(&lock, LOCK_DIE_ON_ERROR);
+ repo_hold_locked_index(the_repository, &lock, LOCK_DIE_ON_ERROR);
clean = merge_recursive(o, head_commit, next_commit, ca,
result);
if (clean < 0) {
diff --git a/merge.c b/merge.c
index 91008f7602..dbbc9d9f80 100644
--- a/merge.c
+++ b/merge.c
@@ -58,7 +58,7 @@ int checkout_fast_forward(struct repository *r,
refresh_index(r->index, REFRESH_QUIET, NULL, NULL, NULL);
- if (hold_locked_index(&lock_file, LOCK_REPORT_ON_ERROR) < 0)
+ if (repo_hold_locked_index(r, &lock_file, LOCK_REPORT_ON_ERROR) < 0)
return -1;
memset(&trees, 0, sizeof(trees));
diff --git a/read-cache.c b/read-cache.c
index 48c1797a4a..1030e11051 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -1733,11 +1733,6 @@ static int read_index_extension(struct index_state *istate,
return 0;
}
-int hold_locked_index(struct lock_file *lk, int lock_flags)
-{
- return hold_lock_file_for_update(lk, get_index_file(), lock_flags);
-}
-
int read_index(struct index_state *istate)
{
return read_index_from(istate, get_index_file(), get_git_dir());
diff --git a/repository.c b/repository.c
index 7b02e1dffa..fd965c127c 100644
--- a/repository.c
+++ b/repository.c
@@ -3,6 +3,7 @@
#include "object-store.h"
#include "config.h"
#include "object.h"
+#include "lockfile.h"
#include "submodule-config.h"
/* The main repository */
@@ -263,3 +264,10 @@ int repo_read_index(struct repository *repo)
return read_index_from(repo->index, repo->index_file, repo->gitdir);
}
+
+int repo_hold_locked_index(struct repository *repo,
+ struct lock_file *lf,
+ int flags)
+{
+ return hold_lock_file_for_update(lf, repo->index_file, flags);
+}
diff --git a/repository.h b/repository.h
index 9f16c42c1e..968330218f 100644
--- a/repository.h
+++ b/repository.h
@@ -6,6 +6,7 @@
struct config_set;
struct git_hash_algo;
struct index_state;
+struct lock_file;
struct raw_object_store;
struct submodule_cache;
@@ -130,5 +131,8 @@ void repo_clear(struct repository *repo);
* populated then the number of entries will simply be returned.
*/
int repo_read_index(struct repository *repo);
+int repo_hold_locked_index(struct repository *repo,
+ struct lock_file *lf,
+ int flags);
#endif /* REPOSITORY_H */
diff --git a/rerere.c b/rerere.c
index 13624038e6..fb0fdb2392 100644
--- a/rerere.c
+++ b/rerere.c
@@ -705,7 +705,7 @@ static void update_paths(struct repository *r, struct string_list *update)
struct lock_file index_lock = LOCK_INIT;
int i;
- hold_locked_index(&index_lock, LOCK_DIE_ON_ERROR);
+ repo_hold_locked_index(r, &index_lock, LOCK_DIE_ON_ERROR);
for (i = 0; i < update->nr; i++) {
struct string_list_item *item = &update->items[i];
diff --git a/sequencer.c b/sequencer.c
index 1a92a5d678..668c232b05 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -540,7 +540,7 @@ static int do_recursive_merge(struct repository *r,
char **xopt;
struct lock_file index_lock = LOCK_INIT;
- if (hold_locked_index(&index_lock, LOCK_REPORT_ON_ERROR) < 0)
+ if (repo_hold_locked_index(r, &index_lock, LOCK_REPORT_ON_ERROR) < 0)
return -1;
read_index(r->index);
@@ -1992,8 +1992,8 @@ static int read_and_refresh_cache(struct repository *r,
struct replay_opts *opts)
{
struct lock_file index_lock = LOCK_INIT;
- int index_fd = hold_locked_index(&index_lock, 0);
- if (read_index(r->index) < 0) {
+ int index_fd = repo_hold_locked_index(r, &index_lock, 0);
+ if (repo_read_index(r) < 0) {
rollback_lock_file(&index_lock);
return error(_("git %s: failed to read the index"),
_(action_name(opts)));
@@ -2978,7 +2978,7 @@ static int do_reset(struct repository *r,
struct unpack_trees_options unpack_tree_opts;
int ret = 0;
- if (hold_locked_index(&lock, LOCK_REPORT_ON_ERROR) < 0)
+ if (repo_hold_locked_index(r, &lock, LOCK_REPORT_ON_ERROR) < 0)
return -1;
if (len == 10 && !strncmp("[new root]", name, len)) {
@@ -3096,7 +3096,7 @@ static int do_merge(struct repository *r,
static struct lock_file lock;
const char *p;
- if (hold_locked_index(&lock, LOCK_REPORT_ON_ERROR) < 0) {
+ if (repo_hold_locked_index(r, &lock, LOCK_REPORT_ON_ERROR) < 0) {
ret = -1;
goto leave_merge;
}
diff --git a/wt-status.c b/wt-status.c
index 0fe3bcd4cd..becf78b04f 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -2375,7 +2375,7 @@ int require_clean_work_tree(struct repository *r,
struct lock_file lock_file = LOCK_INIT;
int err = 0, fd;
- fd = hold_locked_index(&lock_file, 0);
+ fd = repo_hold_locked_index(r, &lock_file, 0);
refresh_index(r->index, REFRESH_QUIET, NULL, NULL, NULL);
if (0 <= fd)
update_index_if_able(r->index, &lock_file);
--
2.20.0.482.g66447595a7
^ permalink raw reply related
* [PATCH 03/10] checkout: avoid the_index when possible
From: Nguyễn Thái Ngọc Duy @ 2019-01-05 5:51 UTC (permalink / raw)
To: git; +Cc: Nguyễn Thái Ngọc Duy
In-Reply-To: <20190105055153.3256-1-pclouds@gmail.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
builtin/checkout.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/builtin/checkout.c b/builtin/checkout.c
index 08b0ac48f3..1b672a9fd9 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -284,7 +284,7 @@ static int checkout_paths(const struct checkout_opts *opts,
return run_add_interactive(revision, "--patch=checkout",
&opts->pathspec);
- hold_locked_index(&lock_file, LOCK_DIE_ON_ERROR);
+ repo_hold_locked_index(the_repository, &lock_file, LOCK_DIE_ON_ERROR);
if (read_cache_preload(&opts->pathspec) < 0)
return error(_("index file corrupt"));
--
2.20.0.482.g66447595a7
^ permalink raw reply related
* [PATCH 04/10] read-cache.c: kill read_index()
From: Nguyễn Thái Ngọc Duy @ 2019-01-05 5:51 UTC (permalink / raw)
To: git; +Cc: Nguyễn Thái Ngọc Duy
In-Reply-To: <20190105055153.3256-1-pclouds@gmail.com>
read_index() shares the same problem as hold_locked_index(): it
assumes $GIT_DIR/index. Move all call sites to repo_read_index()
instead. read_index_preload() and read_index_unmerged() are also
killed as a consequence.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
apply.c | 2 +-
blame.c | 4 ++--
builtin/am.c | 2 +-
builtin/commit.c | 2 +-
builtin/diff-tree.c | 2 +-
builtin/rebase.c | 8 ++++----
cache.h | 11 +++--------
merge-recursive.c | 2 +-
merge.c | 2 +-
preload-index.c | 11 ++++++-----
read-cache.c | 11 ++++-------
repository.h | 6 ++++++
rerere.c | 6 +++---
revision.c | 4 ++--
sequencer.c | 20 ++++++++++----------
sha1-name.c | 6 +++---
16 files changed, 49 insertions(+), 50 deletions(-)
diff --git a/apply.c b/apply.c
index 08cde3c4bf..e040c0b957 100644
--- a/apply.c
+++ b/apply.c
@@ -4019,7 +4019,7 @@ static int read_apply_cache(struct apply_state *state)
return read_index_from(state->repo->index, state->index_file,
get_git_dir());
else
- return read_index(state->repo->index);
+ return repo_read_index(state->repo);
}
/* This function tries to read the object name from the current index */
diff --git a/blame.c b/blame.c
index 43861437f7..da57233cbb 100644
--- a/blame.c
+++ b/blame.c
@@ -188,7 +188,7 @@ static struct commit *fake_working_tree_commit(struct repository *r,
unsigned mode;
struct strbuf msg = STRBUF_INIT;
- read_index(r->index);
+ repo_read_index(r);
time(&now);
commit = alloc_commit_node(r);
commit->object.parsed = 1;
@@ -270,7 +270,7 @@ static struct commit *fake_working_tree_commit(struct repository *r,
* want to run "diff-index --cached".
*/
discard_index(r->index);
- read_index(r->index);
+ repo_read_index(r);
len = strlen(path);
if (!mode) {
diff --git a/builtin/am.c b/builtin/am.c
index d32044545d..901dc55078 100644
--- a/builtin/am.c
+++ b/builtin/am.c
@@ -2278,7 +2278,7 @@ int cmd_am(int argc, const char **argv, const char *prefix)
/* Ensure a valid committer ident can be constructed */
git_committer_info(IDENT_STRICT);
- if (read_index_preload(&the_index, NULL, 0) < 0)
+ if (repo_read_index_preload(the_repository, NULL, 0) < 0)
die(_("failed to read the index"));
if (in_progress) {
diff --git a/builtin/commit.c b/builtin/commit.c
index e29fb5e3eb..19eb6cff86 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -1367,7 +1367,7 @@ int cmd_status(int argc, const char **argv, const char *prefix)
if (status_format != STATUS_FORMAT_PORCELAIN &&
status_format != STATUS_FORMAT_PORCELAIN_V2)
progress_flag = REFRESH_PROGRESS;
- read_index(&the_index);
+ repo_read_index(the_repository);
refresh_index(&the_index,
REFRESH_QUIET|REFRESH_UNMERGED|progress_flag,
&s.pathspec, NULL, NULL);
diff --git a/builtin/diff-tree.c b/builtin/diff-tree.c
index ef996126d7..42bc1eb41d 100644
--- a/builtin/diff-tree.c
+++ b/builtin/diff-tree.c
@@ -165,7 +165,7 @@ int cmd_diff_tree(int argc, const char **argv, const char *prefix)
if (opt->diffopt.detect_rename) {
if (!the_index.cache)
- read_index(&the_index);
+ repo_read_index(the_repository);
opt->diffopt.setup |= DIFF_SETUP_USE_SIZE_CACHE;
}
while (fgets(line, sizeof(line), stdin)) {
diff --git a/builtin/rebase.c b/builtin/rebase.c
index 00de70365e..ce5f5b5a17 100644
--- a/builtin/rebase.c
+++ b/builtin/rebase.c
@@ -576,7 +576,7 @@ static int reset_head(struct object_id *oid, const char *action,
if (!detach_head)
unpack_tree_opts.reset = 1;
- if (read_index_unmerged(the_repository->index) < 0) {
+ if (repo_read_index_unmerged(the_repository) < 0) {
ret = error(_("could not read index"));
goto leave_reset_head;
}
@@ -1015,7 +1015,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
die(_("Cannot read HEAD"));
fd = hold_locked_index(&lock_file, 0);
- if (read_index(the_repository->index) < 0)
+ if (repo_read_index(the_repository) < 0)
die(_("could not read index"));
refresh_index(the_repository->index, REFRESH_QUIET, NULL, NULL,
NULL);
@@ -1368,7 +1368,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
get_fork_point(options.upstream_name, head);
}
- if (read_index(the_repository->index) < 0)
+ if (repo_read_index(the_repository) < 0)
die(_("could not read index"));
if (options.autostash) {
@@ -1423,7 +1423,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
putchar('\n');
if (discard_index(the_repository->index) < 0 ||
- read_index(the_repository->index) < 0)
+ repo_read_index(the_repository) < 0)
die(_("could not read index"));
}
}
diff --git a/cache.h b/cache.h
index 634c9ce325..3715808f52 100644
--- a/cache.h
+++ b/cache.h
@@ -408,11 +408,11 @@ void validate_cache_entries(const struct index_state *istate);
#define active_cache_changed (the_index.cache_changed)
#define active_cache_tree (the_index.cache_tree)
-#define read_cache() read_index(&the_index)
+#define read_cache() repo_read_index(the_repository)
#define read_cache_from(path) read_index_from(&the_index, (path), (get_git_dir()))
-#define read_cache_preload(pathspec) read_index_preload(&the_index, (pathspec), 0)
+#define read_cache_preload(pathspec) repo_read_index_preload(the_repository, (pathspec), 0)
#define is_cache_unborn() is_index_unborn(&the_index)
-#define read_cache_unmerged() read_index_unmerged(&the_index)
+#define read_cache_unmerged() repo_read_index_unmerged(the_repository)
#define discard_cache() discard_index(&the_index)
#define unmerged_cache() unmerged_index(&the_index)
#define cache_name_pos(name, namelen) index_name_pos(&the_index,(name),(namelen))
@@ -661,19 +661,14 @@ extern int daemonize(void);
/* Initialize and use the cache information */
struct lock_file;
-extern int read_index(struct index_state *);
extern void preload_index(struct index_state *index,
const struct pathspec *pathspec,
unsigned int refresh_flags);
-extern int read_index_preload(struct index_state *,
- const struct pathspec *pathspec,
- unsigned int refresh_flags);
extern int do_read_index(struct index_state *istate, const char *path,
int must_exist); /* for testting only! */
extern int read_index_from(struct index_state *, const char *path,
const char *gitdir);
extern int is_index_unborn(struct index_state *);
-extern int read_index_unmerged(struct index_state *);
/* For use with `write_locked_index()`. */
#define COMMIT_LOCK (1 << 0)
diff --git a/merge-recursive.c b/merge-recursive.c
index 8dba939d8f..5fbd4253c1 100644
--- a/merge-recursive.c
+++ b/merge-recursive.c
@@ -3576,7 +3576,7 @@ int merge_recursive(struct merge_options *o,
discard_cache();
if (!o->call_depth)
- read_cache();
+ repo_read_index(the_repository);
o->ancestor = "merged common ancestors";
clean = merge_trees(o, get_commit_tree(h1), get_commit_tree(h2),
diff --git a/merge.c b/merge.c
index dbbc9d9f80..7c1d756c3f 100644
--- a/merge.c
+++ b/merge.c
@@ -37,7 +37,7 @@ int try_merge_command(struct repository *r,
argv_array_clear(&args);
discard_index(r->index);
- if (read_index(r->index) < 0)
+ if (repo_read_index(r) < 0)
die(_("failed to read the cache"));
resolve_undo_clear_index(r->index);
diff --git a/preload-index.c b/preload-index.c
index c7dc3f2b9f..e73600ee78 100644
--- a/preload-index.c
+++ b/preload-index.c
@@ -8,6 +8,7 @@
#include "config.h"
#include "progress.h"
#include "thread-utils.h"
+#include "repository.h"
/*
* Mostly randomly chosen maximum thread counts: we
@@ -146,12 +147,12 @@ void preload_index(struct index_state *index,
trace_performance_leave("preload index");
}
-int read_index_preload(struct index_state *index,
- const struct pathspec *pathspec,
- unsigned int refresh_flags)
+int repo_read_index_preload(struct repository *repo,
+ const struct pathspec *pathspec,
+ unsigned int refresh_flags)
{
- int retval = read_index(index);
+ int retval = repo_read_index(repo);
- preload_index(index, pathspec, refresh_flags);
+ preload_index(repo->index, pathspec, refresh_flags);
return retval;
}
diff --git a/read-cache.c b/read-cache.c
index 1030e11051..afbf976107 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -1733,11 +1733,6 @@ static int read_index_extension(struct index_state *istate,
return 0;
}
-int read_index(struct index_state *istate)
-{
- return read_index_from(istate, get_index_file(), get_git_dir());
-}
-
static struct cache_entry *create_from_disk(struct mem_pool *ce_mem_pool,
unsigned int version,
struct ondisk_cache_entry *ondisk,
@@ -3218,12 +3213,14 @@ int write_locked_index(struct index_state *istate, struct lock_file *lock,
* state can call this and check its return value, instead of calling
* read_cache().
*/
-int read_index_unmerged(struct index_state *istate)
+int repo_read_index_unmerged(struct repository *repo)
{
+ struct index_state *istate;
int i;
int unmerged = 0;
- read_index(istate);
+ repo_read_index(repo);
+ istate = repo->index;
for (i = 0; i < istate->cache_nr; i++) {
struct cache_entry *ce = istate->cache[i];
struct cache_entry *new_ce;
diff --git a/repository.h b/repository.h
index 968330218f..cc3879add4 100644
--- a/repository.h
+++ b/repository.h
@@ -7,6 +7,7 @@ struct config_set;
struct git_hash_algo;
struct index_state;
struct lock_file;
+struct pathspec;
struct raw_object_store;
struct submodule_cache;
@@ -135,4 +136,9 @@ int repo_hold_locked_index(struct repository *repo,
struct lock_file *lf,
int flags);
+int repo_read_index_preload(struct repository *,
+ const struct pathspec *pathspec,
+ unsigned refresh_flags);
+int repo_read_index_unmerged(struct repository *);
+
#endif /* REPOSITORY_H */
diff --git a/rerere.c b/rerere.c
index fb0fdb2392..17abb47321 100644
--- a/rerere.c
+++ b/rerere.c
@@ -561,7 +561,7 @@ static int find_conflict(struct repository *r, struct string_list *conflict)
{
int i;
- if (read_index(r->index) < 0)
+ if (repo_read_index(r) < 0)
return error(_("index file corrupt"));
for (i = 0; i < r->index->cache_nr;) {
@@ -595,7 +595,7 @@ int rerere_remaining(struct repository *r, struct string_list *merge_rr)
if (setup_rerere(r, merge_rr, RERERE_READONLY))
return 0;
- if (read_index(r->index) < 0)
+ if (repo_read_index(r) < 0)
return error(_("index file corrupt"));
for (i = 0; i < r->index->cache_nr;) {
@@ -1107,7 +1107,7 @@ int rerere_forget(struct repository *r, struct pathspec *pathspec)
struct string_list conflict = STRING_LIST_INIT_DUP;
struct string_list merge_rr = STRING_LIST_INIT_DUP;
- if (read_index(r->index) < 0)
+ if (repo_read_index(r) < 0)
return error(_("index file corrupt"));
fd = setup_rerere(r, &merge_rr, RERERE_NOAUTOUPDATE);
diff --git a/revision.c b/revision.c
index 13e0519c02..c51ea6a052 100644
--- a/revision.c
+++ b/revision.c
@@ -1384,7 +1384,7 @@ void add_index_objects_to_pending(struct rev_info *revs, unsigned int flags)
{
struct worktree **worktrees, **p;
- read_index(revs->repo->index);
+ repo_read_index(revs->repo);
do_add_index_objects_to_pending(revs, revs->repo->index, flags);
if (revs->single_worktree)
@@ -1530,7 +1530,7 @@ static void prepare_show_merge(struct rev_info *revs)
head->object.flags |= SYMMETRIC_LEFT;
if (!istate->cache_nr)
- read_index(istate);
+ repo_read_index(revs->repo);
for (i = 0; i < istate->cache_nr; i++) {
const struct cache_entry *ce = istate->cache[i];
if (!ce_stage(ce))
diff --git a/sequencer.c b/sequencer.c
index 668c232b05..c2c9cc7e2b 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -446,9 +446,9 @@ static struct tree *empty_tree(struct repository *r)
return lookup_tree(r, the_hash_algo->empty_tree);
}
-static int error_dirty_index(struct index_state *istate, struct replay_opts *opts)
+static int error_dirty_index(struct repository *repo, struct replay_opts *opts)
{
- if (read_index_unmerged(istate))
+ if (repo_read_index_unmerged(repo))
return error_resolve_conflict(_(action_name(opts)));
error(_("your local changes would be overwritten by %s."),
@@ -483,7 +483,7 @@ static int fast_forward_to(struct repository *r,
struct strbuf sb = STRBUF_INIT;
struct strbuf err = STRBUF_INIT;
- read_index(r->index);
+ repo_read_index(r);
if (checkout_fast_forward(r, from, to, 1))
return -1; /* the callee should have complained already */
@@ -543,7 +543,7 @@ static int do_recursive_merge(struct repository *r,
if (repo_hold_locked_index(r, &index_lock, LOCK_REPORT_ON_ERROR) < 0)
return -1;
- read_index(r->index);
+ repo_read_index(r);
init_merge_options(&o);
o.ancestor = base ? base_label : "(empty tree)";
@@ -1766,7 +1766,7 @@ static int do_pick_commit(struct repository *r,
oidcpy(&head, the_hash_algo->empty_tree);
if (index_differs_from(r, unborn ? empty_tree_oid_hex() : "HEAD",
NULL, 0))
- return error_dirty_index(r->index, opts);
+ return error_dirty_index(r, opts);
}
discard_index(r->index);
@@ -2854,7 +2854,7 @@ static int do_exec(struct repository *r, const char *command_line)
child_env.argv);
/* force re-reading of the cache */
- if (discard_index(r->index) < 0 || read_index(r->index) < 0)
+ if (discard_index(r->index) < 0 || repo_read_index(r) < 0)
return error(_("could not read index"));
dirty = require_clean_work_tree(r, "rebase", NULL, 1, 1);
@@ -3023,7 +3023,7 @@ static int do_reset(struct repository *r,
unpack_tree_opts.merge = 1;
unpack_tree_opts.update = 1;
- if (read_index_unmerged(r->index)) {
+ if (repo_read_index_unmerged(r)) {
rollback_lock_file(&lock);
strbuf_release(&ref_name);
return error_resolve_conflict(_(action_name(opts)));
@@ -3277,7 +3277,7 @@ static int do_merge(struct repository *r,
/* force re-reading of the cache */
if (!ret && (discard_index(r->index) < 0 ||
- read_index(r->index) < 0))
+ repo_read_index(r) < 0))
ret = error(_("could not read index"));
goto leave_merge;
}
@@ -3299,7 +3299,7 @@ static int do_merge(struct repository *r,
commit_list_insert(j->item, &reversed);
free_commit_list(bases);
- read_index(r->index);
+ repo_read_index(r);
init_merge_options(&o);
o.branch1 = "HEAD";
o.branch2 = ref_name.buf;
@@ -3972,7 +3972,7 @@ int sequencer_continue(struct repository *r, struct replay_opts *opts)
goto release_todo_list;
}
if (index_differs_from(r, "HEAD", NULL, 0)) {
- res = error_dirty_index(r->index, opts);
+ res = error_dirty_index(r, opts);
goto release_todo_list;
}
todo_list.current++;
diff --git a/sha1-name.c b/sha1-name.c
index b24502811b..a0fc1008ec 100644
--- a/sha1-name.c
+++ b/sha1-name.c
@@ -1723,9 +1723,9 @@ static int get_oid_with_context_1(const char *name,
if (flags & GET_OID_RECORD_PATH)
oc->path = xstrdup(cp);
- if (!active_cache)
- read_cache();
- pos = cache_name_pos(cp, namelen);
+ if (!the_index.cache)
+ repo_read_index(the_repository);
+ pos = index_name_pos(&the_index, cp, namelen);
if (pos < 0)
pos = -pos - 1;
while (pos < active_nr) {
--
2.20.0.482.g66447595a7
^ permalink raw reply related
* [PATCH 05/10] read-cache.c: replace update_index_if_able with repo_&
From: Nguyễn Thái Ngọc Duy @ 2019-01-05 5:51 UTC (permalink / raw)
To: git; +Cc: Nguyễn Thái Ngọc Duy
In-Reply-To: <20190105055153.3256-1-pclouds@gmail.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
builtin/commit.c | 2 +-
builtin/describe.c | 2 +-
builtin/diff.c | 2 +-
builtin/rebase.c | 5 ++---
cache.h | 6 ------
read-cache.c | 14 ++++++++------
repository.h | 6 ++++++
wt-status.c | 2 +-
8 files changed, 20 insertions(+), 19 deletions(-)
diff --git a/builtin/commit.c b/builtin/commit.c
index 19eb6cff86..d3f1234bf0 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -1396,7 +1396,7 @@ int cmd_status(int argc, const char **argv, const char *prefix)
wt_status_collect(&s);
if (0 <= fd)
- update_index_if_able(&the_index, &index_lock);
+ repo_update_index_if_able(the_repository, &index_lock);
if (s.relative_paths)
s.prefix = prefix;
diff --git a/builtin/describe.c b/builtin/describe.c
index cc118448ee..bc97e50650 100644
--- a/builtin/describe.c
+++ b/builtin/describe.c
@@ -634,7 +634,7 @@ int cmd_describe(int argc, const char **argv, const char *prefix)
NULL, NULL, NULL);
fd = hold_locked_index(&index_lock, 0);
if (0 <= fd)
- update_index_if_able(&the_index, &index_lock);
+ repo_update_index_if_able(the_repository, &index_lock);
repo_init_revisions(the_repository, &revs, prefix);
argv_array_pushv(&args, diff_index_args);
diff --git a/builtin/diff.c b/builtin/diff.c
index f0393bba23..ec78920ee2 100644
--- a/builtin/diff.c
+++ b/builtin/diff.c
@@ -212,7 +212,7 @@ static void refresh_index_quietly(void)
discard_cache();
read_cache();
refresh_cache(REFRESH_QUIET|REFRESH_UNMERGED);
- update_index_if_able(&the_index, &lock_file);
+ repo_update_index_if_able(the_repository, &lock_file);
}
static int builtin_diff_files(struct rev_info *revs, int argc, const char **argv)
diff --git a/builtin/rebase.c b/builtin/rebase.c
index ce5f5b5a17..7124e66d00 100644
--- a/builtin/rebase.c
+++ b/builtin/rebase.c
@@ -1020,8 +1020,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
refresh_index(the_repository->index, REFRESH_QUIET, NULL, NULL,
NULL);
if (0 <= fd)
- update_index_if_able(the_repository->index,
- &lock_file);
+ repo_update_index_if_able(the_repository, &lock_file);
rollback_lock_file(&lock_file);
if (has_unstaged_changes(the_repository, 1)) {
@@ -1378,7 +1377,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
fd = hold_locked_index(&lock_file, 0);
refresh_cache(REFRESH_QUIET);
if (0 <= fd)
- update_index_if_able(&the_index, &lock_file);
+ repo_update_index_if_able(the_repository, &lock_file);
rollback_lock_file(&lock_file);
if (has_unstaged_changes(the_repository, 1) ||
diff --git a/cache.h b/cache.h
index 3715808f52..702c5bfbb3 100644
--- a/cache.h
+++ b/cache.h
@@ -823,12 +823,6 @@ extern void fill_stat_cache_info(struct cache_entry *ce, struct stat *st);
extern int refresh_index(struct index_state *, unsigned int flags, const struct pathspec *pathspec, char *seen, const char *header_msg);
extern struct cache_entry *refresh_cache_entry(struct index_state *, struct cache_entry *, unsigned int);
-/*
- * Opportunistically update the index but do not complain if we can't.
- * The lockfile is always committed or rolled back.
- */
-extern void update_index_if_able(struct index_state *, struct lock_file *);
-
extern void set_alternate_index_output(const char *);
extern int verify_index_checksum;
diff --git a/read-cache.c b/read-cache.c
index afbf976107..61cc0571da 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -2654,9 +2654,9 @@ static int verify_index_from(const struct index_state *istate, const char *path)
return 0;
}
-static int verify_index(const struct index_state *istate)
+static int repo_verify_index(struct repository *repo)
{
- return verify_index_from(istate, get_index_file());
+ return verify_index_from(repo->index, repo->index_file);
}
static int has_racy_timestamp(struct index_state *istate)
@@ -2672,11 +2672,13 @@ static int has_racy_timestamp(struct index_state *istate)
return 0;
}
-void update_index_if_able(struct index_state *istate, struct lock_file *lockfile)
+void repo_update_index_if_able(struct repository *repo,
+ struct lock_file *lockfile)
{
- if ((istate->cache_changed || has_racy_timestamp(istate)) &&
- verify_index(istate))
- write_locked_index(istate, lockfile, COMMIT_LOCK);
+ if ((repo->index->cache_changed ||
+ has_racy_timestamp(repo->index)) &&
+ repo_verify_index(repo))
+ write_locked_index(repo->index, lockfile, COMMIT_LOCK);
else
rollback_lock_file(lockfile);
}
diff --git a/repository.h b/repository.h
index cc3879add4..6fe1c089db 100644
--- a/repository.h
+++ b/repository.h
@@ -140,5 +140,11 @@ int repo_read_index_preload(struct repository *,
const struct pathspec *pathspec,
unsigned refresh_flags);
int repo_read_index_unmerged(struct repository *);
+/*
+ * Opportunistically update the index but do not complain if we can't.
+ * The lockfile is always committed or rolled back.
+ */
+void repo_update_index_if_able(struct repository *, struct lock_file *);
+
#endif /* REPOSITORY_H */
diff --git a/wt-status.c b/wt-status.c
index becf78b04f..1f564b12d2 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -2378,7 +2378,7 @@ int require_clean_work_tree(struct repository *r,
fd = repo_hold_locked_index(r, &lock_file, 0);
refresh_index(r->index, REFRESH_QUIET, NULL, NULL, NULL);
if (0 <= fd)
- update_index_if_able(r->index, &lock_file);
+ repo_update_index_if_able(r, &lock_file);
rollback_lock_file(&lock_file);
if (has_unstaged_changes(r, ignore_submodules)) {
--
2.20.0.482.g66447595a7
^ permalink raw reply related
* [PATCH 06/10] sha1-name.c: remove implicit dependency on the_index
From: Nguyễn Thái Ngọc Duy @ 2019-01-05 5:51 UTC (permalink / raw)
To: git; +Cc: Nguyễn Thái Ngọc Duy
In-Reply-To: <20190105055153.3256-1-pclouds@gmail.com>
This kills the_index dependency in get_oid_with_context() but for
get_oid() and friends, they still assume the_repository (which also
means the_index).
Unfortunately the widespread use of get_oid() will make it hard to
make the conversion now. We probably will add repo_get_oid() at some
point and limit the use of get_oid() in builtin/ instead of forcing
all get_oid() call sites to carry struct repository.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
builtin/cat-file.c | 6 ++--
builtin/grep.c | 3 +-
builtin/log.c | 3 +-
builtin/rev-parse.c | 3 +-
cache.h | 4 ++-
list-objects-filter-options.c | 2 +-
revision.c | 8 +++---
sha1-name.c | 54 +++++++++++++++++++++--------------
8 files changed, 50 insertions(+), 33 deletions(-)
diff --git a/builtin/cat-file.c b/builtin/cat-file.c
index 2ca56fd086..7622c502f0 100644
--- a/builtin/cat-file.c
+++ b/builtin/cat-file.c
@@ -73,7 +73,8 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,
if (unknown_type)
flags |= OBJECT_INFO_ALLOW_UNKNOWN_TYPE;
- if (get_oid_with_context(obj_name, GET_OID_RECORD_PATH,
+ if (get_oid_with_context(the_repository, obj_name,
+ GET_OID_RECORD_PATH,
&oid, &obj_context))
die("Not a valid object name %s", obj_name);
@@ -382,7 +383,8 @@ static void batch_one_object(const char *obj_name,
int flags = opt->follow_symlinks ? GET_OID_FOLLOW_SYMLINKS : 0;
enum follow_symlinks_result result;
- result = get_oid_with_context(obj_name, flags, &data->oid, &ctx);
+ result = get_oid_with_context(the_repository, obj_name,
+ flags, &data->oid, &ctx);
if (result != FOUND) {
switch (result) {
case MISSING_OBJECT:
diff --git a/builtin/grep.c b/builtin/grep.c
index bad9c0a3d5..3d695ad8fe 100644
--- a/builtin/grep.c
+++ b/builtin/grep.c
@@ -1014,7 +1014,8 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
break;
}
- if (get_oid_with_context(arg, GET_OID_RECORD_PATH,
+ if (get_oid_with_context(the_repository, arg,
+ GET_OID_RECORD_PATH,
&oid, &oc)) {
if (seen_dashdash)
die(_("unable to resolve revision: %s"), arg);
diff --git a/builtin/log.c b/builtin/log.c
index e8e51068bd..dbfb4e31ad 100644
--- a/builtin/log.c
+++ b/builtin/log.c
@@ -508,7 +508,8 @@ static int show_blob_object(const struct object_id *oid, struct rev_info *rev, c
!rev->diffopt.flags.allow_textconv)
return stream_blob_to_fd(1, oid, NULL, 0);
- if (get_oid_with_context(obj_name, GET_OID_RECORD_PATH,
+ if (get_oid_with_context(the_repository, obj_name,
+ GET_OID_RECORD_PATH,
&oidc, &obj_context))
die(_("Not a valid object name %s"), obj_name);
if (!obj_context.path ||
diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c
index 10d4dab894..910a71ed8b 100644
--- a/builtin/rev-parse.c
+++ b/builtin/rev-parse.c
@@ -933,7 +933,8 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
name++;
type = REVERSED;
}
- if (!get_oid_with_context(name, flags, &oid, &unused)) {
+ if (!get_oid_with_context(the_repository, name,
+ flags, &oid, &unused)) {
if (verify)
revs_count++;
else
diff --git a/cache.h b/cache.h
index 702c5bfbb3..fdcd69bfb0 100644
--- a/cache.h
+++ b/cache.h
@@ -1328,7 +1328,9 @@ extern int get_oid_tree(const char *str, struct object_id *oid);
extern int get_oid_treeish(const char *str, struct object_id *oid);
extern int get_oid_blob(const char *str, struct object_id *oid);
extern void maybe_die_on_misspelt_object_name(const char *name, const char *prefix);
-extern int get_oid_with_context(const char *str, unsigned flags, struct object_id *oid, struct object_context *oc);
+extern int get_oid_with_context(struct repository *repo, const char *str,
+ unsigned flags, struct object_id *oid,
+ struct object_context *oc);
typedef int each_abbrev_fn(const struct object_id *oid, void *);
diff --git a/list-objects-filter-options.c b/list-objects-filter-options.c
index e8da2e8581..8443184e22 100644
--- a/list-objects-filter-options.c
+++ b/list-objects-filter-options.c
@@ -71,7 +71,7 @@ static int gently_parse_list_objects_filter(
* command, but DO NOT complain if we don't have the blob or
* ref locally.
*/
- if (!get_oid_with_context(v0, GET_OID_BLOB,
+ if (!get_oid_with_context(the_repository, v0, GET_OID_BLOB,
&sparse_oid, &oc))
filter_options->sparse_oid_value = oiddup(&sparse_oid);
filter_options->choice = LOFC_SPARSE_OID;
diff --git a/revision.c b/revision.c
index c51ea6a052..4a723efe9a 100644
--- a/revision.c
+++ b/revision.c
@@ -1589,8 +1589,8 @@ static int handle_dotdot_1(const char *arg, char *dotdot,
if (!*b_name)
b_name = "HEAD";
- if (get_oid_with_context(a_name, oc_flags, &a_oid, a_oc) ||
- get_oid_with_context(b_name, oc_flags, &b_oid, b_oc))
+ if (get_oid_with_context(revs->repo, a_name, oc_flags, &a_oid, a_oc) ||
+ get_oid_with_context(revs->repo, b_name, oc_flags, &b_oid, b_oc))
return -1;
if (!cant_be_filename) {
@@ -1724,7 +1724,7 @@ int handle_revision_arg(const char *arg_, struct rev_info *revs, int flags, unsi
if (revarg_opt & REVARG_COMMITTISH)
get_sha1_flags |= GET_OID_COMMITTISH;
- if (get_oid_with_context(arg, get_sha1_flags, &oid, &oc))
+ if (get_oid_with_context(revs->repo, arg, get_sha1_flags, &oid, &oc))
return revs->ignore_missing ? 0 : -1;
if (!cant_be_filename)
verify_non_filename(revs->prefix, arg);
@@ -2453,7 +2453,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s
struct object_id oid;
struct object *object;
struct object_context oc;
- if (get_oid_with_context(revs->def, 0, &oid, &oc))
+ if (get_oid_with_context(revs->repo, revs->def, 0, &oid, &oc))
diagnose_missing_default(revs->def);
object = get_reference(revs, revs->def, &oid, 0);
add_pending_object_with_mode(revs, object, revs->def, oc.mode);
diff --git a/sha1-name.c b/sha1-name.c
index a0fc1008ec..d8cab7b5a6 100644
--- a/sha1-name.c
+++ b/sha1-name.c
@@ -1513,7 +1513,7 @@ int strbuf_check_branch_ref(struct strbuf *sb, const char *name)
int get_oid(const char *name, struct object_id *oid)
{
struct object_context unused;
- return get_oid_with_context(name, 0, oid, &unused);
+ return get_oid_with_context(the_repository, name, 0, oid, &unused);
}
@@ -1530,35 +1530,40 @@ int get_oid(const char *name, struct object_id *oid)
int get_oid_committish(const char *name, struct object_id *oid)
{
struct object_context unused;
- return get_oid_with_context(name, GET_OID_COMMITTISH,
+ return get_oid_with_context(the_repository,
+ name, GET_OID_COMMITTISH,
oid, &unused);
}
int get_oid_treeish(const char *name, struct object_id *oid)
{
struct object_context unused;
- return get_oid_with_context(name, GET_OID_TREEISH,
+ return get_oid_with_context(the_repository,
+ name, GET_OID_TREEISH,
oid, &unused);
}
int get_oid_commit(const char *name, struct object_id *oid)
{
struct object_context unused;
- return get_oid_with_context(name, GET_OID_COMMIT,
+ return get_oid_with_context(the_repository,
+ name, GET_OID_COMMIT,
oid, &unused);
}
int get_oid_tree(const char *name, struct object_id *oid)
{
struct object_context unused;
- return get_oid_with_context(name, GET_OID_TREE,
+ return get_oid_with_context(the_repository,
+ name, GET_OID_TREE,
oid, &unused);
}
int get_oid_blob(const char *name, struct object_id *oid)
{
struct object_context unused;
- return get_oid_with_context(name, GET_OID_BLOB,
+ return get_oid_with_context(the_repository,
+ name, GET_OID_BLOB,
oid, &unused);
}
@@ -1597,7 +1602,8 @@ static void diagnose_invalid_oid_path(const char *prefix,
}
/* Must be called only when :stage:filename doesn't exist. */
-static void diagnose_invalid_index_path(int stage,
+static void diagnose_invalid_index_path(struct index_state *istate,
+ int stage,
const char *prefix,
const char *filename)
{
@@ -1610,11 +1616,11 @@ static void diagnose_invalid_index_path(int stage,
prefix = "";
/* Wrong stage number? */
- pos = cache_name_pos(filename, namelen);
+ pos = index_name_pos(istate, filename, namelen);
if (pos < 0)
pos = -pos - 1;
- if (pos < active_nr) {
- ce = active_cache[pos];
+ if (pos < istate->cache_nr) {
+ ce = istate->cache[pos];
if (ce_namelen(ce) == namelen &&
!memcmp(ce->name, filename, namelen))
die("Path '%s' is in the index, but not at stage %d.\n"
@@ -1626,11 +1632,11 @@ static void diagnose_invalid_index_path(int stage,
/* Confusion between relative and absolute filenames? */
strbuf_addstr(&fullname, prefix);
strbuf_addstr(&fullname, filename);
- pos = cache_name_pos(fullname.buf, fullname.len);
+ pos = index_name_pos(istate, fullname.buf, fullname.len);
if (pos < 0)
pos = -pos - 1;
- if (pos < active_nr) {
- ce = active_cache[pos];
+ if (pos < istate->cache_nr) {
+ ce = istate->cache[pos];
if (ce_namelen(ce) == fullname.len &&
!memcmp(ce->name, fullname.buf, fullname.len))
die("Path '%s' is in the index, but not '%s'.\n"
@@ -1664,7 +1670,8 @@ static char *resolve_relative_path(const char *rel)
rel);
}
-static int get_oid_with_context_1(const char *name,
+static int get_oid_with_context_1(struct repository *repo,
+ const char *name,
unsigned flags,
const char *prefix,
struct object_id *oid,
@@ -1723,13 +1730,13 @@ static int get_oid_with_context_1(const char *name,
if (flags & GET_OID_RECORD_PATH)
oc->path = xstrdup(cp);
- if (!the_index.cache)
+ if (!repo->index->cache)
repo_read_index(the_repository);
- pos = index_name_pos(&the_index, cp, namelen);
+ pos = index_name_pos(repo->index, cp, namelen);
if (pos < 0)
pos = -pos - 1;
- while (pos < active_nr) {
- ce = active_cache[pos];
+ while (pos < repo->index->cache_nr) {
+ ce = repo->index->cache[pos];
if (ce_namelen(ce) != namelen ||
memcmp(ce->name, cp, namelen))
break;
@@ -1742,7 +1749,7 @@ static int get_oid_with_context_1(const char *name,
pos++;
}
if (only_to_die && name[1] && name[1] != '/')
- diagnose_invalid_index_path(stage, prefix, cp);
+ diagnose_invalid_index_path(repo->index, stage, prefix, cp);
free(new_path);
return -1;
}
@@ -1807,12 +1814,15 @@ void maybe_die_on_misspelt_object_name(const char *name, const char *prefix)
{
struct object_context oc;
struct object_id oid;
- get_oid_with_context_1(name, GET_OID_ONLY_TO_DIE, prefix, &oid, &oc);
+ get_oid_with_context_1(the_repository, name, GET_OID_ONLY_TO_DIE,
+ prefix, &oid, &oc);
}
-int get_oid_with_context(const char *str, unsigned flags, struct object_id *oid, struct object_context *oc)
+int get_oid_with_context(struct repository *repo, const char *str,
+ unsigned flags, struct object_id *oid,
+ struct object_context *oc)
{
if (flags & GET_OID_FOLLOW_SYMLINKS && flags & GET_OID_ONLY_TO_DIE)
BUG("incompatible flags for get_sha1_with_context");
- return get_oid_with_context_1(str, flags, NULL, oid, oc);
+ return get_oid_with_context_1(repo, str, flags, NULL, oid, oc);
}
--
2.20.0.482.g66447595a7
^ permalink raw reply related
* [PATCH 07/10] merge-recursive.c: remove implicit dependency on the_index
From: Nguyễn Thái Ngọc Duy @ 2019-01-05 5:51 UTC (permalink / raw)
To: git; +Cc: Nguyễn Thái Ngọc Duy
In-Reply-To: <20190105055153.3256-1-pclouds@gmail.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
builtin/am.c | 2 +-
builtin/checkout.c | 2 +-
builtin/merge-recursive.c | 2 +-
builtin/merge.c | 2 +-
merge-recursive.c | 148 ++++++++++++++++++++------------------
merge-recursive.h | 6 +-
sequencer.c | 4 +-
7 files changed, 91 insertions(+), 75 deletions(-)
diff --git a/builtin/am.c b/builtin/am.c
index 901dc55078..611712dc95 100644
--- a/builtin/am.c
+++ b/builtin/am.c
@@ -1545,7 +1545,7 @@ static int fall_back_threeway(const struct am_state *state, const char *index_pa
* changes.
*/
- init_merge_options(&o);
+ init_merge_options(&o, the_repository);
o.branch1 = "HEAD";
their_tree_name = xstrfmt("%.*s", linelen(state->msg), state->msg);
diff --git a/builtin/checkout.c b/builtin/checkout.c
index 1b672a9fd9..a95ba2c6dc 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -670,7 +670,7 @@ static int merge_working_tree(const struct checkout_opts *opts,
* a pain; plumb in an option to set
* o.renormalize?
*/
- init_merge_options(&o);
+ init_merge_options(&o, the_repository);
o.verbosity = 0;
work = write_tree_from_memory(&o);
diff --git a/builtin/merge-recursive.c b/builtin/merge-recursive.c
index 9b2f707c29..4864f7b22f 100644
--- a/builtin/merge-recursive.c
+++ b/builtin/merge-recursive.c
@@ -28,7 +28,7 @@ int cmd_merge_recursive(int argc, const char **argv, const char *prefix)
struct merge_options o;
struct commit *result;
- init_merge_options(&o);
+ init_merge_options(&o, the_repository);
if (argv[0] && ends_with(argv[0], "-subtree"))
o.subtree_shift = "";
diff --git a/builtin/merge.c b/builtin/merge.c
index dc0b7cc521..bc1aecfe70 100644
--- a/builtin/merge.c
+++ b/builtin/merge.c
@@ -702,7 +702,7 @@ static int try_merge_strategy(const char *strategy, struct commit_list *common,
return 2;
}
- init_merge_options(&o);
+ init_merge_options(&o, the_repository);
if (!strcmp(strategy, "subtree"))
o.subtree_shift = "";
diff --git a/merge-recursive.c b/merge-recursive.c
index 5fbd4253c1..28f44c73ec 100644
--- a/merge-recursive.c
+++ b/merge-recursive.c
@@ -343,22 +343,24 @@ static int add_cacheinfo(struct merge_options *o,
unsigned int mode, const struct object_id *oid,
const char *path, int stage, int refresh, int options)
{
+ struct index_state *istate = o->repo->index;
struct cache_entry *ce;
int ret;
- ce = make_cache_entry(&the_index, mode, oid ? oid : &null_oid, path, stage, 0);
+ ce = make_cache_entry(istate, mode, oid ? oid : &null_oid, path, stage, 0);
if (!ce)
return err(o, _("add_cacheinfo failed for path '%s'; merge aborting."), path);
- ret = add_cache_entry(ce, options);
+ ret = add_index_entry(istate, ce, options);
if (refresh) {
struct cache_entry *nce;
- nce = refresh_cache_entry(&the_index, ce, CE_MATCH_REFRESH | CE_MATCH_IGNORE_MISSING);
+ nce = refresh_cache_entry(istate, ce,
+ CE_MATCH_REFRESH | CE_MATCH_IGNORE_MISSING);
if (!nce)
return err(o, _("add_cacheinfo failed to refresh for path '%s'; merge aborting."), path);
if (nce != ce)
- ret = add_cache_entry(nce, options);
+ ret = add_index_entry(istate, nce, options);
}
return ret;
}
@@ -386,7 +388,7 @@ static int unpack_trees_start(struct merge_options *o,
o->unpack_opts.merge = 1;
o->unpack_opts.head_idx = 2;
o->unpack_opts.fn = threeway_merge;
- o->unpack_opts.src_index = &the_index;
+ o->unpack_opts.src_index = o->repo->index;
o->unpack_opts.dst_index = &tmp_index;
o->unpack_opts.aggressive = !merge_detect_rename(o);
setup_unpack_trees_porcelain(&o->unpack_opts, "merge");
@@ -396,16 +398,16 @@ static int unpack_trees_start(struct merge_options *o,
init_tree_desc_from_tree(t+2, merge);
rc = unpack_trees(3, t, &o->unpack_opts);
- cache_tree_free(&active_cache_tree);
+ cache_tree_free(&o->repo->index->cache_tree);
/*
- * Update the_index to match the new results, AFTER saving a copy
+ * Update o->repo->index to match the new results, AFTER saving a copy
* in o->orig_index. Update src_index to point to the saved copy.
* (verify_uptodate() checks src_index, and the original index is
* the one that had the necessary modification timestamps.)
*/
- o->orig_index = the_index;
- the_index = tmp_index;
+ o->orig_index = *o->repo->index;
+ *o->repo->index = tmp_index;
o->unpack_opts.src_index = &o->orig_index;
return rc;
@@ -420,12 +422,13 @@ static void unpack_trees_finish(struct merge_options *o)
struct tree *write_tree_from_memory(struct merge_options *o)
{
struct tree *result = NULL;
+ struct index_state *istate = o->repo->index;
- if (unmerged_cache()) {
+ if (unmerged_index(istate)) {
int i;
fprintf(stderr, "BUG: There are unmerged index entries:\n");
- for (i = 0; i < active_nr; i++) {
- const struct cache_entry *ce = active_cache[i];
+ for (i = 0; i < istate->cache_nr; i++) {
+ const struct cache_entry *ce = istate->cache[i];
if (ce_stage(ce))
fprintf(stderr, "BUG: %d %.*s\n", ce_stage(ce),
(int)ce_namelen(ce), ce->name);
@@ -433,16 +436,16 @@ struct tree *write_tree_from_memory(struct merge_options *o)
BUG("unmerged index entries in merge-recursive.c");
}
- if (!active_cache_tree)
- active_cache_tree = cache_tree();
+ if (!istate->cache_tree)
+ istate->cache_tree = cache_tree();
- if (!cache_tree_fully_valid(active_cache_tree) &&
- cache_tree_update(&the_index, 0) < 0) {
+ if (!cache_tree_fully_valid(istate->cache_tree) &&
+ cache_tree_update(istate, 0) < 0) {
err(o, _("error building trees"));
return NULL;
}
- result = lookup_tree(the_repository, &active_cache_tree->oid);
+ result = lookup_tree(the_repository, &istate->cache_tree->oid);
return result;
}
@@ -512,17 +515,17 @@ static struct stage_data *insert_stage_data(const char *path,
* Create a dictionary mapping file names to stage_data objects. The
* dictionary contains one entry for every path with a non-zero stage entry.
*/
-static struct string_list *get_unmerged(void)
+static struct string_list *get_unmerged(struct index_state *istate)
{
struct string_list *unmerged = xcalloc(1, sizeof(struct string_list));
int i;
unmerged->strdup_strings = 1;
- for (i = 0; i < active_nr; i++) {
+ for (i = 0; i < istate->cache_nr; i++) {
struct string_list_item *item;
struct stage_data *e;
- const struct cache_entry *ce = active_cache[i];
+ const struct cache_entry *ce = istate->cache[i];
if (!ce_stage(ce))
continue;
@@ -682,7 +685,7 @@ static int update_stages(struct merge_options *opt, const char *path,
int clear = 1;
int options = ADD_CACHE_OK_TO_ADD | ADD_CACHE_SKIP_DFCHECK;
if (clear)
- if (remove_file_from_cache(path))
+ if (remove_file_from_index(opt->repo->index, path))
return -1;
if (o)
if (add_cacheinfo(opt, o->mode, &o->oid, path, 1, 0, options))
@@ -717,13 +720,14 @@ static int remove_file(struct merge_options *o, int clean,
int update_working_directory = !o->call_depth && !no_wd;
if (update_cache) {
- if (remove_file_from_cache(path))
+ if (remove_file_from_index(o->repo->index, path))
return -1;
}
if (update_working_directory) {
if (ignore_case) {
struct cache_entry *ce;
- ce = cache_file_exists(path, strlen(path), ignore_case);
+ ce = index_file_exists(o->repo->index, path, strlen(path),
+ ignore_case);
if (ce && ce_stage(ce) == 0 && strcmp(path, ce->name))
return 0;
}
@@ -773,7 +777,8 @@ static char *unique_path(struct merge_options *o, const char *path, const char *
* check the working directory. If empty_ok is non-zero, also return
* 0 in the case where the working-tree dir exists but is empty.
*/
-static int dir_in_way(const char *path, int check_working_copy, int empty_ok)
+static int dir_in_way(struct index_state *istate, const char *path,
+ int check_working_copy, int empty_ok)
{
int pos;
struct strbuf dirpath = STRBUF_INIT;
@@ -782,12 +787,12 @@ static int dir_in_way(const char *path, int check_working_copy, int empty_ok)
strbuf_addstr(&dirpath, path);
strbuf_addch(&dirpath, '/');
- pos = cache_name_pos(dirpath.buf, dirpath.len);
+ pos = index_name_pos(istate, dirpath.buf, dirpath.len);
if (pos < 0)
pos = -1 - pos;
- if (pos < active_nr &&
- !strncmp(dirpath.buf, active_cache[pos]->name, dirpath.len)) {
+ if (pos < istate->cache_nr &&
+ !strncmp(dirpath.buf, istate->cache[pos]->name, dirpath.len)) {
strbuf_release(&dirpath);
return 1;
}
@@ -830,8 +835,10 @@ static int was_tracked(struct merge_options *o, const char *path)
return 0;
}
-static int would_lose_untracked(const char *path)
+static int would_lose_untracked(struct merge_options *o, const char *path)
{
+ struct index_state *istate = o->repo->index;
+
/*
* This may look like it can be simplified to:
* return !was_tracked(o, path) && file_exists(path)
@@ -849,19 +856,19 @@ static int would_lose_untracked(const char *path)
* update_file()/would_lose_untracked(); see every comment in this
* file which mentions "update_stages".
*/
- int pos = cache_name_pos(path, strlen(path));
+ int pos = index_name_pos(istate, path, strlen(path));
if (pos < 0)
pos = -1 - pos;
- while (pos < active_nr &&
- !strcmp(path, active_cache[pos]->name)) {
+ while (pos < istate->cache_nr &&
+ !strcmp(path, istate->cache[pos]->name)) {
/*
* If stage #0, it is definitely tracked.
* If it has stage #2 then it was tracked
* before this merge started. All other
* cases the path was not tracked.
*/
- switch (ce_stage(active_cache[pos])) {
+ switch (ce_stage(istate->cache[pos])) {
case 0:
case 2:
return 0;
@@ -921,7 +928,7 @@ static int make_room_for_path(struct merge_options *o, const char *path)
* Do not unlink a file in the work tree if we are not
* tracking it.
*/
- if (would_lose_untracked(path))
+ if (would_lose_untracked(o, path))
return err(o, _("refusing to lose untracked file at '%s'"),
path);
@@ -971,7 +978,7 @@ static int update_file_flags(struct merge_options *o,
}
if (S_ISREG(mode)) {
struct strbuf strbuf = STRBUF_INIT;
- if (convert_to_working_tree(&the_index, path, buf, size, &strbuf)) {
+ if (convert_to_working_tree(o->repo->index, path, buf, size, &strbuf)) {
free(buf);
size = strbuf.len;
buf = strbuf_detach(&strbuf, NULL);
@@ -1091,7 +1098,7 @@ static int merge_3way(struct merge_options *o,
merge_status = ll_merge(result_buf, a->path, &orig, base_name,
&src1, name1, &src2, name2,
- &the_index, &ll_opts);
+ o->repo->index, &ll_opts);
free(base_name);
free(name1);
@@ -1102,7 +1109,8 @@ static int merge_3way(struct merge_options *o,
return merge_status;
}
-static int find_first_merges(struct object_array *result, const char *path,
+static int find_first_merges(struct repository *repo,
+ struct object_array *result, const char *path,
struct commit *a, struct commit *b)
{
int i, j;
@@ -1122,7 +1130,7 @@ static int find_first_merges(struct object_array *result, const char *path,
/* get all revisions that merge commit a */
xsnprintf(merged_revision, sizeof(merged_revision), "^%s",
oid_to_hex(&a->object.oid));
- repo_init_revisions(the_repository, &revs, NULL);
+ repo_init_revisions(repo, &revs, NULL);
rev_opts.submodule = path;
/* FIXME: can't handle linked worktrees in submodules yet */
revs.single_worktree = path != NULL;
@@ -1252,7 +1260,8 @@ static int merge_submodule(struct merge_options *o,
return 0;
/* find commit which merges them */
- parent_count = find_first_merges(&merges, path, commit_a, commit_b);
+ parent_count = find_first_merges(o->repo, &merges, path,
+ commit_a, commit_b);
switch (parent_count) {
case 0:
output(o, 1, _("Failed to merge submodule %s (merge following commits not found)"), path);
@@ -1400,7 +1409,7 @@ static int handle_rename_via_dir(struct merge_options *o,
*/
const struct diff_filespec *dest = pair->two;
- if (!o->call_depth && would_lose_untracked(dest->path)) {
+ if (!o->call_depth && would_lose_untracked(o, dest->path)) {
char *alt_path = unique_path(o, dest->path, rename_branch);
output(o, 1, _("Error: Refusing to lose untracked file at %s; "
@@ -1438,8 +1447,8 @@ static int handle_change_delete(struct merge_options *o,
const char *update_path = path;
int ret = 0;
- if (dir_in_way(path, !o->call_depth, 0) ||
- (!o->call_depth && would_lose_untracked(path))) {
+ if (dir_in_way(o->repo->index, path, !o->call_depth, 0) ||
+ (!o->call_depth && would_lose_untracked(o, path))) {
update_path = alt_path = unique_path(o, path, change_branch);
}
@@ -1449,7 +1458,7 @@ static int handle_change_delete(struct merge_options *o,
* correct; since there is no true "middle point" between
* them, simply reuse the base version for virtual merge base.
*/
- ret = remove_file_from_cache(path);
+ ret = remove_file_from_index(o->repo->index, path);
if (!ret)
ret = update_file(o, 0, o_oid, o_mode, update_path);
} else {
@@ -1525,7 +1534,7 @@ static int handle_rename_delete(struct merge_options *o,
return -1;
if (o->call_depth)
- return remove_file_from_cache(dest->path);
+ return remove_file_from_index(o->repo->index, dest->path);
else
return update_stages(o, dest->path, NULL,
rename_branch == o->branch1 ? dest : NULL,
@@ -1606,10 +1615,10 @@ static int handle_file_collision(struct merge_options *o,
/* Remove rename sources if rename/add or rename/rename(2to1) */
if (prev_path1)
remove_file(o, 1, prev_path1,
- o->call_depth || would_lose_untracked(prev_path1));
+ o->call_depth || would_lose_untracked(o, prev_path1));
if (prev_path2)
remove_file(o, 1, prev_path2,
- o->call_depth || would_lose_untracked(prev_path2));
+ o->call_depth || would_lose_untracked(o, prev_path2));
/*
* Remove the collision path, if it wouldn't cause dirty contents
@@ -1620,7 +1629,7 @@ static int handle_file_collision(struct merge_options *o,
output(o, 1, _("Refusing to lose dirty file at %s"),
collide_path);
update_path = alt_path = unique_path(o, collide_path, "merged");
- } else if (would_lose_untracked(collide_path)) {
+ } else if (would_lose_untracked(o, collide_path)) {
/*
* Only way we get here is if both renames were from
* a directory rename AND user had an untracked file
@@ -1716,12 +1725,12 @@ static char *find_path_for_conflict(struct merge_options *o,
const char *branch2)
{
char *new_path = NULL;
- if (dir_in_way(path, !o->call_depth, 0)) {
+ if (dir_in_way(o->repo->index, path, !o->call_depth, 0)) {
new_path = unique_path(o, path, branch1);
output(o, 1, _("%s is a directory in %s adding "
"as %s instead"),
path, branch2, new_path);
- } else if (would_lose_untracked(path)) {
+ } else if (would_lose_untracked(o, path)) {
new_path = unique_path(o, path, branch1);
output(o, 1, _("Refusing to lose untracked file"
" at %s; adding as %s instead"),
@@ -1782,14 +1791,14 @@ static int handle_rename_rename_1to2(struct merge_options *o,
return -1;
}
else
- remove_file_from_cache(a->path);
+ remove_file_from_index(o->repo->index, a->path);
add = filespec_from_entry(&other, ci->dst_entry2, 3 ^ 1);
if (add) {
if (update_file(o, 0, &add->oid, add->mode, b->path))
return -1;
}
else
- remove_file_from_cache(b->path);
+ remove_file_from_index(o->repo->index, b->path);
} else {
/*
* For each destination path, we need to see if there is a
@@ -1886,7 +1895,7 @@ static struct diff_queue_struct *get_diffpairs(struct merge_options *o,
struct diff_queue_struct *ret;
struct diff_options opts;
- repo_diff_setup(the_repository, &opts);
+ repo_diff_setup(o->repo, &opts);
opts.flags.recursive = 1;
opts.flags.rename_empty = 0;
opts.detect_rename = merge_detect_rename(o);
@@ -3041,8 +3050,8 @@ static int blob_unchanged(struct merge_options *opt,
* performed. Comparison can be skipped if both files are
* unchanged since their sha1s have already been compared.
*/
- if (renormalize_buffer(&the_index, path, o.buf, o.len, &o) |
- renormalize_buffer(&the_index, path, a.buf, a.len, &a))
+ if (renormalize_buffer(opt->repo->index, path, o.buf, o.len, &o) |
+ renormalize_buffer(opt->repo->index, path, a.buf, a.len, &a))
ret = (o.len == a.len && !memcmp(o.buf, a.buf, o.len));
error_return:
@@ -3123,7 +3132,7 @@ static int handle_content_merge(struct merge_options *o,
a.path = (char *)path1;
b.path = (char *)path2;
- if (dir_in_way(path, !o->call_depth,
+ if (dir_in_way(o->repo->index, path, !o->call_depth,
S_ISGITLINK(pair1->two->mode)))
df_conflict_remains = 1;
}
@@ -3157,8 +3166,8 @@ static int handle_content_merge(struct merge_options *o,
pos = index_name_pos(&o->orig_index, path, strlen(path));
ce = o->orig_index.cache[pos];
if (ce_skip_worktree(ce)) {
- pos = index_name_pos(&the_index, path, strlen(path));
- ce = the_index.cache[pos];
+ pos = index_name_pos(o->repo->index, path, strlen(path));
+ ce = o->repo->index->cache[pos];
ce->ce_flags |= CE_SKIP_WORKTREE;
}
return mfi.clean;
@@ -3177,7 +3186,7 @@ static int handle_content_merge(struct merge_options *o,
if (df_conflict_remains || is_dirty) {
char *new_path;
if (o->call_depth) {
- remove_file_from_cache(path);
+ remove_file_from_index(o->repo->index, path);
} else {
if (!mfi.clean) {
if (update_stages(o, path, &one, &a, &b))
@@ -3337,7 +3346,7 @@ static int process_entry(struct merge_options *o,
oid = b_oid;
conf = _("directory/file");
}
- if (dir_in_way(path,
+ if (dir_in_way(o->repo->index, path,
!o->call_depth && !S_ISGITLINK(a_mode),
0)) {
char *new_path = unique_path(o, path, add_branch);
@@ -3348,7 +3357,7 @@ static int process_entry(struct merge_options *o,
if (update_file(o, 0, oid, mode, new_path))
clean_merge = -1;
else if (o->call_depth)
- remove_file_from_cache(path);
+ remove_file_from_index(o->repo->index, path);
free(new_path);
} else {
output(o, 2, _("Adding %s"), path);
@@ -3396,10 +3405,11 @@ int merge_trees(struct merge_options *o,
struct tree *common,
struct tree **result)
{
+ struct index_state *istate = o->repo->index;
int code, clean;
struct strbuf sb = STRBUF_INIT;
- if (!o->call_depth && index_has_changes(&the_index, head, &sb)) {
+ if (!o->call_depth && index_has_changes(istate, head, &sb)) {
err(o, _("Your local changes to the following files would be overwritten by merge:\n %s"),
sb.buf);
return -1;
@@ -3427,7 +3437,7 @@ int merge_trees(struct merge_options *o,
return -1;
}
- if (unmerged_cache()) {
+ if (unmerged_index(istate)) {
struct string_list *entries;
struct rename_info re_info;
int i;
@@ -3442,7 +3452,7 @@ int merge_trees(struct merge_options *o,
get_files_dirs(o, head);
get_files_dirs(o, merge);
- entries = get_unmerged();
+ entries = get_unmerged(o->repo->index);
clean = detect_and_process_renames(o, common, head, merge,
entries, &re_info);
record_df_conflict_files(o, entries);
@@ -3558,7 +3568,7 @@ int merge_recursive(struct merge_options *o,
* overwritten it: the committed "conflicts" were
* already resolved.
*/
- discard_cache();
+ discard_index(o->repo->index);
saved_b1 = o->branch1;
saved_b2 = o->branch2;
o->branch1 = "Temporary merge branch 1";
@@ -3574,9 +3584,9 @@ int merge_recursive(struct merge_options *o,
return err(o, _("merge returned no commit"));
}
- discard_cache();
+ discard_index(o->repo->index);
if (!o->call_depth)
- repo_read_index(the_repository);
+ repo_read_index(o->repo);
o->ancestor = "merged common ancestors";
clean = merge_trees(o, get_commit_tree(h1), get_commit_tree(h2),
@@ -3643,7 +3653,7 @@ int merge_recursive_generic(struct merge_options *o,
}
}
- repo_hold_locked_index(the_repository, &lock, LOCK_DIE_ON_ERROR);
+ repo_hold_locked_index(o->repo, &lock, LOCK_DIE_ON_ERROR);
clean = merge_recursive(o, head_commit, next_commit, ca,
result);
if (clean < 0) {
@@ -3651,7 +3661,7 @@ int merge_recursive_generic(struct merge_options *o,
return clean;
}
- if (write_locked_index(&the_index, &lock,
+ if (write_locked_index(o->repo->index, &lock,
COMMIT_LOCK | SKIP_IF_UNCHANGED))
return err(o, _("Unable to write index."));
@@ -3675,10 +3685,12 @@ static void merge_recursive_config(struct merge_options *o)
git_config(git_xmerge_config, NULL);
}
-void init_merge_options(struct merge_options *o)
+void init_merge_options(struct merge_options *o,
+ struct repository *repo)
{
const char *merge_verbosity;
memset(o, 0, sizeof(struct merge_options));
+ o->repo = repo;
o->verbosity = 2;
o->buffer_output = 1;
o->diff_rename_limit = -1;
diff --git a/merge-recursive.h b/merge-recursive.h
index e6a0828eca..c2b7bb65c6 100644
--- a/merge-recursive.h
+++ b/merge-recursive.h
@@ -6,6 +6,8 @@
struct commit;
+struct repository;
+
struct merge_options {
const char *ancestor;
const char *branch1;
@@ -34,6 +36,7 @@ struct merge_options {
struct string_list df_conflict_file_set;
struct unpack_trees_options unpack_opts;
struct index_state orig_index;
+ struct repository *repo;
};
/*
@@ -92,7 +95,8 @@ int merge_recursive_generic(struct merge_options *o,
const struct object_id **ca,
struct commit **result);
-void init_merge_options(struct merge_options *o);
+void init_merge_options(struct merge_options *o,
+ struct repository *repo);
struct tree *write_tree_from_memory(struct merge_options *o);
int parse_merge_opt(struct merge_options *out, const char *s);
diff --git a/sequencer.c b/sequencer.c
index c2c9cc7e2b..cede6ea095 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -545,7 +545,7 @@ static int do_recursive_merge(struct repository *r,
repo_read_index(r);
- init_merge_options(&o);
+ init_merge_options(&o, r);
o.ancestor = base ? base_label : "(empty tree)";
o.branch1 = "HEAD";
o.branch2 = next ? next_label : "(empty tree)";
@@ -3300,7 +3300,7 @@ static int do_merge(struct repository *r,
free_commit_list(bases);
repo_read_index(r);
- init_merge_options(&o);
+ init_merge_options(&o, r);
o.branch1 = "HEAD";
o.branch2 = ref_name.buf;
o.buffer_output = 2;
--
2.20.0.482.g66447595a7
^ permalink raw reply related
* [PATCH 08/10] merge-recursive.c: remove implicit dependency on the_repository
From: Nguyễn Thái Ngọc Duy @ 2019-01-05 5:51 UTC (permalink / raw)
To: git; +Cc: Nguyễn Thái Ngọc Duy
In-Reply-To: <20190105055153.3256-1-pclouds@gmail.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
merge-recursive.c | 45 ++++++++++++++++++++++++---------------------
1 file changed, 24 insertions(+), 21 deletions(-)
diff --git a/merge-recursive.c b/merge-recursive.c
index 28f44c73ec..a596d95739 100644
--- a/merge-recursive.c
+++ b/merge-recursive.c
@@ -146,7 +146,8 @@ static int err(struct merge_options *o, const char *err, ...)
return -1;
}
-static struct tree *shift_tree_object(struct tree *one, struct tree *two,
+static struct tree *shift_tree_object(struct repository *repo,
+ struct tree *one, struct tree *two,
const char *subtree_shift)
{
struct object_id shifted;
@@ -159,12 +160,14 @@ static struct tree *shift_tree_object(struct tree *one, struct tree *two,
}
if (oideq(&two->object.oid, &shifted))
return two;
- return lookup_tree(the_repository, &shifted);
+ return lookup_tree(repo, &shifted);
}
-static struct commit *make_virtual_commit(struct tree *tree, const char *comment)
+static struct commit *make_virtual_commit(struct repository *repo,
+ struct tree *tree,
+ const char *comment)
{
- struct commit *commit = alloc_commit_node(the_repository);
+ struct commit *commit = alloc_commit_node(repo);
set_merge_remote_desc(commit, comment, (struct object *)commit);
commit->maybe_tree = tree;
@@ -445,7 +448,7 @@ struct tree *write_tree_from_memory(struct merge_options *o)
return NULL;
}
- result = lookup_tree(the_repository, &istate->cache_tree->oid);
+ result = lookup_tree(o->repo, &istate->cache_tree->oid);
return result;
}
@@ -1208,9 +1211,9 @@ static int merge_submodule(struct merge_options *o,
return 0;
}
- if (!(commit_base = lookup_commit_reference(the_repository, base)) ||
- !(commit_a = lookup_commit_reference(the_repository, a)) ||
- !(commit_b = lookup_commit_reference(the_repository, b))) {
+ if (!(commit_base = lookup_commit_reference(o->repo, base)) ||
+ !(commit_a = lookup_commit_reference(o->repo, a)) ||
+ !(commit_b = lookup_commit_reference(o->repo, b))) {
output(o, 1, _("Failed to merge submodule %s (commits not present)"), path);
return 0;
}
@@ -3416,8 +3419,8 @@ int merge_trees(struct merge_options *o,
}
if (o->subtree_shift) {
- merge = shift_tree_object(head, merge, o->subtree_shift);
- common = shift_tree_object(head, common, o->subtree_shift);
+ merge = shift_tree_object(o->repo, head, merge, o->subtree_shift);
+ common = shift_tree_object(o->repo, head, common, o->subtree_shift);
}
if (oid_eq(&common->object.oid, &merge->object.oid)) {
@@ -3553,8 +3556,8 @@ int merge_recursive(struct merge_options *o,
/* if there is no common ancestor, use an empty tree */
struct tree *tree;
- tree = lookup_tree(the_repository, the_repository->hash_algo->empty_tree);
- merged_common_ancestors = make_virtual_commit(tree, "ancestor");
+ tree = lookup_tree(o->repo, o->repo->hash_algo->empty_tree);
+ merged_common_ancestors = make_virtual_commit(o->repo, tree, "ancestor");
}
for (iter = ca; iter; iter = iter->next) {
@@ -3598,7 +3601,7 @@ int merge_recursive(struct merge_options *o,
}
if (o->call_depth) {
- *result = make_virtual_commit(mrtree, "merged tree");
+ *result = make_virtual_commit(o->repo, mrtree, "merged tree");
commit_list_insert(h1, &(*result)->parents);
commit_list_insert(h2, &(*result)->parents->next);
}
@@ -3611,17 +3614,17 @@ int merge_recursive(struct merge_options *o,
return clean;
}
-static struct commit *get_ref(const struct object_id *oid, const char *name)
+static struct commit *get_ref(struct repository *repo, const struct object_id *oid,
+ const char *name)
{
struct object *object;
- object = deref_tag(the_repository, parse_object(the_repository, oid),
- name,
- strlen(name));
+ object = deref_tag(repo, parse_object(repo, oid),
+ name, strlen(name));
if (!object)
return NULL;
if (object->type == OBJ_TREE)
- return make_virtual_commit((struct tree*)object, name);
+ return make_virtual_commit(repo, (struct tree*)object, name);
if (object->type != OBJ_COMMIT)
return NULL;
if (parse_commit((struct commit *)object))
@@ -3638,15 +3641,15 @@ int merge_recursive_generic(struct merge_options *o,
{
int clean;
struct lock_file lock = LOCK_INIT;
- struct commit *head_commit = get_ref(head, o->branch1);
- struct commit *next_commit = get_ref(merge, o->branch2);
+ struct commit *head_commit = get_ref(o->repo, head, o->branch1);
+ struct commit *next_commit = get_ref(o->repo, merge, o->branch2);
struct commit_list *ca = NULL;
if (base_list) {
int i;
for (i = 0; i < num_base_list; ++i) {
struct commit *base;
- if (!(base = get_ref(base_list[i], oid_to_hex(base_list[i]))))
+ if (!(base = get_ref(o->repo, base_list[i], oid_to_hex(base_list[i]))))
return err(o, _("Could not parse object '%s'"),
oid_to_hex(base_list[i]));
commit_list_insert(base, &ca);
--
2.20.0.482.g66447595a7
^ permalink raw reply related
* [PATCH 09/10] read-cache.c: remove the_* from index_has_changes()
From: Nguyễn Thái Ngọc Duy @ 2019-01-05 5:51 UTC (permalink / raw)
To: git; +Cc: Nguyễn Thái Ngọc Duy
In-Reply-To: <20190105055153.3256-1-pclouds@gmail.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
builtin/am.c | 6 +++---
cache.h | 6 +++---
merge-recursive.c | 2 +-
read-cache.c | 12 +++++-------
4 files changed, 12 insertions(+), 14 deletions(-)
diff --git a/builtin/am.c b/builtin/am.c
index 611712dc95..a9ffc92eaa 100644
--- a/builtin/am.c
+++ b/builtin/am.c
@@ -1719,7 +1719,7 @@ static void am_run(struct am_state *state, int resume)
refresh_and_write_cache();
- if (index_has_changes(&the_index, NULL, &sb)) {
+ if (repo_index_has_changes(the_repository, NULL, &sb)) {
write_state_bool(state, "dirtyindex", 1);
die(_("Dirty index: cannot apply patches (dirty: %s)"), sb.buf);
}
@@ -1777,7 +1777,7 @@ static void am_run(struct am_state *state, int resume)
* the result may have produced the same tree as ours.
*/
if (!apply_status &&
- !index_has_changes(&the_index, NULL, NULL)) {
+ !repo_index_has_changes(the_repository, NULL, NULL)) {
say(state, stdout, _("No changes -- Patch already applied."));
goto next;
}
@@ -1831,7 +1831,7 @@ static void am_resolve(struct am_state *state)
say(state, stdout, _("Applying: %.*s"), linelen(state->msg), state->msg);
- if (!index_has_changes(&the_index, NULL, NULL)) {
+ if (!repo_index_has_changes(the_repository, NULL, NULL)) {
printf_ln(_("No changes - did you forget to use 'git add'?\n"
"If there is nothing left to stage, chances are that something else\n"
"already introduced the same changes; you might want to skip this patch."));
diff --git a/cache.h b/cache.h
index fdcd69bfb0..326e73f391 100644
--- a/cache.h
+++ b/cache.h
@@ -706,9 +706,9 @@ extern int unmerged_index(const struct index_state *);
* provided, the space-separated list of files that differ will be appended
* to it.
*/
-extern int index_has_changes(struct index_state *istate,
- struct tree *tree,
- struct strbuf *sb);
+extern int repo_index_has_changes(struct repository *repo,
+ struct tree *tree,
+ struct strbuf *sb);
extern int verify_path(const char *path, unsigned mode);
extern int strcmp_offset(const char *s1, const char *s2, size_t *first_change);
diff --git a/merge-recursive.c b/merge-recursive.c
index a596d95739..df00896b25 100644
--- a/merge-recursive.c
+++ b/merge-recursive.c
@@ -3412,7 +3412,7 @@ int merge_trees(struct merge_options *o,
int code, clean;
struct strbuf sb = STRBUF_INIT;
- if (!o->call_depth && index_has_changes(istate, head, &sb)) {
+ if (!o->call_depth && repo_index_has_changes(o->repo, head, &sb)) {
err(o, _("Your local changes to the following files would be overwritten by merge:\n %s"),
sb.buf);
return -1;
diff --git a/read-cache.c b/read-cache.c
index 61cc0571da..2549477ed2 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -2365,22 +2365,20 @@ int unmerged_index(const struct index_state *istate)
return 0;
}
-int index_has_changes(struct index_state *istate,
- struct tree *tree,
- struct strbuf *sb)
+int repo_index_has_changes(struct repository *repo,
+ struct tree *tree,
+ struct strbuf *sb)
{
+ struct index_state *istate = repo->index;
struct object_id cmp;
int i;
- if (istate != &the_index) {
- BUG("index_has_changes cannot yet accept istate != &the_index; do_diff_cache needs updating first.");
- }
if (tree)
cmp = tree->object.oid;
if (tree || !get_oid_tree("HEAD", &cmp)) {
struct diff_options opt;
- repo_diff_setup(the_repository, &opt);
+ repo_diff_setup(repo, &opt);
opt.flags.exit_with_status = 1;
if (!sb)
opt.flags.quick = 1;
--
2.20.0.482.g66447595a7
^ permalink raw reply related
* [PATCH 10/10] cache.h: flip NO_THE_INDEX_COMPATIBILITY_MACROS switch
From: Nguyễn Thái Ngọc Duy @ 2019-01-05 5:51 UTC (permalink / raw)
To: git; +Cc: Nguyễn Thái Ngọc Duy
In-Reply-To: <20190105055153.3256-1-pclouds@gmail.com>
From now on, by default index compat macros are off because they could
hide the_index dependency. Only those in builtin can use it (and even
so should be avoided if possible).
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
attr.c | 1 -
builtin/add.c | 1 +
builtin/am.c | 1 +
builtin/blame.c | 3 ++-
builtin/cat-file.c | 1 +
builtin/check-attr.c | 1 +
builtin/check-ignore.c | 1 +
builtin/checkout-index.c | 1 +
builtin/checkout.c | 1 +
builtin/clean.c | 1 +
builtin/commit.c | 1 +
builtin/describe.c | 1 +
builtin/diff-files.c | 1 +
builtin/diff-index.c | 1 +
builtin/diff-tree.c | 1 +
builtin/diff.c | 1 +
builtin/difftool.c | 1 +
builtin/fsck.c | 1 +
builtin/grep.c | 1 +
builtin/hash-object.c | 3 ++-
builtin/log.c | 1 +
builtin/ls-files.c | 1 -
builtin/merge-index.c | 1 +
builtin/merge-ours.c | 1 +
builtin/merge-tree.c | 4 +++-
builtin/merge.c | 1 +
builtin/mv.c | 1 +
builtin/pack-objects.c | 2 +-
builtin/pull.c | 1 +
builtin/read-tree.c | 1 +
builtin/rebase--interactive.c | 1 +
builtin/rebase.c | 1 +
builtin/replace.c | 2 +-
builtin/reset.c | 1 +
builtin/rev-parse.c | 1 +
builtin/rm.c | 1 +
builtin/submodule--helper.c | 1 +
builtin/update-index.c | 1 +
builtin/write-tree.c | 1 +
cache-tree.h | 2 +-
cache.h | 6 +++---
convert.c | 1 -
dir.c | 1 -
git.c | 4 ++--
name-hash.c | 1 -
pathspec.c | 1 -
read-cache.c | 2 --
repository.c | 1 +
submodule.c | 1 -
t/helper/test-dump-fsmonitor.c | 4 ++--
t/helper/test-dump-untracked-cache.c | 1 +
t/helper/test-tool.h | 1 +
tree.c | 1 -
unpack-trees.c | 1 -
54 files changed, 52 insertions(+), 24 deletions(-)
diff --git a/attr.c b/attr.c
index b63fe0fc0e..e4e4574857 100644
--- a/attr.c
+++ b/attr.c
@@ -7,7 +7,6 @@
* an insanely large number of attributes.
*/
-#define NO_THE_INDEX_COMPATIBILITY_MACROS
#include "cache.h"
#include "config.h"
#include "exec-cmd.h"
diff --git a/builtin/add.c b/builtin/add.c
index f65c172299..81df0d34de 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -3,6 +3,7 @@
*
* Copyright (C) 2006 Linus Torvalds
*/
+#define USE_THE_INDEX_COMPATIBILITY_MACROS
#include "cache.h"
#include "config.h"
#include "builtin.h"
diff --git a/builtin/am.c b/builtin/am.c
index a9ffc92eaa..ad913ef20e 100644
--- a/builtin/am.c
+++ b/builtin/am.c
@@ -3,6 +3,7 @@
*
* Based on git-am.sh by Junio C Hamano.
*/
+#define USE_THE_INDEX_COMPATIBILITY_MACROS
#include "cache.h"
#include "config.h"
#include "builtin.h"
diff --git a/builtin/blame.c b/builtin/blame.c
index 6d798f9939..0074ed311c 100644
--- a/builtin/blame.c
+++ b/builtin/blame.c
@@ -1007,7 +1007,8 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
long bottom, top;
if (parse_range_arg(range_list.items[range_i].string,
nth_line_cb, &sb, lno, anchor,
- &bottom, &top, sb.path, &the_index))
+ &bottom, &top, sb.path,
+ the_repository->index))
usage(blame_usage);
if ((!lno && (top || bottom)) || lno < bottom)
die(Q_("file %s has only %lu line",
diff --git a/builtin/cat-file.c b/builtin/cat-file.c
index 7622c502f0..a5ca47c697 100644
--- a/builtin/cat-file.c
+++ b/builtin/cat-file.c
@@ -3,6 +3,7 @@
*
* Copyright (C) Linus Torvalds, 2005
*/
+#define USE_THE_INDEX_COMPATIBILITY_MACROS
#include "cache.h"
#include "config.h"
#include "builtin.h"
diff --git a/builtin/check-attr.c b/builtin/check-attr.c
index 30a2f84274..dd83397786 100644
--- a/builtin/check-attr.c
+++ b/builtin/check-attr.c
@@ -1,3 +1,4 @@
+#define USE_THE_INDEX_COMPATIBILITY_MACROS
#include "builtin.h"
#include "cache.h"
#include "config.h"
diff --git a/builtin/check-ignore.c b/builtin/check-ignore.c
index ec9a959e08..599097304b 100644
--- a/builtin/check-ignore.c
+++ b/builtin/check-ignore.c
@@ -1,3 +1,4 @@
+#define USE_THE_INDEX_COMPATIBILITY_MACROS
#include "builtin.h"
#include "cache.h"
#include "config.h"
diff --git a/builtin/checkout-index.c b/builtin/checkout-index.c
index eb74774cbc..345591bc4b 100644
--- a/builtin/checkout-index.c
+++ b/builtin/checkout-index.c
@@ -4,6 +4,7 @@
* Copyright (C) 2005 Linus Torvalds
*
*/
+#define USE_THE_INDEX_COMPATIBILITY_MACROS
#include "builtin.h"
#include "config.h"
#include "lockfile.h"
diff --git a/builtin/checkout.c b/builtin/checkout.c
index a95ba2c6dc..0446cac05e 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -1,3 +1,4 @@
+#define USE_THE_INDEX_COMPATIBILITY_MACROS
#include "builtin.h"
#include "config.h"
#include "checkout.h"
diff --git a/builtin/clean.c b/builtin/clean.c
index bbcdeb2d9e..aaba4af3c2 100644
--- a/builtin/clean.c
+++ b/builtin/clean.c
@@ -6,6 +6,7 @@
* Based on git-clean.sh by Pavel Roskin
*/
+#define USE_THE_INDEX_COMPATIBILITY_MACROS
#include "builtin.h"
#include "cache.h"
#include "config.h"
diff --git a/builtin/commit.c b/builtin/commit.c
index d3f1234bf0..2f4af02a27 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -5,6 +5,7 @@
* Based on git-commit.sh by Junio C Hamano and Linus Torvalds
*/
+#define USE_THE_INDEX_COMPATIBILITY_MACROS
#include "cache.h"
#include "config.h"
#include "lockfile.h"
diff --git a/builtin/describe.c b/builtin/describe.c
index bc97e50650..02ec56417a 100644
--- a/builtin/describe.c
+++ b/builtin/describe.c
@@ -1,3 +1,4 @@
+#define USE_THE_INDEX_COMPATIBILITY_MACROS
#include "cache.h"
#include "config.h"
#include "lockfile.h"
diff --git a/builtin/diff-files.c b/builtin/diff-files.c
index 48cfcb935d..86ae474fbf 100644
--- a/builtin/diff-files.c
+++ b/builtin/diff-files.c
@@ -3,6 +3,7 @@
*
* Copyright (C) Linus Torvalds, 2005
*/
+#define USE_THE_INDEX_COMPATIBILITY_MACROS
#include "cache.h"
#include "config.h"
#include "diff.h"
diff --git a/builtin/diff-index.c b/builtin/diff-index.c
index fcccd1f10d..93ec642423 100644
--- a/builtin/diff-index.c
+++ b/builtin/diff-index.c
@@ -1,3 +1,4 @@
+#define USE_THE_INDEX_COMPATIBILITY_MACROS
#include "cache.h"
#include "config.h"
#include "diff.h"
diff --git a/builtin/diff-tree.c b/builtin/diff-tree.c
index 42bc1eb41d..a90681bcba 100644
--- a/builtin/diff-tree.c
+++ b/builtin/diff-tree.c
@@ -1,3 +1,4 @@
+#define USE_THE_INDEX_COMPATIBILITY_MACROS
#include "cache.h"
#include "config.h"
#include "diff.h"
diff --git a/builtin/diff.c b/builtin/diff.c
index ec78920ee2..74351a5757 100644
--- a/builtin/diff.c
+++ b/builtin/diff.c
@@ -3,6 +3,7 @@
*
* Copyright (c) 2006 Junio C Hamano
*/
+#define USE_THE_INDEX_COMPATIBILITY_MACROS
#include "cache.h"
#include "config.h"
#include "lockfile.h"
diff --git a/builtin/difftool.c b/builtin/difftool.c
index 544b0e8639..eeb9e370b9 100644
--- a/builtin/difftool.c
+++ b/builtin/difftool.c
@@ -11,6 +11,7 @@
*
* Copyright (C) 2016 Johannes Schindelin
*/
+#define USE_THE_INDEX_COMPATIBILITY_MACROS
#include "cache.h"
#include "config.h"
#include "builtin.h"
diff --git a/builtin/fsck.c b/builtin/fsck.c
index bf5ddff43f..46f6ea9baa 100644
--- a/builtin/fsck.c
+++ b/builtin/fsck.c
@@ -1,3 +1,4 @@
+#define USE_THE_INDEX_COMPATIBILITY_MACROS
#include "builtin.h"
#include "cache.h"
#include "repository.h"
diff --git a/builtin/grep.c b/builtin/grep.c
index 3d695ad8fe..308b89536e 100644
--- a/builtin/grep.c
+++ b/builtin/grep.c
@@ -3,6 +3,7 @@
*
* Copyright (c) 2006 Junio C Hamano
*/
+#define USE_THE_INDEX_COMPATIBILITY_MACROS
#include "cache.h"
#include "repository.h"
#include "config.h"
diff --git a/builtin/hash-object.c b/builtin/hash-object.c
index d6f06ea32f..e055c11103 100644
--- a/builtin/hash-object.c
+++ b/builtin/hash-object.c
@@ -40,7 +40,8 @@ static void hash_fd(int fd, const char *type, const char *path, unsigned flags,
if (fstat(fd, &st) < 0 ||
(literally
? hash_literally(&oid, fd, type, flags)
- : index_fd(&the_index, &oid, fd, &st, type_from_string(type), path, flags)))
+ : index_fd(the_repository->index, &oid, fd, &st,
+ type_from_string(type), path, flags)))
die((flags & HASH_WRITE_OBJECT)
? "Unable to add %s to database"
: "Unable to hash %s", path);
diff --git a/builtin/log.c b/builtin/log.c
index dbfb4e31ad..195ff0b471 100644
--- a/builtin/log.c
+++ b/builtin/log.c
@@ -4,6 +4,7 @@
* (C) Copyright 2006 Linus Torvalds
* 2006 Junio Hamano
*/
+#define USE_THE_INDEX_COMPATIBILITY_MACROS
#include "cache.h"
#include "config.h"
#include "refs.h"
diff --git a/builtin/ls-files.c b/builtin/ls-files.c
index c70a9c7158..7cc7ec22c9 100644
--- a/builtin/ls-files.c
+++ b/builtin/ls-files.c
@@ -5,7 +5,6 @@
*
* Copyright (C) Linus Torvalds, 2005
*/
-#define NO_THE_INDEX_COMPATIBILITY_MACROS
#include "cache.h"
#include "repository.h"
#include "config.h"
diff --git a/builtin/merge-index.c b/builtin/merge-index.c
index c99443b095..38ea6ad6ca 100644
--- a/builtin/merge-index.c
+++ b/builtin/merge-index.c
@@ -1,3 +1,4 @@
+#define USE_THE_INDEX_COMPATIBILITY_MACROS
#include "builtin.h"
#include "run-command.h"
diff --git a/builtin/merge-ours.c b/builtin/merge-ours.c
index 0b07263415..4594507420 100644
--- a/builtin/merge-ours.c
+++ b/builtin/merge-ours.c
@@ -7,6 +7,7 @@
*
* Pretend we resolved the heads, but declare our tree trumps everybody else.
*/
+#define USE_THE_INDEX_COMPATIBILITY_MACROS
#include "git-compat-util.h"
#include "builtin.h"
#include "diff.h"
diff --git a/builtin/merge-tree.c b/builtin/merge-tree.c
index 70f6fc9167..53719e0b9d 100644
--- a/builtin/merge-tree.c
+++ b/builtin/merge-tree.c
@@ -1,3 +1,4 @@
+#define USE_THE_INDEX_COMPATIBILITY_MACROS
#include "builtin.h"
#include "tree-walk.h"
#include "xdiff-interface.h"
@@ -76,7 +77,8 @@ static void *result(struct merge_list *entry, unsigned long *size)
their = NULL;
if (entry)
their = entry->blob;
- return merge_blobs(&the_index, path, base, our, their, size);
+ return merge_blobs(the_repository->index, path,
+ base, our, their, size);
}
static void *origin(struct merge_list *entry, unsigned long *size)
diff --git a/builtin/merge.c b/builtin/merge.c
index bc1aecfe70..e47d77baee 100644
--- a/builtin/merge.c
+++ b/builtin/merge.c
@@ -6,6 +6,7 @@
* Based on git-merge.sh by Junio C Hamano.
*/
+#define USE_THE_INDEX_COMPATIBILITY_MACROS
#include "cache.h"
#include "config.h"
#include "parse-options.h"
diff --git a/builtin/mv.c b/builtin/mv.c
index 80bb967a63..be15ba7044 100644
--- a/builtin/mv.c
+++ b/builtin/mv.c
@@ -3,6 +3,7 @@
*
* Copyright (C) 2006 Johannes Schindelin
*/
+#define USE_THE_INDEX_COMPATIBILITY_MACROS
#include "builtin.h"
#include "config.h"
#include "pathspec.h"
diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index 24bba8147f..d9d3b90b23 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -970,7 +970,7 @@ static int no_try_delta(const char *path)
if (!check)
check = attr_check_initl("delta", NULL);
- git_check_attr(&the_index, path, check);
+ git_check_attr(the_repository->index, path, check);
if (ATTR_FALSE(check->items[0].value))
return 1;
return 0;
diff --git a/builtin/pull.c b/builtin/pull.c
index 74808b9455..701d1473dc 100644
--- a/builtin/pull.c
+++ b/builtin/pull.c
@@ -5,6 +5,7 @@
*
* Fetch one or more remote refs and merge it/them into the current HEAD.
*/
+#define USE_THE_INDEX_COMPATIBILITY_MACROS
#include "cache.h"
#include "config.h"
#include "builtin.h"
diff --git a/builtin/read-tree.c b/builtin/read-tree.c
index ac255ad2c2..9083dcfa28 100644
--- a/builtin/read-tree.c
+++ b/builtin/read-tree.c
@@ -4,6 +4,7 @@
* Copyright (C) Linus Torvalds, 2005
*/
+#define USE_THE_INDEX_COMPATIBILITY_MACROS
#include "cache.h"
#include "config.h"
#include "lockfile.h"
diff --git a/builtin/rebase--interactive.c b/builtin/rebase--interactive.c
index dd2a55ab1d..6895322d61 100644
--- a/builtin/rebase--interactive.c
+++ b/builtin/rebase--interactive.c
@@ -1,3 +1,4 @@
+#define USE_THE_INDEX_COMPATIBILITY_MACROS
#include "builtin.h"
#include "cache.h"
#include "config.h"
diff --git a/builtin/rebase.c b/builtin/rebase.c
index 7124e66d00..b667837276 100644
--- a/builtin/rebase.c
+++ b/builtin/rebase.c
@@ -4,6 +4,7 @@
* Copyright (c) 2018 Pratik Karki
*/
+#define USE_THE_INDEX_COMPATIBILITY_MACROS
#include "builtin.h"
#include "run-command.h"
#include "exec-cmd.h"
diff --git a/builtin/replace.c b/builtin/replace.c
index affcdfb416..5b80b7f211 100644
--- a/builtin/replace.c
+++ b/builtin/replace.c
@@ -295,7 +295,7 @@ static int import_object(struct object_id *oid, enum object_type type,
close(fd);
return -1;
}
- if (index_fd(&the_index, oid, fd, &st, type, NULL, flags) < 0)
+ if (index_fd(the_repository->index, oid, fd, &st, type, NULL, flags) < 0)
return error(_("unable to write object to database"));
/* index_fd close()s fd for us */
}
diff --git a/builtin/reset.c b/builtin/reset.c
index 59898c972e..4d18a461fa 100644
--- a/builtin/reset.c
+++ b/builtin/reset.c
@@ -7,6 +7,7 @@
*
* Copyright (c) 2005, 2006 Linus Torvalds and Junio C Hamano
*/
+#define USE_THE_INDEX_COMPATIBILITY_MACROS
#include "builtin.h"
#include "config.h"
#include "lockfile.h"
diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c
index 910a71ed8b..f8bbe6d47e 100644
--- a/builtin/rev-parse.c
+++ b/builtin/rev-parse.c
@@ -3,6 +3,7 @@
*
* Copyright (C) Linus Torvalds, 2005
*/
+#define USE_THE_INDEX_COMPATIBILITY_MACROS
#include "cache.h"
#include "config.h"
#include "commit.h"
diff --git a/builtin/rm.c b/builtin/rm.c
index 17086d3d97..db85b33982 100644
--- a/builtin/rm.c
+++ b/builtin/rm.c
@@ -3,6 +3,7 @@
*
* Copyright (C) Linus Torvalds 2006
*/
+#define USE_THE_INDEX_COMPATIBILITY_MACROS
#include "builtin.h"
#include "config.h"
#include "lockfile.h"
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index b45514be31..9c832fc606 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -1,3 +1,4 @@
+#define USE_THE_INDEX_COMPATIBILITY_MACROS
#include "builtin.h"
#include "repository.h"
#include "cache.h"
diff --git a/builtin/update-index.c b/builtin/update-index.c
index e19da77edc..02ace602b9 100644
--- a/builtin/update-index.c
+++ b/builtin/update-index.c
@@ -3,6 +3,7 @@
*
* Copyright (C) Linus Torvalds, 2005
*/
+#define USE_THE_INDEX_COMPATIBILITY_MACROS
#include "cache.h"
#include "config.h"
#include "lockfile.h"
diff --git a/builtin/write-tree.c b/builtin/write-tree.c
index cdcbf8264e..3d46d22ee5 100644
--- a/builtin/write-tree.c
+++ b/builtin/write-tree.c
@@ -3,6 +3,7 @@
*
* Copyright (C) Linus Torvalds, 2005
*/
+#define USE_THE_INDEX_COMPATIBILITY_MACROS
#include "builtin.h"
#include "cache.h"
#include "config.h"
diff --git a/cache-tree.h b/cache-tree.h
index 326209198b..757bbc48bc 100644
--- a/cache-tree.h
+++ b/cache-tree.h
@@ -51,7 +51,7 @@ void prime_cache_tree(struct repository *, struct index_state *, struct tree *);
int cache_tree_matches_traversal(struct cache_tree *, struct name_entry *ent, struct traverse_info *info);
-#ifndef NO_THE_INDEX_COMPATIBILITY_MACROS
+#ifdef USE_THE_INDEX_COMPATIBILITY_MACROS
static inline int write_cache_as_tree(struct object_id *oid, int flags, const char *prefix)
{
return write_index_as_tree(oid, &the_index, get_index_file(), flags, prefix);
diff --git a/cache.h b/cache.h
index 326e73f391..962eb127d3 100644
--- a/cache.h
+++ b/cache.h
@@ -338,8 +338,6 @@ struct index_state {
struct mem_pool *ce_mem_pool;
};
-extern struct index_state the_index;
-
/* Name hashing */
extern int test_lazy_init_name_hash(struct index_state *istate, int try_threaded);
extern void add_name_hash(struct index_state *istate, struct cache_entry *ce);
@@ -401,7 +399,9 @@ struct cache_entry *dup_cache_entry(const struct cache_entry *ce, struct index_s
*/
void validate_cache_entries(const struct index_state *istate);
-#ifndef NO_THE_INDEX_COMPATIBILITY_MACROS
+#ifdef USE_THE_INDEX_COMPATIBILITY_MACROS
+extern struct index_state the_index;
+
#define active_cache (the_index.cache)
#define active_nr (the_index.cache_nr)
#define active_alloc (the_index.cache_alloc)
diff --git a/convert.c b/convert.c
index e0848226d2..df8c6a0bf8 100644
--- a/convert.c
+++ b/convert.c
@@ -1,4 +1,3 @@
-#define NO_THE_INDEX_COMPATIBILITY_MACROS
#include "cache.h"
#include "config.h"
#include "object-store.h"
diff --git a/dir.c b/dir.c
index ab6477d777..80e07441f7 100644
--- a/dir.c
+++ b/dir.c
@@ -7,7 +7,6 @@
* Copyright (C) Linus Torvalds, 2005-2006
* Junio Hamano, 2005-2006
*/
-#define NO_THE_INDEX_COMPATIBILITY_MACROS
#include "cache.h"
#include "config.h"
#include "dir.h"
diff --git a/git.c b/git.c
index 4d53a3d50d..0c2b269797 100644
--- a/git.c
+++ b/git.c
@@ -417,9 +417,9 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv)
trace_argv_printf(argv, "trace: built-in: git");
- validate_cache_entries(&the_index);
+ validate_cache_entries(the_repository->index);
status = p->fn(argc, argv, prefix);
- validate_cache_entries(&the_index);
+ validate_cache_entries(the_repository->index);
if (status)
return status;
diff --git a/name-hash.c b/name-hash.c
index 623ca6923a..b4861bc7b0 100644
--- a/name-hash.c
+++ b/name-hash.c
@@ -5,7 +5,6 @@
*
* Copyright (C) 2008 Linus Torvalds
*/
-#define NO_THE_INDEX_COMPATIBILITY_MACROS
#include "cache.h"
#include "thread-utils.h"
diff --git a/pathspec.c b/pathspec.c
index 6f005996fd..f1505cfd0a 100644
--- a/pathspec.c
+++ b/pathspec.c
@@ -1,4 +1,3 @@
-#define NO_THE_INDEX_COMPATIBILITY_MACROS
#include "cache.h"
#include "config.h"
#include "dir.h"
diff --git a/read-cache.c b/read-cache.c
index 2549477ed2..b3865d6884 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -3,7 +3,6 @@
*
* Copyright (C) Linus Torvalds, 2005
*/
-#define NO_THE_INDEX_COMPATIBILITY_MACROS
#include "cache.h"
#include "config.h"
#include "diff.h"
@@ -95,7 +94,6 @@ static struct mem_pool *find_mem_pool(struct index_state *istate)
return *pool_ptr;
}
-struct index_state the_index;
static const char *alternate_index_output;
static void set_index_entry(struct index_state *istate, int nr, struct cache_entry *ce)
diff --git a/repository.c b/repository.c
index fd965c127c..81dc4f0a23 100644
--- a/repository.c
+++ b/repository.c
@@ -9,6 +9,7 @@
/* The main repository */
static struct repository the_repo;
struct repository *the_repository;
+struct index_state the_index;
void initialize_the_repository(void)
{
diff --git a/submodule.c b/submodule.c
index 6415cc5580..4208a50260 100644
--- a/submodule.c
+++ b/submodule.c
@@ -1,4 +1,3 @@
-#define NO_THE_INDEX_COMPATIBILITY_MACROS
#include "cache.h"
#include "repository.h"
diff --git a/t/helper/test-dump-fsmonitor.c b/t/helper/test-dump-fsmonitor.c
index 08e3684aff..2786f47088 100644
--- a/t/helper/test-dump-fsmonitor.c
+++ b/t/helper/test-dump-fsmonitor.c
@@ -3,11 +3,11 @@
int cmd__dump_fsmonitor(int ac, const char **av)
{
- struct index_state *istate = &the_index;
+ struct index_state *istate = the_repository->index;
int i;
setup_git_directory();
- if (do_read_index(istate, get_index_file(), 0) < 0)
+ if (do_read_index(istate, the_repository->index_file, 0) < 0)
die("unable to read index file");
if (!istate->fsmonitor_last_update) {
printf("no fsmonitor\n");
diff --git a/t/helper/test-dump-untracked-cache.c b/t/helper/test-dump-untracked-cache.c
index 52870ebbb3..cf0f2c7228 100644
--- a/t/helper/test-dump-untracked-cache.c
+++ b/t/helper/test-dump-untracked-cache.c
@@ -1,3 +1,4 @@
+#define USE_THE_INDEX_COMPATIBILITY_MACROS
#include "test-tool.h"
#include "cache.h"
#include "dir.h"
diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h
index 042f12464b..f4fb3b9861 100644
--- a/t/helper/test-tool.h
+++ b/t/helper/test-tool.h
@@ -1,6 +1,7 @@
#ifndef TEST_TOOL_H
#define TEST_TOOL_H
+#define USE_THE_INDEX_COMPATIBILITY_MACROS
#include "git-compat-util.h"
int cmd__chmtime(int argc, const char **argv);
diff --git a/tree.c b/tree.c
index 215d3fdc7c..181a3778f3 100644
--- a/tree.c
+++ b/tree.c
@@ -1,4 +1,3 @@
-#define NO_THE_INDEX_COMPATIBILITY_MACROS
#include "cache.h"
#include "cache-tree.h"
#include "tree.h"
diff --git a/unpack-trees.c b/unpack-trees.c
index 6d53cbfc86..40f554814d 100644
--- a/unpack-trees.c
+++ b/unpack-trees.c
@@ -1,4 +1,3 @@
-#define NO_THE_INDEX_COMPATIBILITY_MACROS
#include "cache.h"
#include "argv-array.h"
#include "repository.h"
--
2.20.0.482.g66447595a7
^ permalink raw reply related
* Re: [PATCH 1/1] Add optional targets for documentation l10n
From: Jean-Noël AVILA @ 2019-01-05 8:35 UTC (permalink / raw)
To: git
In-Reply-To: <xmqqk1jkb0c9.fsf@gitster-ct.c.googlers.com>
On Friday, 4 January 2019 22:05:10 CET Junio C Hamano wrote:
> Jean-Noël Avila <jn.avila@free.fr> writes:
>
> > From: Jean-Noel Avila <jn.avila@free.fr>
> >
> > The standard doc lists can be filtered to allow using the compilation
> > rules with translated manpages where all the pages of the original
> > version may not be present.
> >
> > The install variable are reused in the secondary repo so that the
> > configured paths can be used for translated manpages too.
> >
> > Signed-off-by: Jean-Noël Avila <jn.avila@free.fr>
> > ---
> > Documentation/Makefile | 25 +++++++++++++++++++------
> > 1 file changed, 19 insertions(+), 6 deletions(-)
> >
> > diff --git a/Documentation/Makefile b/Documentation/Makefile
> > index b5be2e2d3f..1f61a1fe86 100644
> > --- a/Documentation/Makefile
> > +++ b/Documentation/Makefile
> > @@ -35,13 +35,18 @@ MAN7_TXT += gittutorial-2.txt
> > MAN7_TXT += gittutorial.txt
> > MAN7_TXT += gitworkflows.txt
> >
> > -MAN_TXT = $(MAN1_TXT) $(MAN5_TXT) $(MAN7_TXT)
> > +TMP_MAN_TXT = $(MAN1_TXT) $(MAN5_TXT) $(MAN7_TXT)
> > +MAN_FILTER ?= $(TMP_MAN_TXT)
> > +MAN_TXT = $(filter $(TMP_MAN_TXT), $(MAN_FILTER))
> > +undefine TMP_MAN_TXT
> > +
>
> I think your arguments to $(filter) is the other way around, but
> other than that, I think I get what you are trying to do. Let me
> make sure I got it right.
>
> The idea is to use $(filter PATTERN..., TEXT) that removes words in
> TEXT that do not match any of the words in PATTERN, and for normal
> build, MAN_FILTER is set identical to TMP_MAN_TXT (which is the
> original MAN_TXT), so there is no filtering happen, but in a build
> that does tweak MAN_FILTER, MAN_TXT can become a subset of the
> original MAN_TXT.
>
> Am I on the right track?
>
Yes that's exactly the purpose of this trick. In fact, $(filter) in this
configuration is equivalent to an intersection of lists, so the order does not
change the end result.
> > MAN_XML = $(patsubst %.txt,%.xml,$(MAN_TXT))
> > MAN_HTML = $(patsubst %.txt,%.html,$(MAN_TXT))
>
> And these act on already-filtered MAN_TXT
>
Yes the filtered list fans out to the outputs.
> > OBSOLETE_HTML += everyday.html
> > OBSOLETE_HTML += git-remote-helpers.html
> > -DOC_HTML = $(MAN_HTML) $(OBSOLETE_HTML)
> > +
> > +TMP_DOC_HTML = $(MAN_HTML) $(OBSOLETE_HTML)
> >
> > ARTICLES += howto-index
> > ARTICLES += git-tools
> > @@ -81,11 +86,14 @@ TECH_DOCS += technical/trivial-merge
> > SP_ARTICLES += $(TECH_DOCS)
> > SP_ARTICLES += technical/api-index
> >
> > -DOC_HTML += $(patsubst %,%.html,$(ARTICLES) $(SP_ARTICLES))
> > +TMP_DOC_HTML += $(patsubst %,%.html,$(ARTICLES) $(SP_ARTICLES))
> > +HTML_FILTER ?= $(TMP_DOC_HTML)
> > +DOC_HTML = $(filter $(HTML_FILTER),$(TMP_DOC_HTML))
> > +undefine TMP_DOC_HTML
>
> This one uses $(filter) in the right direction.
>
> So is it expected that HTML help pages that correspond to manpages
> are strict subset of manpages?
>
> I see HTML_FILTER may be useful to filter HTML pages that come from
> $(ARTICLES), but I'd expect that all $(MAN_HTML) that came from the
> already-filtered $(MAN_TXT) would not require any further filtering.
> With the approach shown, the secondary project ends up needing to
> list all the translated MAN_TXT twice (once for MAN_FILTER, and
> again for HTML_FILTER), doesn't it?
The issue I had here is that DOC_HTML is a superset of of MAN_HTML (which
needed to be translated anyway for MAN_XML) and I have no way to remove from
the difference of them the files that are not already translated. So a second
filter is needed, even if now, MAN_FILTER==HTML_FILTER.
As the translations expand hopefully, we will add the html documentation.
>
> I am wondering if it makes more sense to have HTML_FILTER filter _only_
> parts of the DOC_HTML that does not come from MAN_TXT (i.e. those
> $(ARTICLES) pages).
>
It can be done. That would separate manpage filter from doc filter. The
secondary project can be simplified.
> > -DOC_MAN1 = $(patsubst %.txt,%.1,$(MAN1_TXT))
> > -DOC_MAN5 = $(patsubst %.txt,%.5,$(MAN5_TXT))
> > -DOC_MAN7 = $(patsubst %.txt,%.7,$(MAN7_TXT))
> > +DOC_MAN1 = $(patsubst %.txt,%.1,$(filter $(MAN_FILTER), $(MAN1_TXT)))
> > +DOC_MAN5 = $(patsubst %.txt,%.5,$(filter $(MAN_FILTER), $(MAN5_TXT)))
> > +DOC_MAN7 = $(patsubst %.txt,%.7,$(filter $(MAN_FILTER), $(MAN7_TXT)))
>
> These are OK, too.
>
> By the way, lose the SP after ',' in $(filter). As we can see in
> the context lines in the patch, args to $(make-functions) are
> separated with comma without surrounding SP by convention.
>
> What kind of PATTERN does the secondary project supply when invoking
> this Makefile? If it is list of filenames, I am wondering if it is
> simpler to have it override MAN{1,5,7}_TXT variables, without adding
> these "TMP_* + fliter + undef TMP_*" dance.
Ah, I see. The filter from MAN{1,5,7}_TXT would ripple the same way as MAN_TXT,
just one level upstream. The filtering at this level would no longer be
needed.
Unfortunately, the TMP_* dance would also be needed because these variables
are built in several steps by append operations, and once filtered, the
original variables are still useless. My Makefile-fu is low, so I may be
missing something about redefining variables.
More generally, is this setup sustainable?
^ permalink raw reply
* [PATCH v2] Add optional targets for documentation l10n
From: Jean-Noël Avila @ 2019-01-05 13:44 UTC (permalink / raw)
To: git; +Cc: Jean-Noel Avila
In-Reply-To: <20190104165406.22358-1-jn.avila@free.fr>
From: Jean-Noel Avila <jn.avila@free.fr>
The standard doc lists can be filtered to allow using the compilation
rules with translated manpages where all the pages of the original
version may not be present.
The install variable are reused in the secondary repo so that the
configured paths can be used for translated manpages too.
Signed-off-by: Jean-Noël Avila <jn.avila@free.fr>
---
The TMP_* dance was removed. The MAN{1,5,7} filtering was preserved, to keep the dispatching policy of manpages in a single place.
Documentation/Makefile | 22 +++++++++++++++++-----
1 file changed, 17 insertions(+), 5 deletions(-)
diff --git a/Documentation/Makefile b/Documentation/Makefile
index b5be2e2d3f..c8450d6425 100644
--- a/Documentation/Makefile
+++ b/Documentation/Makefile
@@ -35,13 +35,18 @@ MAN7_TXT += gittutorial-2.txt
MAN7_TXT += gittutorial.txt
MAN7_TXT += gitworkflows.txt
+ifdef MAN_FILTER
+MAN_TXT = $(filter $(MAN_FILTER),$(MAN1_TXT) $(MAN5_TXT) $(MAN7_TXT))
+else
MAN_TXT = $(MAN1_TXT) $(MAN5_TXT) $(MAN7_TXT)
+MAN_FILTER = $(MAN_TXT)
+endif
+
MAN_XML = $(patsubst %.txt,%.xml,$(MAN_TXT))
MAN_HTML = $(patsubst %.txt,%.html,$(MAN_TXT))
OBSOLETE_HTML += everyday.html
OBSOLETE_HTML += git-remote-helpers.html
-DOC_HTML = $(MAN_HTML) $(OBSOLETE_HTML)
ARTICLES += howto-index
ARTICLES += git-tools
@@ -81,11 +86,13 @@ TECH_DOCS += technical/trivial-merge
SP_ARTICLES += $(TECH_DOCS)
SP_ARTICLES += technical/api-index
-DOC_HTML += $(patsubst %,%.html,$(ARTICLES) $(SP_ARTICLES))
+SP_ARTICLES_HTML += $(patsubst %,%.html,$(ARTICLES) $(SP_ARTICLES))
+HTML_FILTER ?= $(SP_ARTICLES_HTML) $(OBSOLETE_HTML)
+DOC_HTML = $(MAN_HTML) $(filter $(HTML_FILTER),$(SP_ARTICLES_HTML) $(OBSOLETE_HTML))
-DOC_MAN1 = $(patsubst %.txt,%.1,$(MAN1_TXT))
-DOC_MAN5 = $(patsubst %.txt,%.5,$(MAN5_TXT))
-DOC_MAN7 = $(patsubst %.txt,%.7,$(MAN7_TXT))
+DOC_MAN1 = $(patsubst %.txt,%.1,$(filter $(MAN_FILTER), $(MAN1_TXT)))
+DOC_MAN5 = $(patsubst %.txt,%.5,$(filter $(MAN_FILTER), $(MAN5_TXT)))
+DOC_MAN7 = $(patsubst %.txt,%.7,$(filter $(MAN_FILTER), $(MAN7_TXT)))
prefix ?= $(HOME)
bindir ?= $(prefix)/bin
@@ -444,4 +451,9 @@ print-man1:
lint-docs::
$(QUIET_LINT)$(PERL_PATH) lint-gitlink.perl
+ifeq ($(wildcard po/Makefile),po/Makefile)
+doc-l10n install-l10n::
+ $(MAKE) -C po $@
+endif
+
.PHONY: FORCE
--
2.20.1
^ permalink raw reply related
* Re: [PATCH 02/10] repository.c: replace hold_locked_index() with repo_hold_locked_index()
From: Martin Ågren @ 2019-01-05 14:33 UTC (permalink / raw)
To: Nguyễn Thái Ngọc Duy; +Cc: Git Mailing List
In-Reply-To: <20190105055153.3256-3-pclouds@gmail.com>
On Sat, 5 Jan 2019 at 07:07, Nguyễn Thái Ngọc Duy <pclouds@gmail.com> wrote:
>
> hold_locked_index() assumes the index path at $GIT_DIR/index. This is
> not good for places that take an arbitrary index_state instead of
> the_index, which is basically everywhere except builtin/.
>
> Replace it with repo_hold_locked_index(). hold_locked_index() remains
> as a wrapper around repo_hold_locked_index() to reduce changes in builtin/
> diff --git a/builtin/clone.c b/builtin/clone.c
> index 7c7f98c72c..ddb3230d21 100644
> --- a/builtin/clone.c
> +++ b/builtin/clone.c
> @@ -8,6 +8,7 @@
> * Clone a repository into a different directory that does not yet exist.
> */
>
> +#define USE_THE_INDEX_COMPATIBILITY_MACROS
I think this should be in patch 10/10.
> diff --git a/cache.h b/cache.h
> index ca36b44ee0..634c9ce325 100644
> --- a/cache.h
> +++ b/cache.h
> @@ -433,6 +433,7 @@ void validate_cache_entries(const struct index_state *istate);
> #define unmerge_cache_entry_at(at) unmerge_index_entry_at(&the_index, at)
> #define unmerge_cache(pathspec) unmerge_index(&the_index, pathspec)
> #define read_blob_data_from_cache(path, sz) read_blob_data_from_index(&the_index, (path), (sz))
> +#define hold_locked_index(lock_file, flags) repo_hold_locked_index(the_repository, (lock_file), (flags))
> #endif
>
> #define TYPE_BITS 3
> @@ -833,7 +834,6 @@ extern struct cache_entry *refresh_cache_entry(struct index_state *, struct cach
> */
> extern void update_index_if_able(struct index_state *, struct lock_file *);
>
> -extern int hold_locked_index(struct lock_file *, int);
The reason this moves is it gets protected with "#ifndef
NO_THE_INDEX_COMPATIBILITY_MACROS". Ok.
> -int hold_locked_index(struct lock_file *lk, int lock_flags)
> -{
> - return hold_lock_file_for_update(lk, get_index_file(), lock_flags);
> -}
> +int repo_hold_locked_index(struct repository *repo,
> + struct lock_file *lf,
> + int flags)
> +{
> + return hold_lock_file_for_update(lf, repo->index_file, flags);
> +}
`get_index_file()` BUGs if `the_repository->index_file` is NULL, but
other than that, this looks like a faithful conversion. Do we want to
keep that check here?
Martin
^ permalink raw reply
* A few questions regarding git annotated tags
From: Michal Novotny @ 2019-01-05 15:50 UTC (permalink / raw)
To: git
Hello,
I am making an rpm packaging application called rpkg-util
(https://pagure.io/rpkg-util) that can render parts of rpm metadata
from git metadata, e.g. software version. It uses annotated tags to
store most of the data that are then rendered to an rpm spec file
(e.g. the version or changelog).
Now I would like to make sure that I am not omitting some better
approach than the one that I am currently using and for that I would
like to ask the following questions.
I could potentially make it so that I tag subtrees instead of commits
and then derive the needed information from these subtree tags. This
could be useful if I have multiple rpm packages in different subtrees
of the same repo. I could then tag the subtree where the rpm package
is placed.
This could bring some simplification into the code but as far as I
know, you cannot easily checkout a tree tag, which is something a
packager should be able to do easily: to checkout a state of repo when
a certain subpackage was tagged. This is the first question. Can you
e.g. do:
git tag somename HEAD:
and then do something similar to
git checkout somename
which would restore the repository or at least the respective subtree
of it into the state when "somename" tag was created?
Right now, I am putting a package name directly into tag name so I
know what tags belong to what package based on that. And I am using
normal annotated tags. This works quite well, I would say, but at one
point I need to use shared state to move the discovered package name
from one part of the code to another so that the other part can work
with the correct subset of the available annotated tags. I wouldn't
need to do that if I could derive the correct tag subset based just on
the path to the subtree where a package is placed. The path can be
simply an input parameter of all my functions and they could all fetch
the correct tag subset based just on that information. Those functions
are independent of each other, they all derive some information from
the tags but each one is specialized to fetch a different piece of
information. This would be nice. Right now some of my functions accept
name when they need to fetch the associated tag set and work with it
and some accept path if they don't require the tag set.
Alternative approach to creating the tree tags would be to store the
path information into annotated tag message, which I could do. But is
there a relatively simple way to filter tags based on their message
content? Can I put the information into some other part of tag than
name or the message so that it can be easily filtered?
It would be also good if the association of the tags to the subtrees
was made obvious (it will no longer be obvious when it won't depend on
name of the tag) but that's a different problem that I could
potentially solve if I can make the tag<->subtree relation work in
some way. I am pretty happy with the current name-based solution but I
don't want to miss something obvious or less obvious.
Thank you
Michal Novotny
^ permalink raw reply
* Re: [PATCH v3] Simplify handling of setup_git_directory_gently() failure cases.
From: Erin Dahlgren @ 2019-01-05 16:57 UTC (permalink / raw)
To: Jeff King; +Cc: Junio C Hamano, git, Johannes Schindelin
In-Reply-To: <20190104082558.GB26014@sigill.intra.peff.net>
On Fri, Jan 4, 2019 at 12:26 AM Jeff King <peff@peff.net> wrote:
>
> On Thu, Jan 03, 2019 at 10:09:18AM -0800, Junio C Hamano wrote:
>
> > >> @@ -1132,7 +1142,10 @@ const char *setup_git_directory_gently(int *nongit_ok)
> > >> * the user has set GIT_DIR. It may be beneficial to disallow bogus
> > >> * GIT_DIR values at some point in the future.
> > >> */
> > >> - if (startup_info->have_repository || getenv(GIT_DIR_ENVIRONMENT)) {
> > >> + if (// GIT_DIR_EXPLICIT, GIT_DIR_DISCOVERED, GIT_DIR_BARE
> > >> + startup_info->have_repository ||
> > >> + // GIT_DIR_EXPLICIT
> > >> + getenv(GIT_DIR_ENVIRONMENT)) {
> > >
> > > Same "//" style issue as above. I'm not sure how much value there is in
> > > repeating the GIT_DIR_* cases here, as they're likely to grow out of
> > > sync with the switch() statement above.
> >
> > It is unclear to me if the original code is doing the right thing
> > under one condition, and this patch does not seem to change the
> > behaviour.
> >
> > What happens if GIT_DIR environment is set to an invalid path and
> > nongit_ok is non-NULL? setup_explicit_git_dir() would have assigned
> > 1 to *nongit_ok, so have_repository is false at this point.
> >
> > We enter the if() statement in such a case, and end up calling
> > setup_git_env(gitdir) using the bogus path that is not pointing at a
> > repository. We leave have_repository to be false but the paths
> > recorded in the_repository by setup_git_env() would all point at
> > bogus places.
>
> Yeah, that matches my analysis of what the code is doing.
>
> Looks like this code (and comment) come from 73f192c991 (setup: don't
> perform lazy initialization of repository state, 2017-06-20). I'm
> guessing this was mostly a hack to quiet some test that complained about
> the other changes in that commit. And indeed, dropping the getenv() half
> of the conditional and running the tests in 73f192c991 gets me a failure
> in t1050, which does:
>
> GIT_DIR=non-existent git index-pack --strict --verify foo/.git/objects/pack/*.pack
>
> But that's a bug in index-pack, which should be able to verify a pack
> outside of a repository. And I think (according to bisection) we fixed
> that in 14a9bd2898 (prepare_commit_graft: treat non-repository as a
> noop, 2018-05-31), and the tests currently pass even with this patch
> applied:
>
> diff --git a/setup.c b/setup.c
> index 1be5037f12..e2c03e9bbc 100644
> --- a/setup.c
> +++ b/setup.c
> @@ -1132,7 +1132,7 @@ const char *setup_git_directory_gently(int *nongit_ok)
> * the user has set GIT_DIR. It may be beneficial to disallow bogus
> * GIT_DIR values at some point in the future.
> */
> - if (startup_info->have_repository || getenv(GIT_DIR_ENVIRONMENT)) {
> + if (startup_info->have_repository) {
> if (!the_repository->gitdir) {
> const char *gitdir = getenv(GIT_DIR_ENVIRONMENT);
> if (!gitdir)
>
> > > At first I thought this could all be folded into the "else" clause of
> > > the conditional above (which would make the logic much easier to
> > > follow), but that wouldn't cover the case of GIT_DIR=/bogus, which is
> > > what that getenv() is trying to handle here.
> >
> > Yes, but should GIT_DIR=/bogus even be touching the_repository?
>
> Probably not. And from my poking around above, I think we're probably
> safe to remove this hackery now.
>
> > It is a separate clean-up and does not affect the validity of this
> > simplification patchd, so I agreee with ...
> >
> > > So I think this is the best we can do for now.
>
> Yep, it's definitely orthogonal. But if we do this cleanup as part of
> it, we should be able to simplify further on top of Erin's patch, like
> this:
>
> diff --git a/setup.c b/setup.c
> index eb8332bc02..edf65c44bf 100644
> --- a/setup.c
> +++ b/setup.c
> @@ -1125,35 +1125,26 @@ const char *setup_git_directory_gently(int *nongit_ok)
> // !nongit_ok || !*nongit_ok
> startup_info->have_repository = 1;
> startup_info->prefix = prefix;
> +
> if (prefix)
> setenv(GIT_PREFIX_ENVIRONMENT, prefix, 1);
> else
> setenv(GIT_PREFIX_ENVIRONMENT, "", 1);
> - }
>
> - /*
> - * Not all paths through the setup code will call 'set_git_dir()' (which
> - * directly sets up the environment) so in order to guarantee that the
> - * environment is in a consistent state after setup, explicitly setup
> - * the environment if we have a repository.
> - *
> - * NEEDSWORK: currently we allow bogus GIT_DIR values to be set in some
> - * code paths so we also need to explicitly setup the environment if
> - * the user has set GIT_DIR. It may be beneficial to disallow bogus
> - * GIT_DIR values at some point in the future.
> - */
> - if (// GIT_DIR_EXPLICIT, GIT_DIR_DISCOVERED, GIT_DIR_BARE
> - startup_info->have_repository ||
> - // GIT_DIR_EXPLICIT
> - getenv(GIT_DIR_ENVIRONMENT)) {
> + /*
> + * Not all paths through the setup code will call 'set_git_dir()' (which
> + * directly sets up the environment) so in order to guarantee that the
> + * environment is in a consistent state after setup, explicitly setup
> + * the environment if we have a repository.
> + */
> if (!the_repository->gitdir) {
> const char *gitdir = getenv(GIT_DIR_ENVIRONMENT);
> if (!gitdir)
> gitdir = DEFAULT_GIT_DIR_ENVIRONMENT;
> setup_git_env(gitdir);
> }
> - if (startup_info->have_repository)
> - repo_set_hash_algo(the_repository, repo_fmt.hash_algo);
> +
> + repo_set_hash_algo(the_repository, repo_fmt.hash_algo);
> }
>
> strbuf_release(&dir);
>
> I actually wonder if the "not all paths..." bit is even still true these
> days (and if it is, I think we should consider fixing those code paths).
> Certainly that setup_git_env() needed to trigger for the GIT_DIR=bogus,
> but with that gone, any $GIT_DIR should have triggered GIT_DIR_EXPLICIT,
> and any "default to .git" should be handled as part of discovery, I'd
> think.
>
> So what next? Erin, are you interested in using the details of this
> conversation to take the cleanups a bit further?
Sure, no problem. If this is urgent, then I would probably be more
inclined to keep this small and do more cleanup in followup patches.
But if it's not urgent (that is my understanding), I'd be happy to
take the cleanups further. I'm traveling today through next week but
I'll try to post another version addressing the comments in the next
couple of days.
Thanks all for the comments so far.
- Erin
> If not, then I can try to prepare a few patches on top of yours.
>
> -Peff
^ permalink raw reply
* Re: [PATCH] diff: add support for reading files literally with --no-index
From: brian m. carlson @ 2019-01-05 17:39 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Jonathan Nieder, git, Jeff King, Duy Nguyen
In-Reply-To: <xmqq36q8cjgf.fsf@gitster-ct.c.googlers.com>
[-- Attachment #1: Type: text/plain, Size: 1540 bytes --]
On Fri, Jan 04, 2019 at 11:26:56AM -0800, Junio C Hamano wrote:
> "brian m. carlson" <sandals@crustytoothpaste.net> writes:
>
> >> - --dereference to control whether to follow symlinks
> >
> > This is actually surprisingly difficult. The reason I implemented this
> > only for no-index mode is because there are actually several places we
> > can stat a file in the diff code, and implementing a --dereference
> > option that catches all of those cases and getting the option passed
> > down to them is non-trivial.
>
> Another thing to worry about is symlinks that point outside the
> working tree. When a tracked content "dir/link" is a symlink to
> "/etc/motd", it probably makes sense to open("/etc/motd") and read()
> it on the working tree side of the diff, and probably even on the
> index side of the diff, but what about obtaining contents for
> "dir/link" in a year-old commit under --deference mode? I am not
> sure if it makes sense to read from the filesystem in such a case.
>
> I personally am perfectly fine if this "do not compare readlink(2),
> but read contents literally" is limited to the --no-index mode.
That's a good point. I think I'll stick with the current design, then,
since that seems like the least surprising way forward. It also means
that we don't read outside of the working tree unless --no-index is in
use, which may be beneficial for security purposes.
Thanks for a helpful perspective.
--
brian m. carlson: Houston, Texas, US
OpenPGP: https://keybase.io/bk2204
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 868 bytes --]
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox