* [PATCH v3 2/2] Make rebase--interactive use OPTIONS_SPEC
From: Stephan Beyer @ 2008-06-21 23:55 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, Johannes Schindelin, Christian Couder, Stephan Beyer
In-Reply-To: <1214092551-8075-1-git-send-email-s-beyer@gmx.net>
Also add some checks that --continue/--abort/--skip
actions are used without --onto, -p, -t, etc.
Signed-off-by: Stephan Beyer <s-beyer@gmx.net>
---
Hi,
I resent this patch, too, because I've changed something:
To make the OPTIONS_SPEC more consistent with other OPTIONS_SPECs,
I lowe-cased the first letters of the help string for each option.
Regards,
Stephan
git-rebase--interactive.sh | 71 +++++++++++++++++++++++++++++--------------
1 files changed, 48 insertions(+), 23 deletions(-)
diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index 3f926d8..f13768c 100755
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -10,10 +10,27 @@
# The original idea comes from Eric W. Biederman, in
# http://article.gmane.org/gmane.comp.version-control.git/22407
-USAGE='(--continue | --abort | --skip | [--preserve-merges] [--first-parent]
- [--preserve-tags] [--verbose] [--onto <branch>] <upstream> [<branch>])'
+OPTIONS_KEEPDASHDASH=
+OPTIONS_SPEC="\
+git-rebase [-i] [options] [--] <upstream> [<branch>]
+git-rebase [-i] (--continue | --abort | --skip)
+--
+ Available options are
+p,preserve-merges try to recreate merges instead of ignoring them
+t,preserve-tags update tags to the new commit object
+m,merge always used (no-op)
+i,interactive always used (no-op)
+onto= rebase onto given branch instead of upstream
+v,verbose display a diffstat of what changed upstream
+ When preserving merges
+f,first-parent show only commits following the first parent of each commit
+s,strategy= use the given merge strategy
+ Actions:
+continue continue rebasing process
+abort abort rebasing process and restore original branch
+skip skip current patch and continue rebasing process
+"
-OPTIONS_SPEC=
. git-sh-setup
require_work_tree
@@ -25,6 +42,8 @@ SQUASH_MSG="$DOTEST"/message-squash
PRESERVE_MERGES=
STRATEGY=
VERBOSE=
+ONTO=
+MARK_PREFIX='refs/rebase-marks'
test -f "$DOTEST"/strategy && STRATEGY="$(cat "$DOTEST"/strategy)"
test -f "$DOTEST"/verbose && VERBOSE=t
@@ -515,10 +534,19 @@ create_extended_todo_list () {
done
}
+is_standalone () {
+ test $# -eq 2 -a "$2" = '--' &&
+ test -z "$ONTO" &&
+ test -z "$PRESERVE_TAGS" &&
+ test -z "$PRESERVE_MERGES" &&
+ test -z "$FIRST_PARENT"
+}
+
while test $# != 0
do
case "$1" in
--continue)
+ is_standalone "$@" || usage
comment_for_reflog continue
test -d "$DOTEST" || die "No interactive rebase running"
@@ -551,6 +579,7 @@ do
do_rest
;;
--abort)
+ is_standalone "$@" || usage
comment_for_reflog abort
git rerere clear
@@ -568,6 +597,7 @@ do
exit
;;
--skip)
+ is_standalone "$@" || usage
comment_for_reflog skip
git rerere clear
@@ -575,7 +605,7 @@ do
output git reset --hard && do_rest
;;
- -s|--strategy)
+ -s)
case "$#,$1" in
*,*=*)
STRATEGY="-s "$(expr "z$1" : 'z-[^=]*=\(.*\)') ;;
@@ -586,32 +616,36 @@ do
shift ;;
esac
;;
- -m|--merge)
+ -m)
# we use merge anyway
;;
- -C*)
- die "Interactive rebase uses merge, so $1 does not make sense"
- ;;
- -v|--verbose)
+ -v)
VERBOSE=t
;;
- -p|--preserve-merges)
+ -p)
PRESERVE_MERGES=t
;;
- -f|--first-parent)
+ -f)
FIRST_PARENT=t
PRESERVE_MERGES=t
;;
- -t|--preserve-tags)
+ -t)
PRESERVE_TAGS=t
;;
- -i|--interactive)
+ -i)
# yeah, we know
;;
+ --onto)
+ shift
+ ONTO=$(git rev-parse --verify "$1") ||
+ die "Does not point to a valid commit: $1"
+ ;;
''|-h)
usage
;;
- *)
+ --)
+ shift
+ test $# -eq 1 -o $# -eq 2 || usage
test -d "$DOTEST" &&
die "Interactive rebase already started"
@@ -620,15 +654,6 @@ do
comment_for_reflog start
- ONTO=
- case "$1" in
- --onto)
- ONTO=$(git rev-parse --verify "$2") ||
- die "Does not point to a valid commit: $2"
- shift; shift
- ;;
- esac
-
require_clean_work_tree
UPSTREAM=$(git rev-parse --verify "$1") || die "Invalid base"
--
1.5.6.310.g344d
^ permalink raw reply related
* [PATCH 2/2] Extend parse-options test suite
From: Stephan Beyer @ 2008-06-22 0:00 UTC (permalink / raw)
To: git; +Cc: Pierre Habouzit, Junio C Hamano, Johannes Schindelin,
Stephan Beyer
In-Reply-To: <1214092802-8175-1-git-send-email-s-beyer@gmx.net>
This patch serves two purposes:
1. test-parse-option.c should be a more complete
example for the parse-options API, and
2. there have been no tests for OPT_CALLBACK,
OPT_DATE, OPT_BIT, OPT_SET_INT and OPT_SET_PTR
before.
Signed-off-by: Stephan Beyer <s-beyer@gmx.net>
---
On reviewing you should perhaps first have a look at the .c file,
then the changes of t0040 make more sense.
t/t0040-parse-options.sh | 116 +++++++++++++++++++++++++++++++++++++++++++---
test-parse-options.c | 39 ++++++++++++++--
2 files changed, 144 insertions(+), 11 deletions(-)
diff --git a/t/t0040-parse-options.sh b/t/t0040-parse-options.sh
index 9965cfa..87c6164 100755
--- a/t/t0040-parse-options.sh
+++ b/t/t0040-parse-options.sh
@@ -11,23 +11,35 @@ cat > expect.err << EOF
usage: test-parse-options <options>
-b, --boolean get a boolean
+ -4, --or4 bitwise-or boolean with ...0100
+
-i, --integer <n> get a integer
-j <n> get a integer, too
+ --set23 set integer to 23
+ -t <time> get timestamp of <time>
+ -L, --length <str> get length of <str>
-string options
+String options
-s, --string <string>
get a string
--string2 <str> get another string
--st <st> get another string (pervert ordering)
-o <str> get another string
+ --default-string set string to default
-magic arguments
+Magic arguments
--quux means --quux
+Standard options
+ --abbrev [<n>] use <n> digits to display SHA-1s
+ -v, --verbose be verbose
+ -n, --dry-run dry run
+ -q, --quiet be quiet
+
EOF
test_expect_success 'test help' '
- ! test-parse-options -h > output 2> output.err &&
+ test_must_fail test-parse-options -h > output 2> output.err &&
test ! -s output &&
test_cmp expect.err output.err
'
@@ -36,21 +48,31 @@ cat > expect << EOF
boolean: 2
integer: 1729
string: 123
+abbrev: 7
+verbose: 2
+quiet: no
+dry run: yes
EOF
test_expect_success 'short options' '
- test-parse-options -s123 -b -i 1729 -b > output 2> output.err &&
+ test-parse-options -s123 -b -i 1729 -b -vv -n > output 2> output.err &&
test_cmp expect output &&
test ! -s output.err
'
+
cat > expect << EOF
boolean: 2
integer: 1729
string: 321
+abbrev: 10
+verbose: 2
+quiet: no
+dry run: no
EOF
test_expect_success 'long options' '
test-parse-options --boolean --integer 1729 --boolean --string2=321 \
+ --verbose --verbose --no-dry-run --abbrev=10 \
> output 2> output.err &&
test ! -s output.err &&
test_cmp expect output
@@ -60,6 +82,10 @@ cat > expect << EOF
boolean: 1
integer: 13
string: 123
+abbrev: 7
+verbose: 0
+quiet: no
+dry run: no
arg 00: a1
arg 01: b1
arg 02: --boolean
@@ -76,6 +102,10 @@ cat > expect << EOF
boolean: 0
integer: 2
string: (not set)
+abbrev: 7
+verbose: 0
+quiet: no
+dry run: no
EOF
test_expect_success 'unambiguously abbreviated option' '
@@ -99,6 +129,10 @@ cat > expect << EOF
boolean: 0
integer: 0
string: 123
+abbrev: 7
+verbose: 0
+quiet: no
+dry run: no
EOF
test_expect_success 'non ambiguous option (after two options it abbreviates)' '
@@ -107,20 +141,24 @@ test_expect_success 'non ambiguous option (after two options it abbreviates)' '
test_cmp expect output
'
-cat > expect.err << EOF
+cat > typo.err << EOF
error: did you mean \`--boolean\` (with two dashes ?)
EOF
test_expect_success 'detect possible typos' '
- ! test-parse-options -boolean > output 2> output.err &&
+ test_must_fail test-parse-options -boolean > output 2> output.err &&
test ! -s output &&
- test_cmp expect.err output.err
+ test_cmp typo.err output.err
'
cat > expect <<EOF
boolean: 0
integer: 0
string: (not set)
+abbrev: 7
+verbose: 0
+quiet: no
+dry run: no
arg 00: --quux
EOF
@@ -130,4 +168,68 @@ test_expect_success 'keep some options as arguments' '
test_cmp expect output
'
+cat > expect <<EOF
+boolean: 0
+integer: 1
+string: default
+abbrev: 7
+verbose: 0
+quiet: yes
+dry run: no
+arg 00: foo
+EOF
+
+test_expect_success 'OPT_DATE() and OPT_SET_PTR() work' '
+ test-parse-options -t "1970-01-01 00:00:01 +0000" --default-string \
+ foo -q > output 2> output.err &&
+ test ! -s output.err &&
+ test_cmp expect output
+'
+
+cat > expect <<EOF
+Callback: "four", 0
+boolean: 5
+integer: 4
+string: (not set)
+abbrev: 7
+verbose: 0
+quiet: no
+dry run: no
+EOF
+
+test_expect_success 'OPT_CALLBACK() and OPT_BIT() work' '
+ test-parse-options --length=four -b -4 > output 2> output.err &&
+ test ! -s output.err &&
+ test_cmp expect output
+'
+
+cat > expect <<EOF
+Callback: "not set", 1
+EOF
+
+test_expect_success 'OPT_CALLBACK() and callback errors work' '
+ test_must_fail test-parse-options --no-length > output 2> output.err &&
+ test_cmp expect output &&
+ test_cmp expect.err output.err
+'
+
+cat > expect <<EOF
+boolean: 1
+integer: 23
+string: (not set)
+abbrev: 7
+verbose: 0
+quiet: no
+dry run: no
+EOF
+
+test_expect_success 'OPT_BIT() and OPT_SET_INT() work' '
+ test-parse-options --set23 -bbbbb --no-or4 > output 2> output.err &&
+ test ! -s output.err &&
+ test_cmp expect output
+'
+
+# --or4
+# --no-or4
+
test_done
diff --git a/test-parse-options.c b/test-parse-options.c
index 73360d7..2a79e72 100644
--- a/test-parse-options.c
+++ b/test-parse-options.c
@@ -2,9 +2,22 @@
#include "parse-options.h"
static int boolean = 0;
-static int integer = 0;
+static unsigned long integer = 0;
+static int abbrev = 7;
+static int verbose = 0, dry_run = 0, quiet = 0;
static char *string = NULL;
+int length_callback(const struct option *opt, const char *arg, int unset)
+{
+ printf("Callback: \"%s\", %d\n",
+ (arg ? arg : "not set"), unset);
+ if (unset)
+ return 1; /* do not support unset */
+
+ *(unsigned long *)opt->value = strlen(arg);
+ return 0;
+}
+
int main(int argc, const char **argv)
{
const char *usage[] = {
@@ -13,15 +26,29 @@ int main(int argc, const char **argv)
};
struct option options[] = {
OPT_BOOLEAN('b', "boolean", &boolean, "get a boolean"),
+ OPT_BIT('4', "or4", &boolean,
+ "bitwise-or boolean with ...0100", 4),
+ OPT_GROUP(""),
OPT_INTEGER('i', "integer", &integer, "get a integer"),
OPT_INTEGER('j', NULL, &integer, "get a integer, too"),
- OPT_GROUP("string options"),
+ OPT_SET_INT(0, "set23", &integer, "set integer to 23", 23),
+ OPT_DATE('t', NULL, &integer, "get timestamp of <time>"),
+ OPT_CALLBACK('L', "length", &integer, "str",
+ "get length of <str>", length_callback),
+ OPT_GROUP("String options"),
OPT_STRING('s', "string", &string, "string", "get a string"),
OPT_STRING(0, "string2", &string, "str", "get another string"),
OPT_STRING(0, "st", &string, "st", "get another string (pervert ordering)"),
OPT_STRING('o', NULL, &string, "str", "get another string"),
- OPT_GROUP("magic arguments"),
+ OPT_SET_PTR(0, "default-string", &string,
+ "set string to default", (unsigned long)"default"),
+ OPT_GROUP("Magic arguments"),
OPT_ARGUMENT("quux", "means --quux"),
+ OPT_GROUP("Standard options"),
+ OPT__ABBREV(&abbrev),
+ OPT__VERBOSE(&verbose),
+ OPT__DRY_RUN(&dry_run),
+ OPT__QUIET(&quiet),
OPT_END(),
};
int i;
@@ -29,8 +56,12 @@ int main(int argc, const char **argv)
argc = parse_options(argc, argv, options, usage, 0);
printf("boolean: %d\n", boolean);
- printf("integer: %d\n", integer);
+ printf("integer: %lu\n", integer);
printf("string: %s\n", string ? string : "(not set)");
+ printf("abbrev: %d\n", abbrev);
+ printf("verbose: %d\n", verbose);
+ printf("quiet: %s\n", quiet ? "yes" : "no");
+ printf("dry run: %s\n", dry_run ? "yes" : "no");
for (i = 0; i < argc; i++)
printf("arg %02d: %s\n", i, argv[i]);
--
1.5.6.310.g344d
^ permalink raw reply related
* [PATCH 1/2] api-parse-options.txt: Introduce documentation for parse options API
From: Stephan Beyer @ 2008-06-22 0:00 UTC (permalink / raw)
To: git; +Cc: Pierre Habouzit, Junio C Hamano, Johannes Schindelin,
Stephan Beyer
Add some documentation of basics, macros and callback
implementation of the parse-options API.
Signed-off-by: Stephan Beyer <s-beyer@gmx.net>
---
Documentation/technical/api-parse-options.txt | 206 ++++++++++++++++++++++++-
1 files changed, 204 insertions(+), 2 deletions(-)
diff --git a/Documentation/technical/api-parse-options.txt b/Documentation/technical/api-parse-options.txt
index b7cda94..a916db4 100644
--- a/Documentation/technical/api-parse-options.txt
+++ b/Documentation/technical/api-parse-options.txt
@@ -1,6 +1,208 @@
parse-options API
=================
-Talk about <parse-options.h>
+The parse-options API is used to parse and massage options in git
+and to provide a usage help with consistent look.
-(Pierre)
+Basics
+------
+
+The argument vector `argv[]` may usually contain mandatory or optional
+'non-option arguments', e.g. a filename or a branch, and 'options'.
+Options are optional arguments that start with a dash and
+that allow to change the behavior of a command.
+
+* There are basically three types of options:
+ 'boolean' options,
+ options with (mandatory) 'arguments' and
+ options with 'optional arguments'
+ (i.e. a boolean option that can be adjusted).
+
+* There are basically two forms of options:
+ 'Short options' consist of one dash (`-`) and one alphanumeric
+ character.
+ 'Long options' begin with two dashes (`\--`) and some
+ alphanumeric characters.
+
+* Options are case-sensitive.
+ Please define 'lower-case long options' only.
+
+The parse-options API allows:
+
+* 'sticked' and 'separate form' of options with arguments.
+ `-oArg` is sticked, `-o Arg` is separate form.
+ `\--option=Arg` is sticked, `\--option Arg` is separate form.
+
+* Long options may be 'abbreviated', as long as the abbreviation
+ is unambiguous.
+
+* Short options may be bundled, e.g. `-a -b` can be specified as `-ab`.
+
+* Boolean long options can be 'negated' (or 'unset') by prepending
+ `no-`, e.g. `\--no-abbrev` instead of `\--abbrev`.
+
+* Options and other arguments can clearly be separated using the `\--`
+ option, e.g. `-a -b \--option \-- \--this-is-a-file` indicates that
+ `\--this-is-a-file` must not be processed as an option.
+
+Steps to parse options
+----------------------
+
+. `#include "parse-options.h"`
+
+. define a NULL-terminated
+ `static const char * const builtin_foo_usage[]` array
+ containing alternative usage strings
+
+. define `builtin_foo_options` array as described below
+ in section 'Data Structure'.
+
+. in `cmd_foo(int argc, const char **argv, const char *prefix)`
+ call
+
+ argc = parse_options(argc, argv, builtin_foo_options, builtin_foo_usage, flags);
++
+`parse_options()` will filter out the processed options of `argv[]` and leave the
+non-option arguments in `argv[]`.
+`argc` is updated appropriately because of the assignment.
++
+Flags are the bitwise-or of:
+
+`PARSE_OPT_KEEP_DASHDASH`::
+ Usually long options (`\--long-opt`) are boiled down to their
+ short option equivalent, if available.
+ Using this flag, long options are kept.
+
+`PARSE_OPT_STOP_AT_NON_OPTION`::
+ Usually all options the whole argument vector is massaged
+ and reordered.
+ Using this flag, processing is stopped at the first non-option
+ argument.
+
+Data Structure
+--------------
+
+The main data structure is an array of the `option` struct,
+say `static struct option builtin_add_options[]`.
+There are some macros to easily define options:
+
+`OPT__ABBREV(&int_var)`::
+ Add `\--abbrev [<n>]`.
+
+`OPT__DRY_RUN(&int_var)`::
+ Add `-n, \--dry-run`.
+
+`OPT__QUIET(&int_var)`::
+ Add `-q, \--quiet`.
+
+`OPT__VERBOSE(&int_var)`::
+ Add `-v, \--verbose`.
+
+`OPT_GROUP(description)`::
+ Start an option group. `description` is a short string that
+ describes the group or an empty string.
+ Start the description with an upper-case letter.
+
+`OPT_BOOLEAN(short, long, &int_var, description)`::
+ Introduce a boolean option.
+ `int_var` is incremented on each use.
+
+`OPT_BIT(short, long, &int_var, description, mask)`::
+ Introduce a boolean option.
+ If used, `int_var` is bitwise-ored with `mask`.
+
+`OPT_SET_INT(short, long, &int_var, description, integer)`::
+ Introduce a boolean option.
+ If used, set `int_var` to `integer`.
+
+`OPT_SET_PTR(short, long, &ptr_var, description, ptr)`::
+ Introduce a boolean option.
+ If used, set `ptr_var` to `ptr`.
+
+`OPT_STRING(short, long, &str_var, arg_str, description)`::
+ Introduce an option with string argument.
+ The string argument is put into `str_var`.
+
+`OPT_INTEGER(short, long, &int_var, description)`::
+ Introduce an option with integer argument.
+ The integer is put into `int_var`.
+
+`OPT_DATE(short, long, &int_var, description)`::
+ Introduce an option with date argument, see `approxidate()`.
+ The timestamp is put into `int_var`.
+
+`OPT_CALLBACK(short, long, &var, arg_str, description, func_ptr)`::
+ Introduce an option with argument.
+ The argument will be fed into the function given by `func_ptr`
+ and the result will be put into `var`.
+ See 'Option Callbacks' below for a more elaborate description.
+
+`OPT_ARGUMENT(long, description)`::
+ Introduce a long-option argument that will be kept in `argv[]`.
+
+
+The last element of the array must be `OPT_END()`.
+
+If not stated otherwise, interpret the arguments as follows:
+
+* `short` is a character for the short option
+ (e.g. `\'e\'` for `-e`, use `0` to omit),
+
+* `long` is a string for the long option
+ (e.g. `"example"` for `\--example`, use `NULL` to omit),
+
+* `int_var` is an integer variable,
+
+* `str_var` is a string variable (`char *`),
+
+* `arg_str` is the string that is shown as argument
+ (e.g. `"branch"` will result in `<branch>`).
+ If set to `NULL`, three dots (`...`) will be displayed.
+
+* `description` is a short string to describe the effect of the option.
+ It shall begin with a lower-case letter and a full stop (`.`) shall be
+ omitted at the end.
+
+Option Callbacks
+----------------
+
+The function must be defined in this form:
+
+ int func(const struct option *opt, const char *arg, int unset)
+
+The callback mechanism is as follows:
+
+* Inside `funct`, the only interesting member of the structure
+ given by `opt` is the void pointer `opt->value`.
+ `\*opt->value` will be the value that is saved into `var`, if you
+ use `OPT_CALLBACK()`.
+ For example, do `*(unsigned long *)opt->value = 42;` to get 42
+ into an `unsigned long` variable.
+
+* Return value `0` indicates success and non-zero return
+ value will invoke `usage_with_options()` and, thus, die.
+
+* If the user negates the option, `arg` is `NULL` and `unset` is 1.
+
+Sophisticated option parsing
+----------------------------
+
+If you need, for example, option callbacks with optional arguments
+or without arguments at all, or if you need other special cases,
+that are not handled by the macros above, you need to specify the
+members of the `option` structure manually.
+
+This is not covered in this document, but well documented
+in `parse-options.h` itself.
+
+Examples
+--------
+
+See `test-parse-options.c` and
+`builtin-add.c`,
+`builtin-clone.c`,
+`builtin-commit.c`,
+`builtin-fetch.c`,
+`builtin-fsck.c`,
+`builtin-rm.c`
+for real-world examples.
--
1.5.6.310.g344d
^ permalink raw reply related
* [jgit PATCH] Paper bag fix quoting for SSH transport commands
From: Shawn O. Pearce @ 2008-06-22 1:36 UTC (permalink / raw)
To: git; +Cc: Robin Rosenberg, Marek Zawirski
Not all Git-over-SSH servers run a Bourne shell on the remote side
to evaluate the command we are sending. Some servers run git-shell,
which will fail to execute git-upload-pack if we feed it a quoted
string for the name git-upload-pack.
Testing concludes that git-shell requires the command name to never
be quoted, and the argument name to always be single quoted. As
this is a long-standing behavior in the wild jgit needs to conform,
as git-shell and all git-shell work-a-likes such as gitosis may be
following the same convention.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
If there are no arguments I'll push this into the public tree.
It seems right on the surface, and is necessary to use jgit against
repo.or.cz, and probably many other sites like it.
.../spearce/jgit/transport/TransportGitSsh.java | 22 ++++++++++++++++++-
1 files changed, 20 insertions(+), 2 deletions(-)
diff --git a/org.spearce.jgit/src/org/spearce/jgit/transport/TransportGitSsh.java b/org.spearce.jgit/src/org/spearce/jgit/transport/TransportGitSsh.java
index d31c525..8944df7 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/transport/TransportGitSsh.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/transport/TransportGitSsh.java
@@ -88,6 +88,24 @@ class TransportGitSsh extends PackTransport {
return new SshFetchConnection();
}
+ private static void sqMinimal(final StringBuilder cmd, final String val) {
+ if (val.matches("^[a-zA-Z0-9._/-]*$")) {
+ // If the string matches only generally safe characters
+ // that the shell is not going to evaluate specially we
+ // should leave the string unquoted. Not all systems
+ // actually run a shell and over-quoting confuses them
+ // when it comes to the command name.
+ //
+ cmd.append(val);
+ } else {
+ sq(cmd, val);
+ }
+ }
+
+ private static void sqAlways(final StringBuilder cmd, final String val) {
+ sq(cmd, val);
+ }
+
private static void sq(final StringBuilder cmd, final String val) {
int i = 0;
@@ -157,9 +175,9 @@ class TransportGitSsh extends PackTransport {
path = (uri.getPath().substring(1));
final StringBuilder cmd = new StringBuilder();
- sq(cmd, exe);
+ sqMinimal(cmd, exe);
cmd.append(' ');
- sq(cmd, path);
+ sqAlways(cmd, path);
channel.setCommand(cmd.toString());
channel.setErrStream(System.err);
channel.connect();
--
1.5.6.74.g8a5e
^ permalink raw reply related
* git rebase --continue error message
From: Lea Wiemann @ 2008-06-22 3:21 UTC (permalink / raw)
To: Git Mailing List
The error message for git rebase --continue is misleading if no rebase
is in progress:
$ git rebase --abort
No rebase in progress?
$ git rebase --continue
You must edit all merge conflicts and then
mark them as resolved using git add
Anyone care to fix it?
^ permalink raw reply
* Why does diff --binary include content of files being deleted?
From: Allan Wind @ 2008-06-22 3:34 UTC (permalink / raw)
To: git
Between tag1 and tag2 I am deleting a number of binary files, and I was
surprised seeing the binaries being added to the diff when said files
are to be deleted:
git diff --binary tag1 tag2 > /tmp/diff && ls -l /tmp/diff
-rw-r--r-- 1 allan users 555135993 2008-06-21 22:37 /tmp/diff
git diff tag1 tag2 > /tmp/diff2 && ls -l /tmp/diff2
-rw-r--r-- 1 allan users 12862 2008-06-21 23:33 /tmp/diff2
/Allan
^ permalink raw reply
* Re: Why does diff --binary include content of files being deleted?
From: Shawn O. Pearce @ 2008-06-22 3:51 UTC (permalink / raw)
To: Allan Wind; +Cc: git
In-Reply-To: <20080622033454.GA10578@lifeintegrity.com>
Allan Wind <allan_wind@lifeintegrity.com> wrote:
> Between tag1 and tag2 I am deleting a number of binary files, and I was
> surprised seeing the binaries being added to the diff when said files
> are to be deleted:
>
> git diff --binary tag1 tag2 > /tmp/diff && ls -l /tmp/diff
> -rw-r--r-- 1 allan users 555135993 2008-06-21 22:37 /tmp/diff
>
> git diff tag1 tag2 > /tmp/diff2 && ls -l /tmp/diff2
> -rw-r--r-- 1 allan users 12862 2008-06-21 23:33 /tmp/diff2
In order to apply the diff in reverse we need the old binary data
in the diff output. So that's why its larger.
In other words lets say you actually wanted to go back to tag1,
after having tag2 for a while:
$ git checkout tag2
$ git diff --binary tag1 tag2 | git apply --index -R
without the binary data in the diff, apply cannot run in the
reverse direction to restore back to tag1. :)
--
Shawn.
^ permalink raw reply
* Re: Why does diff --binary include content of files being deleted?
From: Allan Wind @ 2008-06-22 4:05 UTC (permalink / raw)
To: git
In-Reply-To: <20080622035118.GD11793@spearce.org>
On 2008-06-21T23:51:18-0400, Shawn O. Pearce wrote:
> In order to apply the diff in reverse we need the old binary data
> in the diff output. So that's why its larger.
Makes sense, thanks. In my use case (where I do not need the reverse
diff) this adds 500+ MB or 43159% overhead.
When I tried to apply the large diff my virtual private server with 512
MB of memory git apply ran out of memory and died. Is there any way to
bound the memory usage of git apply?
/Allan
^ permalink raw reply
* Re: Why does diff --binary include content of files being deleted?
From: Shawn O. Pearce @ 2008-06-22 4:15 UTC (permalink / raw)
To: Allan Wind; +Cc: git
In-Reply-To: <20080622040536.GA10813@lifeintegrity.com>
Allan Wind <allan_wind@lifeintegrity.com> wrote:
> On 2008-06-21T23:51:18-0400, Shawn O. Pearce wrote:
> > In order to apply the diff in reverse we need the old binary data
> > in the diff output. So that's why its larger.
>
> Makes sense, thanks. In my use case (where I do not need the reverse
> diff) this adds 500+ MB or 43159% overhead.
Well, then in that case you have to omit --binary I think, or use a
filter script to strip out the binary data from the resulting patch.
> When I tried to apply the large diff my virtual private server with 512
> MB of memory git apply ran out of memory and died. Is there any way to
> bound the memory usage of git apply?
If you submit patches for it. ;-)
git-apply today is meant for applying small patches, like those that
would typically be written by a developer hacking on open source
software. It tries to be completely atomic; either the entire
patch applies at once, or the entire patch rejects with no changes
being made to the local directory. As such it applies everything in
memory, and only writes out when we are sure the patch applies clean.
So no, there isn't a way to make git-apply use less memory.
--
Shawn.
^ permalink raw reply
* Re: about c8af1de9 (git status uses pager)
From: Johannes Gilger @ 2008-06-22 7:24 UTC (permalink / raw)
To: git
In-Reply-To: <20080621214241.GA3839@dualtron.vpn.rwth-aachen.de>
On 21/06/08 23:42, Johannes Gilger wrote:
> Wow, I just noticed it myself. Why was that changed? I don't know about
> your status lines, but I for one find it really annoying. Anything
> that's in a pager isn't visible in my console afterwards. What's next?
> git branch in a pager too?
Seems like I got ahead of myself there. After setting the core.pager to
less -FRSX everything works fine ;)
Regards,
Jojo
--
Johannes Gilger <heipei@hackvalue.de>
http://hackvalue.de/heipei/
GPG-Key: 0x42F6DE81
GPG-Fingerprint: BB49 F967 775E BB52 3A81 882C 58EE B178 42F6 DE81
^ permalink raw reply
* shared lib+symlinks patch for cygwin
From: Reini Urban @ 2008-06-22 7:56 UTC (permalink / raw)
To: git
Attached is a semi-complete patch for a significant space reduction,
esp. on cygwin where file hardlinks do not work as on linux.
old bindir 5.8MB, new 2.7MB
$ du git-1.5.6-1/inst/usr/bin git-1.5.6-2/inst/usr/bin
5.8M git-1.5.6-1/inst/usr/bin
2.7M git-1.5.6-2/inst/usr/bin
First it links to a shared lib for all builtins (cygwin only),
second it uses symlinks instead of hardlinks (cygwin only).
mingw could also take this approach but I cannot test this.
A shared lib for all platforms should IMHO also be considered.
The first dll approach works fine.
The second has open problems with git-gui, because the native windows app
cannot handle symlinks.
file exists returns true but we cannot call it. So I tried to change
the calling sequence from git-config to git config, but Tcl is not my
native language. Maybe someone can help.
For reference:
I found an old shared libgit patch at
http://article.gmane.org/gmane.comp.version-control.git/8680/match=shared+lib
--- origsrc/git-1.5.6/Makefile 2008-06-19 00:49:49.000000000 +0200
+++ src/git-1.5.6/Makefile 2008-06-22 09:08:22.812500000 +0200
@@ -211,12 +211,12 @@
AR = ar
RM = rm -f
TAR = tar
+LN = ln
FIND = find
INSTALL = install
RPMBUILD = rpmbuild
TCL_PATH = tclsh
TCLTK_PATH = wish
-
export TCL_PATH TCLTK_PATH
# sparse is architecture-neutral, which means that we need to tell it
@@ -639,20 +639,20 @@
endif
ifeq ($(uname_O),Cygwin)
NO_D_TYPE_IN_DIRENT = YesPlease
- NO_D_INO_IN_DIRENT = YesPlease
NO_STRCASESTR = YesPlease
NO_MEMMEM = YesPlease
- NO_SYMLINK_HEAD = YesPlease
NEEDS_LIBICONV = YesPlease
NO_FAST_WORKING_DIRECTORY = UnfortunatelyYes
- NO_TRUSTABLE_FILEMODE = UnfortunatelyYes
OLD_ICONV = UnfortunatelyYes
# There are conflicting reports about this.
# On some boxes NO_MMAP is needed, and not so elsewhere.
# Try commenting this out if you suspect MMAP is more efficient
- NO_MMAP = YesPlease
+# NO_MMAP = YesPlease
NO_IPV6 = YesPlease
X = .exe
+ LIB_FILE=cyggit.dll
+ ALL_LDFLAGS += -Wl,--enable-auto-import
+ LN = ln -s
endif
ifeq ($(uname_S),FreeBSD)
NEEDS_LIBICONV = YesPlease
@@ -1040,7 +1040,7 @@
'-DGIT_INFO_PATH="$(infodir_SQ)"' $<
$(BUILT_INS): git$X
- $(QUIET_BUILT_IN)$(RM) $@ && ln git$X $@
+ $(QUIET_BUILT_IN)$(RM) $@ && $(LN) git$X $@
common-cmds.h: ./generate-cmdlist.sh command-list.txt
@@ -1169,8 +1171,17 @@
$(patsubst git-%$X,%.o,$(PROGRAMS)): $(LIB_H) $(wildcard */*.h)
builtin-revert.o wt-status.o: wt-status.h
+ifneq (,$(findstring .dll,$(LIB_FILE)))
+$(LIB_FILE): $(LIB_OBJS) builtin-fetch-pack.o builtin-send-pack.o $(XDIFF_LIB)
+ $(QUIET_CC)$(RM) git-dll.o && $(CC) -DSHARED_LIBOBJ
-DGIT_VERSION='"$(GIT_VERSION)"' \
+ $(ALL_CFLAGS) -o git-dll.o -c git.c
+ $(QUIET_LINK)$(RM) $@ && $(CC) -shared -Wl,--export-all-symbols \
+ -o $@ $(ALL_LDFLAGS) git-dll.o $(LIB_OBJS) builtin-fetch-pack.o
builtin-send-pack.o \
+ $(filter-out $(LIB_FILE),$(LIBS)) $(CURL_LIBCURL) $(EXPAT_LIBEXPAT)
+else
$(LIB_FILE): $(LIB_OBJS)
$(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $(LIB_OBJS)
+endif
XDIFF_OBJS=xdiff/xdiffi.o xdiff/xprepare.o xdiff/xutils.o xdiff/xemit.o \
xdiff/xmerge.o
@@ -1277,15 +1288,18 @@
endif
if test 'z$(bindir_SQ)' != 'z$(gitexecdir_SQ)'; \
then \
- ln -f '$(DESTDIR_SQ)$(bindir_SQ)/git$X' \
+ $(LN) -f '$(DESTDIR_SQ)$(bindir_SQ)/git$X' \
'$(DESTDIR_SQ)$(gitexecdir_SQ)/git$X' || \
cp '$(DESTDIR_SQ)$(bindir_SQ)/git$X' \
'$(DESTDIR_SQ)$(gitexecdir_SQ)/git$X'; \
fi
- $(foreach p,$(BUILT_INS), $(RM) '$(DESTDIR_SQ)$(gitexecdir_SQ)/$p'
&& ln '$(DESTDIR_SQ)$(gitexecdir_SQ)/git$X'
'$(DESTDIR_SQ)$(gitexecdir_SQ)/$p' ;)
+ $(foreach p,$(BUILT_INS), $(RM) '$(DESTDIR_SQ)$(gitexecdir_SQ)/$p'
&& $(LN) '$(DESTDIR_SQ)$(gitexecdir_SQ)/git$X'
'$(DESTDIR_SQ)$(gitexecdir_SQ)/$p' ;)
ifneq (,$X)
$(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_PROGRAMS)
$(BUILT_INS) git$X)), $(RM) '$(DESTDIR_SQ)$(gitexecdir_SQ)/$p';)
endif
+ifneq (,$(findstring .dll,$(LIB_FILE)))
+ $(INSTALL) $(LIB_FILE) '$(DESTDIR_SQ)$(bindir_SQ)'
+endif
install-doc:
$(MAKE) -C Documentation install
diff -urN origsrc/git-1.5.6/git-gui/git-gui.sh src/git-1.5.6/git-gui/git-gui.sh
--- origsrc/git-1.5.6/git-gui/git-gui.sh 2008-06-19 00:49:49.000000000 +0200
+++ src/git-1.5.6/git-gui/git-gui.sh 2008-06-22 09:38:23.359375000 +0200
@@ -279,8 +279,12 @@
}
set p [gitexec git-$name$::_search_exe]
- if {[file exists $p]} {
- set v [list $p]
+ if ([file exists $p]} {
+ if ([is_Cygwin] && [file exists [file join $p .lnk]]) {
+ set v [list $::_git $name]
+ } else {
+ set v [list $p]
+ }
} elseif {[is_Windows] && [file exists [gitexec git-$name]]} {
# Try to determine what sort of magic will make
# git-$name go and do its thing, because native
diff -urN origsrc/git-1.5.6/git.c src/git-1.5.6/git.c
--- origsrc/git-1.5.6/git.c 2008-06-19 00:49:49.000000000 +0200
+++ src/git-1.5.6/git.c 2008-06-21 11:10:48.953125000 +0200
@@ -384,6 +384,7 @@
}
}
+#ifndef SHARED_LIBOBJ
int main(int argc, const char **argv)
{
const char *cmd = argv[0] ? argv[0] : "git-help";
@@ -474,3 +475,4 @@
return 1;
}
+#endif
---------- Forwarded message ----------
From: Reini Urban <rurban@x-ray.at>
Date: 2008/6/21
Subject: Re: [ANNOUNCEMENT] Updated: git-1.5.6-1
To: cygwin@cygwin.com
2008/6/20 Brian Dessent:
> Reini Urban wrote:
>
>> Some attribute causes the linker to refuse to build the dll and wants
>> to build an exe.
>
> That's because you used -Wl,-shared where you should have used -shared.
> When you use -Wl the driver treats the argument as an opaque value that
> is simply passed to the linker without interpretation. In this case it
> means the driver is unaware that you're trying to create a shared
> library and instead passes to the linker the startup object and
> corresponding options for creating a program.
[Bang on the head] Stupid me.
Thanks, that compiles fine.
Unfortunately it doesn't work yet. The testsuite works with 4 failures.
I'll try it upstream now.
They wanted a shared lib for a long time for some perl and python libs.
I just did a simple make and installation improvement.
--
Reini Urban
http://phpwiki.org/ http://murbreak.at/
^ permalink raw reply
* Re: avoiding committing personal cruft
From: David @ 2008-06-22 7:58 UTC (permalink / raw)
To: James Sadler; +Cc: git
In-Reply-To: <e5e204700806211901v17a0450fw56b9db1c8c578dd@mail.gmail.com>
Re-cc-ing the list, I assume you didn't intend to mail me off-list.
On Sun, Jun 22, 2008 at 4:01 AM, James Sadler <freshtonic@gmail.com> wrote:
> 2008/6/22 David <wizzardx@gmail.com>:
>> On Sat, Jun 21, 2008 at 3:20 PM, James Sadler <freshtonic@gmail.com> wrote:
>>>
>>> The ide-branch has nothing in it except the cruft from the IDE and the
>>> paths leading up to that cruft.
>>> The master branch has a .gitignore that ignores the IDE files so I
>>> won't end up polluting master by accident.
>>>
>>> It's a manageable solution for now. I tend to think of it
>>> conceptually as 'layering' two branches: I want the
>>> content of both present in the working tree.
>>>
>>> I was just wondering if anyone else has tried something similar.
>>>
>>
>> Sounds like a normal use of topic branches. Branches rebased against
>> master, where you you keep changes you don't want to go into the main
>> branch at this time.
>
> Just to clarify, are you saying that the topic branch would contain
> all of master + ide cruft?
> I was maintaining a branch that *only* contained my ide cruft.
>
More correctly, the topic branch would contain the changes to the
master branch required to add your personal cruft.
Here is one relatively simple way to do it (there are other ways, this
one works well for me when I have local cruft I want for local dev but
don't want in public repos):
Assuming you have these 2 branches:
master - clean & version, ready to be used by others)
james_updates - your own private cruft. work in progress, ide files,
etc, on top of the master branch. Not ready for others yet.
Do all your hacking, private commits, cruft updates, etc in the
james_updates branch. Also try to keep changes in separate commits (1
for cruft & personal files, 1 for feature change X, one for bugfix Y,
etc).
Later, when you are ready to move (some of the) changes over to the
master branch:
1) Make a temporary copy of the james_updates branch:
git checkout james_updates
git checkout -b james_updates_tmp
2) Interactively rebase the temporary branch over to master:
git rebase -i master
During the interactive rebase, you strip out the cruft commits,
reorder updates, etc, as necessary
3) After the rebase, test the new version. Make sure it compiles and
the new features work correctly. Run any automated tests.
4) Merge the temporary branch into master, and drop the temporary branch:
git checkout master
git merge james_updates_tmp
git branch -d james_updates_tmp
5) Rebase your (original) updates branch onto the updated master:
git checkout james_updates
git rebase master
Now you have a james_updates branch on top of master which only has
your cruft etc which you didn't merge earlier. The already-merged
commits are automatically removed from james_updates during the
rebase.
David.
^ permalink raw reply
* Re: shared lib+symlinks patch for cygwin
From: Brian Dessent @ 2008-06-22 8:10 UTC (permalink / raw)
To: Reini Urban; +Cc: git
In-Reply-To: <6910a60806220056i1dda7f4elb4e5c69cdeea3cf9@mail.gmail.com>
Reini Urban wrote:
> esp. on cygwin where file hardlinks do not work as on linux.
> old bindir 5.8MB, new 2.7MB
Hard links work just fine on Cygwin, assuming the underlying volume is
NTFS. What you probably mean to say is that the Cygwin setup.exe
program won't create hardlinks from the tarball when installing binary
packages. But this could be worked around by creating the links with
'ln' in a postinstall script. Then NTFS users would get the space
savings and FAT users would get copies.
Brian
^ permalink raw reply
* Re: shared lib+symlinks patch for cygwin
From: Reini Urban @ 2008-06-22 8:19 UTC (permalink / raw)
To: git
In-Reply-To: <485E08F7.ADE2290C@dessent.net>
2008/6/22 Brian Dessent <brian@dessent.net>:
> Reini Urban wrote:
>
>> esp. on cygwin where file hardlinks do not work as on linux.
>> old bindir 5.8MB, new 2.7MB
>
> Hard links work just fine on Cygwin, assuming the underlying volume is
> NTFS.
And you have Administrator rights, yes. On cygwin you can install packages
without having root perms.
> What you probably mean to say is that the Cygwin setup.exe
> program won't create hardlinks from the tarball when installing binary
> packages. But this could be worked around by creating the links with
> 'ln' in a postinstall script. Then NTFS users would get the space
> savings and FAT users would get copies.
Good. So just postinstall.sh has to be fixed.
Anyway, I like the symlink approach to be fixed also.
--
Reini Urban
http://phpwiki.org/ http://murbreak.at/
^ permalink raw reply
* Re: about c8af1de9 (git status uses pager)
From: Jan Engelhardt @ 2008-06-22 9:09 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Vegard Nossum, Bart Trojanowski, git
In-Reply-To: <alpine.LNX.1.10.0806212343560.18093@fbirervta.pbzchgretzou.qr>
On Saturday 2008-06-21 23:45, Jan Engelhardt wrote:
>On Saturday 2008-06-21 23:42, Junio C Hamano wrote:
>>"Vegard Nossum" <vegard.nossum@gmail.com> writes:
>>
>>> On Sat, Jun 21, 2008 at 11:21 PM, Jan Engelhardt <jengelh@medozas.de> wrote:
>>>>
>>>> Since git 1.5.6, `git status` always invokes a pager, which is really
>>>> annoying when the output is less than the number of terminal rows
>>>> available. Can I turn that off somehow or do I need to send a reverting
>>>> patch?
>>>
>>> I think it would work to set PAGER="less -F" (a.k.a. --quit-if-one-screen)?
>>
>>Probably better with LESS=FRSX, which is what git uses as a sane default
>>if nothing is set.
>>
>I went with Vegard's suggestion to change the pager command in
>~/.gitconfig, since I have the $LESS environment variable already
>defined as "-MSi", and I do not want to change that; because if I am
>going to run less (often at the end of a pipe), I certainly do not
>want it to just quit on me. So -F in $LESS is a no-no.
>
>Since I need "-MRSi" for git anyhow, tweaking ~/.gitconfig was easy.
>
I've played with `less -F` for a while now, and there is an inherent
problem with that. Or should I say, xterm.
When less quits, the xterm "screen" blits back to the shell output
that was previously visible, so
git status
with less -F as a pager displays practically *nothing*.
I am aware that this is a less / xterm issue, but I wanted to let
you know.
^ permalink raw reply
* Re: about c8af1de9 (git status uses pager)
From: Junio C Hamano @ 2008-06-22 9:40 UTC (permalink / raw)
To: Jan Engelhardt; +Cc: Vegard Nossum, Bart Trojanowski, git
In-Reply-To: <alpine.LNX.1.10.0806221107540.15126@fbirervta.pbzchgretzou.qr>
Jan Engelhardt <jengelh@medozas.de> writes:
> I am aware that this is a less / xterm issue, but I wanted to let
> you know.
Do you mean "me" by "let you know"? Well, I have already been aware of
it, thanks.
^ permalink raw reply
* [PATCH 1/5] rerere: rerere_created_at() and has_resolution() abstraction
From: Junio C Hamano @ 2008-06-22 9:47 UTC (permalink / raw)
To: Ingo Molnar; +Cc: git
In-Reply-To: <7vskvd9kai.fsf@gitster.siamese.dyndns.org>
There were too many places in the code how an entry in the rerere database
looks like, and the garbage_collect() function that iterates over
subdirectories of the rr-cache directory was the worse offender.
Introduce two helper functions, rerere_created_at() and has_resolution(),
to abstract out the logic a bit better.
Incidentally this fixes a small memory leak in garbage_collect()
function. The path list to collect the entries to be pruned were defined
to strdup the paths but the caller was feeding a path after doing an extra
copy. Because the list does not have to be sorted by conflict signature
hash, we use path_list_append() instead of path_list_insert().
While we are at it, make a conflicted hunk comparision in handle_file() a
bit easier to read.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
* So this is a series to handle the first point in the message I am
replying to.
builtin-rerere.c | 57 ++++++++++++++++++++++++-----------------------------
1 files changed, 26 insertions(+), 31 deletions(-)
diff --git a/builtin-rerere.c b/builtin-rerere.c
index 85222d9..610b96a 100644
--- a/builtin-rerere.c
+++ b/builtin-rerere.c
@@ -23,6 +23,18 @@ static const char *rr_path(const char *name, const char *file)
return git_path("rr-cache/%s/%s", name, file);
}
+static time_t rerere_created_at(const char *name)
+{
+ struct stat st;
+ return stat(rr_path(name, "preimage"), &st) ? (time_t) 0 : st.st_mtime;
+}
+
+static int has_resolution(const char *name)
+{
+ struct stat st;
+ return !stat(rr_path(name, "postimage"), &st);
+}
+
static void read_rr(struct path_list *rr)
{
unsigned char sha1[20];
@@ -98,13 +110,10 @@ static int handle_file(const char *path,
else if (!prefixcmp(buf, "======="))
hunk = 2;
else if (!prefixcmp(buf, ">>>>>>> ")) {
- int cmp = strbuf_cmp(&one, &two);
-
+ if (strbuf_cmp(&one, &two) > 0)
+ strbuf_swap(&one, &two);
hunk_no++;
hunk = 0;
- if (cmp > 0) {
- strbuf_swap(&one, &two);
- }
if (out) {
fputs("<<<<<<<\n", out);
fwrite(one.buf, one.len, 1, out);
@@ -201,33 +210,24 @@ static void unlink_rr_item(const char *name)
static void garbage_collect(struct path_list *rr)
{
struct path_list to_remove = { NULL, 0, 0, 1 };
- char buf[1024];
DIR *dir;
struct dirent *e;
- int len, i, cutoff;
+ int i, cutoff;
time_t now = time(NULL), then;
- strlcpy(buf, git_path("rr-cache"), sizeof(buf));
- len = strlen(buf);
- dir = opendir(buf);
- strcpy(buf + len++, "/");
+ dir = opendir(git_path("rr-cache"));
while ((e = readdir(dir))) {
const char *name = e->d_name;
- struct stat st;
- if (name[0] == '.' && (name[1] == '\0' ||
- (name[1] == '.' && name[2] == '\0')))
+ if (name[0] == '.' &&
+ (name[1] == '\0' || (name[1] == '.' && name[2] == '\0')))
continue;
- i = snprintf(buf + len, sizeof(buf) - len, "%s", name);
- strlcpy(buf + len + i, "/preimage", sizeof(buf) - len - i);
- if (stat(buf, &st))
+ then = rerere_created_at(name);
+ if (!then)
continue;
- then = st.st_mtime;
- strlcpy(buf + len + i, "/postimage", sizeof(buf) - len - i);
- cutoff = stat(buf, &st) ? cutoff_noresolve : cutoff_resolve;
- if (then < now - cutoff * 86400) {
- buf[len + i] = '\0';
- path_list_insert(xstrdup(name), &to_remove);
- }
+ cutoff = (has_resolution(name)
+ ? cutoff_resolve : cutoff_noresolve);
+ if (then < now - cutoff * 86400)
+ path_list_append(name, &to_remove);
}
for (i = 0; i < to_remove.nr; i++)
unlink_rr_item(to_remove.items[i].path);
@@ -306,13 +306,11 @@ static int do_plain_rerere(struct path_list *rr, int fd)
*/
for (i = 0; i < rr->nr; i++) {
- struct stat st;
int ret;
const char *path = rr->items[i].path;
const char *name = (const char *)rr->items[i].util;
- if (!stat(rr_path(name, "preimage"), &st) &&
- !stat(rr_path(name, "postimage"), &st)) {
+ if (has_resolution(name)) {
if (!merge(name, path)) {
fprintf(stderr, "Resolved '%s' using "
"previous resolution.\n", path);
@@ -410,11 +408,8 @@ int cmd_rerere(int argc, const char **argv, const char *prefix)
return do_plain_rerere(&merge_rr, fd);
else if (!strcmp(argv[1], "clear")) {
for (i = 0; i < merge_rr.nr; i++) {
- struct stat st;
const char *name = (const char *)merge_rr.items[i].util;
- if (!stat(git_path("rr-cache/%s", name), &st) &&
- S_ISDIR(st.st_mode) &&
- stat(rr_path(name, "postimage"), &st))
+ if (!has_resolution(name))
unlink_rr_item(name);
}
unlink(merge_rr_path);
--
1.5.6.12.g73f03
^ permalink raw reply related
* [PATCH 2/5] git-rerere: detect unparsable conflicts
From: Junio C Hamano @ 2008-06-22 9:47 UTC (permalink / raw)
To: Ingo Molnar; +Cc: git
In-Reply-To: <7vskvd9kai.fsf@gitster.siamese.dyndns.org>
rerere did not detect the case where <<< === >>> markers did not match.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
builtin-rerere.c | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/builtin-rerere.c b/builtin-rerere.c
index 610b96a..addc5c7 100644
--- a/builtin-rerere.c
+++ b/builtin-rerere.c
@@ -144,6 +144,11 @@ static int handle_file(const char *path,
fclose(out);
if (sha1)
SHA1_Final(sha1, &ctx);
+ if (hunk) {
+ if (output)
+ unlink(output);
+ return error("Could not parse conflict hunks in %s", path);
+ }
return hunk_no;
}
--
1.5.6.12.g73f03
^ permalink raw reply related
* [PATCH 3/5] rerere: remove dubious "tail_optimization"
From: Junio C Hamano @ 2008-06-22 9:47 UTC (permalink / raw)
To: Ingo Molnar; +Cc: git
In-Reply-To: <7vskvd9kai.fsf@gitster.siamese.dyndns.org>
It is dubious if it is cheaper to shift entries repeatedly using memmove()
to collect entries that needs to be written out in front of an array than
simply marking the entries to be skipped. In addition, the label called this
"tail optimization", but this obviously is not what people usually call
with that name.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
builtin-rerere.c | 19 +++++++++----------
1 files changed, 9 insertions(+), 10 deletions(-)
diff --git a/builtin-rerere.c b/builtin-rerere.c
index addc5c7..0eec1f9 100644
--- a/builtin-rerere.c
+++ b/builtin-rerere.c
@@ -66,8 +66,12 @@ static int write_rr(struct path_list *rr, int out_fd)
{
int i;
for (i = 0; i < rr->nr; i++) {
- const char *path = rr->items[i].path;
- int length = strlen(path) + 1;
+ const char *path;
+ int length;
+ if (!rr->items[i].util)
+ continue;
+ path = rr->items[i].path;
+ length = strlen(path) + 1;
if (write_in_full(out_fd, rr->items[i].util, 40) != 40 ||
write_in_full(out_fd, "\t", 1) != 1 ||
write_in_full(out_fd, path, length) != length)
@@ -319,7 +323,7 @@ static int do_plain_rerere(struct path_list *rr, int fd)
if (!merge(name, path)) {
fprintf(stderr, "Resolved '%s' using "
"previous resolution.\n", path);
- goto tail_optimization;
+ goto mark_resolved;
}
}
@@ -330,13 +334,8 @@ static int do_plain_rerere(struct path_list *rr, int fd)
fprintf(stderr, "Recorded resolution for '%s'.\n", path);
copy_file(rr_path(name, "postimage"), path, 0666);
-tail_optimization:
- if (i < rr->nr - 1)
- memmove(rr->items + i,
- rr->items + i + 1,
- sizeof(rr->items[0]) * (rr->nr - i - 1));
- rr->nr--;
- i--;
+ mark_resolved:
+ rr->items[i].util = NULL;
}
return write_rr(rr, fd);
--
1.5.6.12.g73f03
^ permalink raw reply related
* [PATCH 4/5] t4200: fix rerere test
From: Junio C Hamano @ 2008-06-22 9:48 UTC (permalink / raw)
To: Ingo Molnar; +Cc: git
In-Reply-To: <7vskvd9kai.fsf@gitster.siamese.dyndns.org>
The test used "diff-files -q" which is not about reporting if there is
a difference at all. Instead, make sure that the path remains as
conflicting in the index after rerere autoresolves it, as we will be
adding rerere.autoupdate configuration with the next patch.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
t/t4200-rerere.sh | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/t/t4200-rerere.sh b/t/t4200-rerere.sh
index 85d7e3e..afb3e3d 100755
--- a/t/t4200-rerere.sh
+++ b/t/t4200-rerere.sh
@@ -193,9 +193,9 @@ test_expect_success 'resolution was recorded properly' '
echo Bello > file3 &&
git add file3 &&
git commit -m version2 &&
- ! git merge fifth &&
- git diff-files -q &&
- test Cello = "$(cat file3)"
+ test_must_fail git merge fifth &&
+ test Cello = "$(cat file3)" &&
+ test 0 != $(git ls-files -u | wc -l)
'
test_done
--
1.5.6.12.g73f03
^ permalink raw reply related
* [PATCH 5/5] rerere.autoupdate
From: Junio C Hamano @ 2008-06-22 9:48 UTC (permalink / raw)
To: Ingo Molnar; +Cc: git
In-Reply-To: <7vskvd9kai.fsf@gitster.siamese.dyndns.org>
When this configuration is set, paths that are autoresolved by git-rerere
are updated in the index as well.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
Documentation/config.txt | 5 +++++
builtin-rerere.c | 37 +++++++++++++++++++++++++++++++++++++
t/t4200-rerere.sh | 10 ++++++++++
3 files changed, 52 insertions(+), 0 deletions(-)
diff --git a/Documentation/config.txt b/Documentation/config.txt
index 5331b45..0c7cf61 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -650,6 +650,11 @@ gc.rerereunresolved::
kept for this many days when `git rerere gc` is run.
The default is 15 days. See linkgit:git-rerere[1].
+rerere.autoupdate::
+ When set to true, `git-rerere` updates the index with the
+ resulting contents after it cleanly resolves conflicts using
+ previously recorded resolution. Defaults to false.
+
rerere.enabled::
Activate recording of resolved conflicts, so that identical
conflict hunks can be resolved automatically, should they
diff --git a/builtin-rerere.c b/builtin-rerere.c
index 0eec1f9..839b26e 100644
--- a/builtin-rerere.c
+++ b/builtin-rerere.c
@@ -16,6 +16,9 @@ static int cutoff_resolve = 60;
/* if rerere_enabled == -1, fall back to detection of .git/rr-cache */
static int rerere_enabled = -1;
+/* automatically update cleanly resolved paths to the index */
+static int rerere_autoupdate;
+
static char *merge_rr_path;
static const char *rr_path(const char *name, const char *file)
@@ -276,9 +279,36 @@ static int diff_two(const char *file1, const char *label1,
return 0;
}
+static struct lock_file index_lock;
+
+static int update_paths(struct path_list *update)
+{
+ int i;
+ int fd = hold_locked_index(&index_lock, 0);
+ int status = 0;
+
+ if (fd < 0)
+ return -1;
+
+ for (i = 0; i < update->nr; i++) {
+ struct path_list_item *item = &update->items[i];
+ if (add_file_to_cache(item->path, ADD_CACHE_IGNORE_ERRORS))
+ status = -1;
+ }
+
+ if (!status && active_cache_changed) {
+ if (write_cache(fd, active_cache, active_nr) ||
+ commit_locked_index(&index_lock))
+ die("Unable to write new index file");
+ } else if (fd >= 0)
+ rollback_lock_file(&index_lock);
+ return status;
+}
+
static int do_plain_rerere(struct path_list *rr, int fd)
{
struct path_list conflict = { NULL, 0, 0, 1 };
+ struct path_list update = { NULL, 0, 0, 1 };
int i;
find_conflict(&conflict);
@@ -323,6 +353,8 @@ static int do_plain_rerere(struct path_list *rr, int fd)
if (!merge(name, path)) {
fprintf(stderr, "Resolved '%s' using "
"previous resolution.\n", path);
+ if (rerere_autoupdate)
+ path_list_insert(path, &update);
goto mark_resolved;
}
}
@@ -338,6 +370,9 @@ static int do_plain_rerere(struct path_list *rr, int fd)
rr->items[i].util = NULL;
}
+ if (update.nr)
+ update_paths(&update);
+
return write_rr(rr, fd);
}
@@ -349,6 +384,8 @@ static int git_rerere_config(const char *var, const char *value, void *cb)
cutoff_noresolve = git_config_int(var, value);
else if (!strcmp(var, "rerere.enabled"))
rerere_enabled = git_config_bool(var, value);
+ else if (!strcmp(var, "rerere.autoupdate"))
+ rerere_autoupdate = git_config_bool(var, value);
else
return git_default_config(var, value, cb);
return 0;
diff --git a/t/t4200-rerere.sh b/t/t4200-rerere.sh
index afb3e3d..a64727d 100755
--- a/t/t4200-rerere.sh
+++ b/t/t4200-rerere.sh
@@ -193,9 +193,19 @@ test_expect_success 'resolution was recorded properly' '
echo Bello > file3 &&
git add file3 &&
git commit -m version2 &&
+ git tag version2 &&
test_must_fail git merge fifth &&
test Cello = "$(cat file3)" &&
test 0 != $(git ls-files -u | wc -l)
'
+test_expect_success 'rerere.autoupdate' '
+ git config rerere.autoupdate true
+ git reset --hard &&
+ git checkout version2 &&
+ test_must_fail git merge fifth &&
+ test 0 = $(git ls-files -u | wc -l)
+
+'
+
test_done
--
1.5.6.12.g73f03
^ permalink raw reply related
* Re: about c8af1de9 (git status uses pager)
From: Vegard Nossum @ 2008-06-22 9:49 UTC (permalink / raw)
To: Jan Engelhardt; +Cc: Junio C Hamano, Bart Trojanowski, git
In-Reply-To: <alpine.LNX.1.10.0806221107540.15126@fbirervta.pbzchgretzou.qr>
On Sun, Jun 22, 2008 at 11:09 AM, Jan Engelhardt <jengelh@medozas.de> wrote:
> I've played with `less -F` for a while now, and there is an inherent
> problem with that. Or should I say, xterm.
> When less quits, the xterm "screen" blits back to the shell output
> that was previously visible, so
> git status
> with less -F as a pager displays practically *nothing*.
> I am aware that this is a less / xterm issue, but I wanted to let
> you know.
>
Option -X should do the trick :-)
Vegard
--
"The animistic metaphor of the bug that maliciously sneaked in while
the programmer was not looking is intellectually dishonest as it
disguises that the error is the programmer's own creation."
-- E. W. Dijkstra, EWD1036
^ permalink raw reply
* Re: about c8af1de9 (git status uses pager)
From: Junio C Hamano @ 2008-06-22 10:01 UTC (permalink / raw)
To: Jan Engelhardt
Cc: Vegard Nossum, Bart Trojanowski, git, Jeff King, Bart Trojanowski
In-Reply-To: <7vtzflolis.fsf@gitster.siamese.dyndns.org>
Junio C Hamano <gitster@pobox.com> writes:
> Jan Engelhardt <jengelh@medozas.de> writes:
>
>> I am aware that this is a less / xterm issue, but I wanted to let
>> you know.
>
> Do you mean "me" by "let you know"? Well, I have already been aware of
> it, thanks.
Having said all that, I have to say I am regretting to have accepted that
patch to enable pager on status, not because it bothers me personally (it
doesn't primarily because I practically never run git-status because I
consider the command useless and living almost always in Emacs helps), but
because in principle changing anything that existing users are used to is
bad.
Jeff had a patch to allow boolean configuration variable "pager.<command>"
to override the built-in pager settings during 1.5.6 cycle, and I think it
was a reasonable approach to take. People who want to page output from
git-status can then set "pager.status = true" in their configuration (and
then we can revert c8af1de (make git-status use a pager, 2008-04-23)).
Alternatively we could keep the current status-quo for the default, and
people can say "pager.status = false" in their configuration.
^ permalink raw reply
* linux-x86-tip: pilot error?
From: Paul E. McKenney @ 2008-06-22 12:36 UTC (permalink / raw)
To: mingo; +Cc: git
Hello, Ingo,
I took the precaution of rebuilding my linux-2.6-tip from scratch as follows:
544 mkdir linux-2.6-tip
545 cd linux-2.6-tip
546 git-init-db
547 git-remote add linus git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
548 git-remote add tip git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip.git
549 git-remote update
550 git-checkout tip-core-rcu-2008-06-16_09.23_Mon
The "git-checkout" command complained as follows:
warning: You appear to be on a branch yet to be born.
warning: Forcing checkout of tip-core-rcu-2008-06-16_09.23_Mon.
Checking 24254 files out...
100% (24254/24254) done
fatal: ambiguous argument 'HEAD': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions
Cannot detach HEAD
In addition, the kernel/rcutorture.c file does not have the "stutter"
changes in it after doing this checkout.
Did I mess something up? Am I working with a too-old version of git
(git version 1.5.2.5)? Or has git simply taken a deep and personal
disliking to me? ;-)
My next step will be to try a more recent version of git. In parallel,
I will just re-do the patch on top of my patch stack.
Thanx, Paul
PS. I am assuming that the repeated messages from git-update of
the following form are expected behavior when there are tags:
* refs/tags/tip-x86-xsave-2008-05-26_08_54_Mon: storing tag 'tip-x86-xsave-2008-05-26_08_54_Mon' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
commit: d40ace0
^ permalink raw reply
* Re: [PATCH 1/2] api-parse-options.txt: Introduce documentation for parse options API
From: Michele Ballabio @ 2008-06-22 12:49 UTC (permalink / raw)
To: git; +Cc: Stephan Beyer, Pierre Habouzit, Junio C Hamano,
Johannes Schindelin
In-Reply-To: <1214092802-8175-1-git-send-email-s-beyer@gmx.net>
On Sunday 22 June 2008, Stephan Beyer wrote:
> +`PARSE_OPT_KEEP_DASHDASH`::
> + Usually long options (`\--long-opt`) are boiled down to their
> + short option equivalent, if available.
> + Using this flag, long options are kept.
No: PARSE_OPT_KEEP_DASHDASH keeps the "--" that usually separates options
from files, as in
git ls-files [options] -- [files]
i.e. after parsing, the new argv will still contain "--".
> +`OPT__ABBREV(&int_var)`::
> + Add `\--abbrev [<n>]`.
better:
+ Add `\--abbrev[=<n>]`.
since the <n> is optional.
^ 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