* [PATCH 6/7] prompt: use git_terminal_prompt
From: Jeff King @ 2011-12-08 8:33 UTC (permalink / raw)
To: git; +Cc: Erik Faye-Lund, Junio C Hamano
In-Reply-To: <20111208082118.GA1507@sigill.intra.peff.net>
Our custom implementation of git_terminal_prompt has many
advantages over regular getpass(), as described in the prior
commit.
This also lets us implement a PROMPT_ECHO flag for callers
who want it.
Signed-off-by: Jeff King <peff@peff.net>
---
prompt.c | 3 ++-
prompt.h | 1 +
2 files changed, 3 insertions(+), 1 deletions(-)
diff --git a/prompt.c b/prompt.c
index 2002644..72ab9de 100644
--- a/prompt.c
+++ b/prompt.c
@@ -2,6 +2,7 @@
#include "run-command.h"
#include "strbuf.h"
#include "prompt.h"
+#include "compat/terminal.h"
static char *do_askpass(const char *cmd, const char *prompt)
{
@@ -50,7 +51,7 @@
return do_askpass(askpass, prompt);
}
- r = getpass(prompt);
+ r = git_terminal_prompt(prompt, flags & PROMPT_ECHO);
if (!r)
die_errno("could not read '%s'", prompt);
return r;
diff --git a/prompt.h b/prompt.h
index 9ab85a7..04f321a 100644
--- a/prompt.h
+++ b/prompt.h
@@ -2,6 +2,7 @@
#define PROMPT_H
#define PROMPT_ASKPASS (1<<0)
+#define PROMPT_ECHO (1<<1)
char *git_prompt(const char *prompt, int flags);
char *git_getpass(const char *prompt);
--
1.7.8.rc2.8.gf0f4f
^ permalink raw reply related
* [PATCH 7/7] credential: use git_prompt instead of git_getpass
From: Jeff King @ 2011-12-08 8:33 UTC (permalink / raw)
To: git; +Cc: Erik Faye-Lund, Junio C Hamano
In-Reply-To: <20111208082118.GA1507@sigill.intra.peff.net>
We use git_getpass to retrieve the username and password
from the terminal. However, git_getpass will not echo the
username as the user types. We can fix this by using the
more generic git_prompt, which underlies git_getpass but
lets us specify an "echo" option.
Signed-off-by: Jeff King <peff@peff.net>
---
credential.c | 15 +++++++--------
1 files changed, 7 insertions(+), 8 deletions(-)
diff --git a/credential.c b/credential.c
index fbb7231..62d1c56 100644
--- a/credential.c
+++ b/credential.c
@@ -109,7 +109,8 @@ static void credential_describe(struct credential *c, struct strbuf *out)
strbuf_addf(out, "/%s", c->path);
}
-static char *credential_ask_one(const char *what, struct credential *c)
+static char *credential_ask_one(const char *what, struct credential *c,
+ int flags)
{
struct strbuf desc = STRBUF_INIT;
struct strbuf prompt = STRBUF_INIT;
@@ -121,11 +122,7 @@ static void credential_describe(struct credential *c, struct strbuf *out)
else
strbuf_addf(&prompt, "%s: ", what);
- /* FIXME: for usernames, we should do something less magical that
- * actually echoes the characters. However, we need to read from
- * /dev/tty and not stdio, which is not portable (but getpass will do
- * it for us). http.c uses the same workaround. */
- r = git_getpass(prompt.buf);
+ r = git_prompt(prompt.buf, flags);
strbuf_release(&desc);
strbuf_release(&prompt);
@@ -135,9 +132,11 @@ static void credential_describe(struct credential *c, struct strbuf *out)
static void credential_getpass(struct credential *c)
{
if (!c->username)
- c->username = credential_ask_one("Username", c);
+ c->username = credential_ask_one("Username", c,
+ PROMPT_ASKPASS|PROMPT_ECHO);
if (!c->password)
- c->password = credential_ask_one("Password", c);
+ c->password = credential_ask_one("Password", c,
+ PROMPT_ASKPASS);
}
int credential_read(struct credential *c, FILE *fp)
--
1.7.8.rc2.8.gf0f4f
^ permalink raw reply related
* Re: Auto update submodules after merge and reset
From: andreas.t.auer_gtml_37453 @ 2011-12-08 9:13 UTC (permalink / raw)
To: Jens Lehmann; +Cc: Andreas T.Auer, git
In-Reply-To: <4EDFE75C.5050201@web.de>
On 07.12.2011 23:23 Jens Lehmann wrote:
> Am 07.12.2011 10:07, schrieb Andreas T.Auer:
> > Jens Lehmann wrote:
> >
> >> Am 30.11.2011 01:55, schrieb Max Krasnyansky: I'm working on a
> >> patch series to teach Git to optionally update the submodules
> >> work trees on checkout, reset merge and so on, but I'm not there
> >> yet.
> >>
> >>> I'm thinking about adding a config option that would enable
> >>> automatic submodule update but wanted to see if there is some
> >>> fundamental reason why it would not be accepted.
> > Because there is no good way to do so. It would be fine when you
> > just track the submodules "read-only", but if you are actually
> > working on submodules, it is a bad idea to always get a detached
> > HEAD.
>
> YMMV. We get along *really* well with this because all developers
> know that if they want to hack on a submodule, they have to create a
> branch in there first (and if they forget to do that, git status and
> friends will tell them).
Sorry, my fault. I was answering to the question why auto-update is not
the default, but replied to the wrong text block. (I should have heeded
the note to self about the coffee in the morning ;-) )
Having the config option is fine, of course. But it is not easy to
choose a good default auto-update method, because you need different
workflows for different submodules/users .
> What bugs us is that submodule HEADs don't follow what is checked
> out (or merged, or reset ...) in the superproject. We had some
> really nasty mismerges because of that, so we need the option to
> enable it.
>
Full ack. Using the auto-update method "disabled" is a bad choice, too. ;-)
> > Because if you are working on a maint branch in the submodule and
> > then you checkout a pu branch in the superproject, because you
> > have forgotten that maint branch in the submodule then all the
> > proposed updates go to the maintenance branch -> bad.
>
> Nope, checkout will fail and not do anything as it will detect
> changes in the submodule to be updated by the checkout (just as it
> would do with a regular file).
>
Without auto-update you can easily checkout the pu branch in the
superproject. And when you execute
git submodule update --merge
the pu referenced commit of the submodule will be merged into the
currently checkedout maint branch of the submodule without warning
unless you have merge conflicts.
And when auto-update is just running git submodule update automatically
it would act as I described.
But you are right, with auto-update the submodule's HEAD can be checked
against the old gitlink before it is changed. If doing it in two steps
it is not possible to have this check.
> >
> > I was thinking about submodule integration and had the idea to
> > bind a submodule to the superproject by having special references
> > in the submodule like refs/super/master, refs/super/featureX... So
> > these references are like tracking branches for the refs/heads/* of
> > the superproject.
>
> Having stuff in the submodule reference branches in the superproject
> sounds upside down, as a superproject has (and should have) zero
> knowledge about the superproject (as it could have many different of
> them).
>
My viewpoint is that I have a big project that is divided into
submodules because not all developerss need all parts of the project.
Therefore I wanted something that uses submodules as separate repos, but
from the users viewpoint it should be as if the submodules are just
subdirectories. It would include that diffs of submodules are not shown
as a summary of commit messages but as a diff of the sources. And from
that perspective it makes more sense to have tracking branches in the
submodule that are owned by the superproject. In the first thought these
tracking refs were meant to be readonly in the submodule and only
updatable from the superproject, but then I thought the possibility of
detaching and re-attaching is nice, too. One thing I've forgot to
mention: the refs/super/* are not SHA1-refs to the superproject (that
would be stupid indeed), but they contain the corresponding gitlink-SHA1
from the revision referenced by refs/heads/*. So when you have a
detached HEAD after auto-update you would simply "git checkout -B
super/<superproject-branchname>" in the submodule, with the difference
that it shouldn't update refs/heads/super/*, but refs/super/* so that
these branches can be treated specially.
> > If you have tracking branches, the supermodule can just update the
> > corresponding branch. If this branch is currently checkedout and
> > the work area is clean, then the work area is updated, too. If
> > there is currently a local branch or a diffent super-branch
> > checked out then the working area should be considered "detached"
> > from the superproject and not updated.
>
> This sounds a lot like the "follow branch tip" model we discussed
> recently (which could be configured via .gitmodules), but I'm not
> sure you really are in the same boat here.
When I understood that correctly it was just a configuration to what
branch should be automatically checked out in the submodule. This seems
to be too complicated IMO, because when you have different branches in
the superproject then you may want to have different branches in the
submodules, too, but you would need to configure that submodule branch
in .gitmodules for each branch separately. I.e. in the master branch the
.gitmodule may contain "master", in the maint branch the .gitmodules may
have "maint" as the branch to follow.
I do want to follow the tip of the branch, if the superproject has that
currently checked out. If the superproject checks out a tagged version
for a rebuild, then the submodule should not follow the tip, but should
get a detached HEAD of the corresponding commit, just as the
superproject. When the superproject goes back to the branch, the
submodule should go back to its tracking branch.
>
> > With this concept you could even switch branches in the
> > superproject and the attached submodules follow - still having no
> > detached HEAD. When you want to do some local work on the
> > submodule you checkout a local branch and merge back into the super
> > branch later.
>
> You lost me here. How can you merge a submodule branch into one of
> the superproject?
It wouldn't work, if the super/* branch would contain a superproject's
SHA-1, that is right. But as explained above, it points to a commit of
the submodule.
>
> But we would want to have a deterministic update procedure, no? (And
> what has more freedom than a detached HEAD? ;-)__
I think my proposal would be deterministic.
And everything where you can commit to has more freedom than a detached HEAD
>
> > Even though it will raise a lot of detailed questions like "should
> > the refs/super/* be pushed/pulled when syncing the submodule
> > repositories".
>
> I doubt that is a good idea, as that might conflict with the same
> submodule sitting in a different superproject. But I'm interested to
> hear how you want to solve that.
The first answer to my question was "yes, you need to transfer the refs
or you get unreferenced objects" and "no, you can't transfer the refs,
because they are owned by the superproject, not the submodule."
But binding a submodule to a superproject makes perfect sense if it is
_one_ project that is split into submodules. In that case you only have
one superproject for a submodule and for that purpose it would be good
workflow. It is even nice to see which commits in the submodule belong
to what branches in the superproject or to what release version (so
tracking superproject tags would make sense, too). If you have a
submodule that has more than one superproject but these are
well-defined, it could be solved using refspecs (e.g. refs/super/foo/*
for one and refs/super/bar/* for the other superproject), but currently
I can't think of a context where this makes sense.
Of course there are other types of submodules, so using refs/super/*
wouldn't be a good default variant for auto-update either. E.g. if you
use a 3rdParty lib, then the detached HEAD is fine, because usually you
don't touch it except when you switch to a new version from time to time.
^ permalink raw reply
* Re: Undo a commit that is already pushed to central server and merged to several branches
From: Matthias Fechner @ 2011-12-08 9:46 UTC (permalink / raw)
To: Johan Herland; +Cc: Ramkumar Ramachandra, Git Mailing List
In-Reply-To: <CALKQrgcQ5jv+oDXxDoTGUhmP-Dg344-oSotb+q-4a3fnEBY1Zw@mail.gmail.com>
Dear Ramkumar and Johan,
Am 07.12.11 17:01, schrieb Johan Herland:
> Use "git revert $commit" to undo the effects of the given $commit.
> This must be applied to all affected branches (either by reverting in
> the master branch and remerging master to the other branches, or by
> using "git revert" in each individual branch).
thanks a lot for your help.
The steps I did now was at first undo everything i did locally with:
git reset --hard origin/master
Then undo the bad commit:
git revert commit-id
git commit
Now the bad commit was undone and I merged the master branch in all
other branches.
I create a new branch and cherry-picked the bad commit into it so I can
correct the problem there and later merge this branch in all the other ones.
Hopefully this short summary will help other users having the same problem.
Bye
Matthias
--
"Programming today is a race between software engineers striving to
build bigger and better idiot-proof programs, and the universe trying to
produce bigger and better idiots. So far, the universe is winning." --
Rich Cook
^ permalink raw reply
* Re: [PATCH] index-pack: eliminate unlimited recursion in get_delta_base()
From: Nguyen Thai Ngoc Duy @ 2011-12-08 11:06 UTC (permalink / raw)
To: Shawn Pearce; +Cc: git, Junio C Hamano
In-Reply-To: <CAJo=hJvrk3Jzg3dQhQnfbmKAFovLuEtJAP4rakHPFeuZ0T5R7g@mail.gmail.com>
2011/12/8 Shawn Pearce <spearce@spearce.org>:
> I think you missed the critical recursion. The real work is the
> recursion within find_unresolved_deltas(). This little helper
> get_base_data() shouldn't be tripping over these cases unless we have
> run out of delta_base_cache_limit and released objects near the base
> end of the delta chain, in which case this will restore them.
>
> Maybe this is useful on its own, but in my opinion its not an
> interesting patch to consider without first fixing
> find_unresolved_deltas's recursion.
Thanks. I missed that function. Will try to fix it.
--
Duy
^ permalink raw reply
* [PATCH 0/2] Parsing a subcommand using parse-options
From: Ramkumar Ramachandra @ 2011-12-08 12:07 UTC (permalink / raw)
To: Git List; +Cc: Junio C Hamano
Hi,
It's been itching me for some time now: I want parse-options to be
able to parse a "subcommand". It all started when I noticed how ugly
my implementation of '--continue' and '--quit' in git-revert were:
using an OPT_BOOLEAN to parse the option into separate integer
variables, and then using if-else constructs to turn that into an
enum. Yuck! Also, wouldn't we all love something like this in the
future?
git stash show
^^ -- The subcommand "show" to the git-stash builtin
Ofcourse, git-stash.sh is just a shell script, and the full motivation
doesn't arise until someone decides to turn it into a C builtin. So,
I went hunting for a C builtin that used subcommands and found
something relatively obscure: git-bundle. It does option-parsing by
hand; changing it to use parse-options is the perfect opportunity to
implement this subcommand feature!
Thoughts?
-- Ram
Ramkumar Ramachandra (2):
parse-options: introduce OPT_SUBCOMMAND
bundle: rewrite builtin to use parse-options
builtin/bundle.c | 111 ++++++++++++++++++++++++++++++----------------
parse-options.c | 5 +-
parse-options.h | 3 +
t/t0040-parse-options.sh | 31 +++++++++++++
test-parse-options.c | 4 ++
5 files changed, 114 insertions(+), 40 deletions(-)
--
1.7.7.3
^ permalink raw reply
* [PATCH 1/2] parse-options: introduce OPT_SUBCOMMAND
From: Ramkumar Ramachandra @ 2011-12-08 12:07 UTC (permalink / raw)
To: Git List; +Cc: Junio C Hamano
In-Reply-To: <1323346028-9201-1-git-send-email-artagnon@gmail.com>
Several git programs take long dash-less options on the command-line
to indicate different modes of operation like:
git stash show
git bundle verify test.bundle
git bisect start
Currently, the parse-options framework forbids the use of
opts->long_name and OPT_PARSE_NODASH, and the parsing has to be done
by hand as a result. Lift this restriction, and create a new
OPT_SUBCOMMAND; this is built on top of OPTION_BIT to allow for the
detection of more than one subcommand.
Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>
---
parse-options.c | 5 +++--
parse-options.h | 3 +++
t/t0040-parse-options.sh | 31 +++++++++++++++++++++++++++++++
test-parse-options.c | 4 ++++
4 files changed, 41 insertions(+), 2 deletions(-)
diff --git a/parse-options.c b/parse-options.c
index f0098eb..079616a 100644
--- a/parse-options.c
+++ b/parse-options.c
@@ -278,6 +278,8 @@ static int parse_nodash_opt(struct parse_opt_ctx_t *p, const char *arg,
continue;
if (options->short_name == arg[0] && arg[1] == '\0')
return get_value(p, options, OPT_SHORT);
+ if (options->long_name && !strcmp(options->long_name, arg))
+ return get_value(p, options, OPT_SHORT);
}
return -2;
}
@@ -314,8 +316,7 @@ static void parse_options_check(const struct option *opts)
if (opts->flags & PARSE_OPT_NODASH &&
((opts->flags & PARSE_OPT_OPTARG) ||
!(opts->flags & PARSE_OPT_NOARG) ||
- !(opts->flags & PARSE_OPT_NONEG) ||
- opts->long_name))
+ !(opts->flags & PARSE_OPT_NONEG)))
err |= optbug(opts, "uses feature "
"not supported for dashless options");
switch (opts->type) {
diff --git a/parse-options.h b/parse-options.h
index 2e811dc..9267d46 100644
--- a/parse-options.h
+++ b/parse-options.h
@@ -123,6 +123,9 @@ struct option {
#define OPT_GROUP(h) { OPTION_GROUP, 0, NULL, NULL, NULL, (h) }
#define OPT_BIT(s, l, v, h, b) { OPTION_BIT, (s), (l), (v), NULL, (h), \
PARSE_OPT_NOARG, NULL, (b) }
+#define OPT_SUBCOMMAND(l, v, h, i) { OPTION_BIT, 0, (l), (v), NULL, (h), \
+ PARSE_OPT_NONEG | PARSE_OPT_NOARG | \
+ PARSE_OPT_NODASH | PARSE_OPT_HIDDEN, NULL, (i) }
#define OPT_NEGBIT(s, l, v, h, b) { OPTION_NEGBIT, (s), (l), (v), NULL, \
(h), PARSE_OPT_NOARG, NULL, (b) }
#define OPT_COUNTUP(s, l, v, h) { OPTION_COUNTUP, (s), (l), (v), NULL, \
diff --git a/t/t0040-parse-options.sh b/t/t0040-parse-options.sh
index a1e4616..47a402e 100755
--- a/t/t0040-parse-options.sh
+++ b/t/t0040-parse-options.sh
@@ -55,6 +55,7 @@ mv expect expect.err
cat > expect << EOF
boolean: 2
+subcommand: 0
integer: 1729
timestamp: 0
string: 123
@@ -74,6 +75,7 @@ test_expect_success 'short options' '
cat > expect << EOF
boolean: 2
+subcommand: 0
integer: 1729
timestamp: 0
string: 321
@@ -103,6 +105,7 @@ test_expect_success 'missing required value' '
cat > expect << EOF
boolean: 1
+subcommand: 0
integer: 13
timestamp: 0
string: 123
@@ -125,6 +128,7 @@ test_expect_success 'intermingled arguments' '
cat > expect << EOF
boolean: 0
+subcommand: 0
integer: 2
timestamp: 0
string: (not set)
@@ -154,6 +158,7 @@ test_expect_success 'ambiguously abbreviated option' '
cat > expect << EOF
boolean: 0
+subcommand: 0
integer: 0
timestamp: 0
string: 123
@@ -182,6 +187,7 @@ test_expect_success 'detect possible typos' '
cat > expect <<EOF
boolean: 0
+subcommand: 0
integer: 0
timestamp: 0
string: (not set)
@@ -201,6 +207,7 @@ test_expect_success 'keep some options as arguments' '
cat > expect <<EOF
boolean: 0
+subcommand: 0
integer: 0
timestamp: 1
string: default
@@ -222,6 +229,7 @@ test_expect_success 'OPT_DATE() and OPT_SET_PTR() work' '
cat > expect <<EOF
Callback: "four", 0
boolean: 5
+subcommand: 0
integer: 4
timestamp: 0
string: (not set)
@@ -250,6 +258,7 @@ test_expect_success 'OPT_CALLBACK() and callback errors work' '
cat > expect <<EOF
boolean: 1
+subcommand: 0
integer: 23
timestamp: 0
string: (not set)
@@ -274,6 +283,7 @@ test_expect_success 'OPT_NEGBIT() and OPT_SET_INT() work' '
cat > expect <<EOF
boolean: 6
+subcommand: 0
integer: 0
timestamp: 0
string: (not set)
@@ -304,6 +314,26 @@ test_expect_success 'OPT_BOOLEAN() with PARSE_OPT_NODASH works' '
cat > expect <<EOF
boolean: 0
+subcommand: 4
+integer: 0
+timestamp: 0
+string: (not set)
+abbrev: 7
+verbose: 0
+quiet: no
+dry run: no
+file: (not set)
+EOF
+
+test_expect_success 'OPT_SUBCOMMAND() works' '
+ test-parse-options sub4 > output 2> output.err &&
+ test ! -s output.err &&
+ test_cmp expect output
+'
+
+cat > expect <<EOF
+boolean: 0
+subcommand: 0
integer: 12345
timestamp: 0
string: (not set)
@@ -322,6 +352,7 @@ test_expect_success 'OPT_NUMBER_CALLBACK() works' '
cat >expect <<EOF
boolean: 0
+subcommand: 0
integer: 0
timestamp: 0
string: (not set)
diff --git a/test-parse-options.c b/test-parse-options.c
index 36487c4..8d5fcd4 100644
--- a/test-parse-options.c
+++ b/test-parse-options.c
@@ -3,6 +3,7 @@
#include "string-list.h"
static int boolean = 0;
+static int subcommand = 0;
static int integer = 0;
static unsigned long timestamp;
static int abbrev = 7;
@@ -40,6 +41,8 @@ int main(int argc, const char **argv)
OPT_BOOLEAN('b', "boolean", &boolean, "get a boolean"),
OPT_BIT('4', "or4", &boolean,
"bitwise-or boolean with ...0100", 4),
+ OPT_SUBCOMMAND("sub4", &subcommand,
+ "bitwise-or subcommand with ...0100", 4),
OPT_NEGBIT(0, "neg-or4", &boolean, "same as --no-or4", 4),
OPT_GROUP(""),
OPT_INTEGER('i', "integer", &integer, "get a integer"),
@@ -80,6 +83,7 @@ int main(int argc, const char **argv)
argc = parse_options(argc, argv, prefix, options, usage, 0);
printf("boolean: %d\n", boolean);
+ printf("subcommand: %d\n", subcommand);
printf("integer: %u\n", integer);
printf("timestamp: %lu\n", timestamp);
printf("string: %s\n", string ? string : "(not set)");
--
1.7.7.3
^ permalink raw reply related
* [PATCH 2/2] bundle: rewrite builtin to use parse-options
From: Ramkumar Ramachandra @ 2011-12-08 12:07 UTC (permalink / raw)
To: Git List; +Cc: Junio C Hamano
In-Reply-To: <1323346028-9201-1-git-send-email-artagnon@gmail.com>
The git-bundle builtin currently parses command-line options by hand;
this is both fragile and cryptic on failure. Since we now have an
OPT_SUBCOMMAND, make use of it to parse the correct subcommand, while
forbidding the use of more than one subcommand in the same invocation.
Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>
---
builtin/bundle.c | 111 +++++++++++++++++++++++++++++++++++------------------
1 files changed, 73 insertions(+), 38 deletions(-)
diff --git a/builtin/bundle.c b/builtin/bundle.c
index 92a8a60..c977d9f 100644
--- a/builtin/bundle.c
+++ b/builtin/bundle.c
@@ -1,5 +1,6 @@
#include "builtin.h"
#include "cache.h"
+#include "parse-options.h"
#include "bundle.h"
/*
@@ -9,57 +10,91 @@
* bundle supporting "fetch", "pull", and "ls-remote".
*/
-static const char builtin_bundle_usage[] =
- "git bundle create <file> <git-rev-list args>\n"
- " or: git bundle verify <file>\n"
- " or: git bundle list-heads <file> [<refname>...]\n"
- " or: git bundle unbundle <file> [<refname>...]";
+static const char * builtin_bundle_usage[] = {
+ "git bundle create <file> <git-rev-list args>",
+ "git bundle verify <file>",
+ "git bundle list-heads <file> [<refname>...]",
+ "git bundle unbundle <file> [<refname>...]",
+ NULL
+};
+
+enum bundle_subcommand {
+ BUNDLE_NONE = 0,
+ BUNDLE_CREATE = 1,
+ BUNDLE_VERIFY = 2,
+ BUNDLE_LIST_HEADS = 4,
+ BUNDLE_UNBUNDLE = 8
+};
int cmd_bundle(int argc, const char **argv, const char *prefix)
{
- struct bundle_header header;
- const char *cmd, *bundle_file;
+ int prefix_length;
int bundle_fd = -1;
- char buffer[PATH_MAX];
+ const char *bundle_file;
+ struct bundle_header header;
+ enum bundle_subcommand subcommand = BUNDLE_NONE;
- if (argc < 3)
- usage(builtin_bundle_usage);
+ struct option options[] = {
+ OPT_SUBCOMMAND("create", &subcommand,
+ "create a new bundle",
+ BUNDLE_CREATE),
+ OPT_SUBCOMMAND("verify", &subcommand,
+ "verify clean application of the bundle",
+ BUNDLE_VERIFY),
+ OPT_SUBCOMMAND("list-heads", &subcommand,
+ "list references defined in the bundle",
+ BUNDLE_LIST_HEADS),
+ OPT_SUBCOMMAND("unbundle", &subcommand,
+ "pass objects in the bundle to 'git index-pack'",
+ BUNDLE_UNBUNDLE),
+ OPT_END(),
+ };
- cmd = argv[1];
- bundle_file = argv[2];
- argc -= 2;
- argv += 2;
+ argc = parse_options(argc, argv, NULL,
+ options, builtin_bundle_usage,
+ PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN);
- if (prefix && bundle_file[0] != '/') {
- snprintf(buffer, sizeof(buffer), "%s/%s", prefix, bundle_file);
- bundle_file = buffer;
- }
+ if (argc < 2)
+ usage_with_options(builtin_bundle_usage, options);
- memset(&header, 0, sizeof(header));
- if (strcmp(cmd, "create") && (bundle_fd =
- read_bundle_header(bundle_file, &header)) < 0)
- return 1;
+ /* The next parameter on the command line is bundle_file */
+ prefix_length = prefix ? strlen(prefix) : 0;
+ bundle_file = prefix_filename(prefix, prefix_length, argv[1]);
+ argc -= 1;
+ argv += 1;
- if (!strcmp(cmd, "verify")) {
+ /* Read out bundle header, except in BUNDLE_CREATE case */
+ if (subcommand == BUNDLE_VERIFY || subcommand == BUNDLE_LIST_HEADS ||
+ subcommand == BUNDLE_UNBUNDLE) {
+ memset(&header, 0, sizeof(header));
+ bundle_fd = read_bundle_header(bundle_file, &header);
+ if (bundle_fd < 0)
+ die_errno(_("Failed to open bundle file '%s'"), bundle_file);
+ }
+
+ switch (subcommand) {
+ case BUNDLE_CREATE:
+ if (!startup_info->have_repository)
+ die(_("Need a repository to create a bundle."));
+ return create_bundle(&header, bundle_file, argc, argv);
+ case BUNDLE_VERIFY:
close(bundle_fd);
if (verify_bundle(&header, 1))
- return 1;
+ return -1; /* Error already reported */
fprintf(stderr, _("%s is okay\n"), bundle_file);
- return 0;
- }
- if (!strcmp(cmd, "list-heads")) {
+ break;
+ case BUNDLE_LIST_HEADS:
close(bundle_fd);
- return !!list_bundle_refs(&header, argc, argv);
- }
- if (!strcmp(cmd, "create")) {
- if (!startup_info->have_repository)
- die(_("Need a repository to create a bundle."));
- return !!create_bundle(&header, bundle_file, argc, argv);
- } else if (!strcmp(cmd, "unbundle")) {
- if (!startup_info->have_repository)
+ return list_bundle_refs(&header, argc, argv);
+ case BUNDLE_UNBUNDLE:
+ if (!startup_info->have_repository) {
+ close(bundle_fd);
die(_("Need a repository to unbundle."));
- return !!unbundle(&header, bundle_fd, 0) ||
+ }
+ return unbundle(&header, bundle_fd, 0) ||
list_bundle_refs(&header, argc, argv);
- } else
- usage(builtin_bundle_usage);
+ default:
+ usage_with_options(builtin_bundle_usage, options);
+ }
+ return 0;
}
--
1.7.7.3
^ permalink raw reply related
* Re: [PATCH 15/15] t3040 (subprojects-basic): modernize style
From: Ramkumar Ramachandra @ 2011-12-08 13:04 UTC (permalink / raw)
To: Jonathan Nieder; +Cc: Junio C Hamano, Git List
In-Reply-To: <20111207222126.GF2911@elie.hsd1.il.comcast.net>
Hi,
Jonathan Nieder wrote:
> It would be easier to read if each preimage test assertion were next to
> the corresponding postimage test assertion. Does "git diff --patience"
> do better?
No, unfortunately.
> If cleaning up the style anyway, I would write this as
> [...]
> But leaving it alone like you did is probably better. ;-)
Exercising restraint. Otherwise, I'm tempted to fix every little nit
in every test I'm touching in the series :P
>> -test_expect_success 'check if fsck ignores the subprojects' \
>> - 'git fsck --full'
>> +test_expect_success 'check if fsck ignores the subprojects' '
>> + git fsck --full
>> +'
>
> Does this test imply that one of the subprojects is broken somehow?
Hm, you're right- the test doesn't seem to make any sense. I'll deal
with it in another patch (unrelated to this series).
Thanks.
-- Ram
^ permalink raw reply
* [PATCH v2 0/6] Fix '&&' chaining in tests
From: Ramkumar Ramachandra @ 2011-12-08 13:10 UTC (permalink / raw)
To: Jonathan Nieder; +Cc: Junio C Hamano, Matthieu Moy, Git List
Hi,
This follows-up $gmane/186481. Thanks to Jonathan and Matthieu for
going through it. Changes are:
1. Changes in response to Jonathan's review.
2. Squash similar patches and re-order.
Thanks.
-- Ram
Ramkumar Ramachandra (6):
t3040 (subprojects-basic): modernize style
t3030 (merge-recursive): use test_expect_code
t1006 (cat-file): use test_cmp
t3200 (branch): fix '&&' chaining
t1510 (worktree): fix '&&' chaining
test: fix '&&' chaining
t/t1006-cat-file.sh | 119 +++++++++++++--------------
t/t1007-hash-object.sh | 2 +-
t/t1013-loose-object-format.sh | 2 +-
t/t1300-repo-config.sh | 2 +-
t/t1412-reflog-loop.sh | 2 +-
t/t1501-worktree.sh | 6 +-
t/t1510-repo-setup.sh | 4 +-
t/t1511-rev-parse-caret.sh | 2 +-
t/t3030-merge-recursive.sh | 72 ++---------------
t/t3040-subprojects-basic.sh | 144 ++++++++++++++++----------------
t/t3200-branch.sh | 4 +-
t/t3310-notes-merge-manual-resolve.sh | 10 +-
t/t3400-rebase.sh | 4 +-
t/t3418-rebase-continue.sh | 4 +-
t/t3419-rebase-patch-id.sh | 2 +-
15 files changed, 156 insertions(+), 223 deletions(-)
--
1.7.7.3
^ permalink raw reply
* [PATCH 1/2] parse-options: introduce OPT_SUBCOMMAND
From: Ramkumar Ramachandra @ 2011-12-08 13:10 UTC (permalink / raw)
To: Jonathan Nieder; +Cc: Junio C Hamano, Matthieu Moy, Git List
In-Reply-To: <1323349817-15737-1-git-send-email-artagnon@gmail.com>
Several git programs take long dash-less options on the command-line
to indicate different modes of operation like:
git stash show
git bundle verify test.bundle
git bisect start
Currently, the parse-options framework forbids the use of
opts->long_name and OPT_PARSE_NODASH, and the parsing has to be done
by hand as a result. Lift this restriction, and create a new
OPT_SUBCOMMAND; this is built on top of OPTION_BIT to allow for the
detection of more than one subcommand.
Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>
---
parse-options.c | 5 +++--
parse-options.h | 3 +++
t/t0040-parse-options.sh | 31 +++++++++++++++++++++++++++++++
test-parse-options.c | 4 ++++
4 files changed, 41 insertions(+), 2 deletions(-)
diff --git a/parse-options.c b/parse-options.c
index f0098eb..079616a 100644
--- a/parse-options.c
+++ b/parse-options.c
@@ -278,6 +278,8 @@ static int parse_nodash_opt(struct parse_opt_ctx_t *p, const char *arg,
continue;
if (options->short_name == arg[0] && arg[1] == '\0')
return get_value(p, options, OPT_SHORT);
+ if (options->long_name && !strcmp(options->long_name, arg))
+ return get_value(p, options, OPT_SHORT);
}
return -2;
}
@@ -314,8 +316,7 @@ static void parse_options_check(const struct option *opts)
if (opts->flags & PARSE_OPT_NODASH &&
((opts->flags & PARSE_OPT_OPTARG) ||
!(opts->flags & PARSE_OPT_NOARG) ||
- !(opts->flags & PARSE_OPT_NONEG) ||
- opts->long_name))
+ !(opts->flags & PARSE_OPT_NONEG)))
err |= optbug(opts, "uses feature "
"not supported for dashless options");
switch (opts->type) {
diff --git a/parse-options.h b/parse-options.h
index 2e811dc..9267d46 100644
--- a/parse-options.h
+++ b/parse-options.h
@@ -123,6 +123,9 @@ struct option {
#define OPT_GROUP(h) { OPTION_GROUP, 0, NULL, NULL, NULL, (h) }
#define OPT_BIT(s, l, v, h, b) { OPTION_BIT, (s), (l), (v), NULL, (h), \
PARSE_OPT_NOARG, NULL, (b) }
+#define OPT_SUBCOMMAND(l, v, h, i) { OPTION_BIT, 0, (l), (v), NULL, (h), \
+ PARSE_OPT_NONEG | PARSE_OPT_NOARG | \
+ PARSE_OPT_NODASH | PARSE_OPT_HIDDEN, NULL, (i) }
#define OPT_NEGBIT(s, l, v, h, b) { OPTION_NEGBIT, (s), (l), (v), NULL, \
(h), PARSE_OPT_NOARG, NULL, (b) }
#define OPT_COUNTUP(s, l, v, h) { OPTION_COUNTUP, (s), (l), (v), NULL, \
diff --git a/t/t0040-parse-options.sh b/t/t0040-parse-options.sh
index a1e4616..47a402e 100755
--- a/t/t0040-parse-options.sh
+++ b/t/t0040-parse-options.sh
@@ -55,6 +55,7 @@ mv expect expect.err
cat > expect << EOF
boolean: 2
+subcommand: 0
integer: 1729
timestamp: 0
string: 123
@@ -74,6 +75,7 @@ test_expect_success 'short options' '
cat > expect << EOF
boolean: 2
+subcommand: 0
integer: 1729
timestamp: 0
string: 321
@@ -103,6 +105,7 @@ test_expect_success 'missing required value' '
cat > expect << EOF
boolean: 1
+subcommand: 0
integer: 13
timestamp: 0
string: 123
@@ -125,6 +128,7 @@ test_expect_success 'intermingled arguments' '
cat > expect << EOF
boolean: 0
+subcommand: 0
integer: 2
timestamp: 0
string: (not set)
@@ -154,6 +158,7 @@ test_expect_success 'ambiguously abbreviated option' '
cat > expect << EOF
boolean: 0
+subcommand: 0
integer: 0
timestamp: 0
string: 123
@@ -182,6 +187,7 @@ test_expect_success 'detect possible typos' '
cat > expect <<EOF
boolean: 0
+subcommand: 0
integer: 0
timestamp: 0
string: (not set)
@@ -201,6 +207,7 @@ test_expect_success 'keep some options as arguments' '
cat > expect <<EOF
boolean: 0
+subcommand: 0
integer: 0
timestamp: 1
string: default
@@ -222,6 +229,7 @@ test_expect_success 'OPT_DATE() and OPT_SET_PTR() work' '
cat > expect <<EOF
Callback: "four", 0
boolean: 5
+subcommand: 0
integer: 4
timestamp: 0
string: (not set)
@@ -250,6 +258,7 @@ test_expect_success 'OPT_CALLBACK() and callback errors work' '
cat > expect <<EOF
boolean: 1
+subcommand: 0
integer: 23
timestamp: 0
string: (not set)
@@ -274,6 +283,7 @@ test_expect_success 'OPT_NEGBIT() and OPT_SET_INT() work' '
cat > expect <<EOF
boolean: 6
+subcommand: 0
integer: 0
timestamp: 0
string: (not set)
@@ -304,6 +314,26 @@ test_expect_success 'OPT_BOOLEAN() with PARSE_OPT_NODASH works' '
cat > expect <<EOF
boolean: 0
+subcommand: 4
+integer: 0
+timestamp: 0
+string: (not set)
+abbrev: 7
+verbose: 0
+quiet: no
+dry run: no
+file: (not set)
+EOF
+
+test_expect_success 'OPT_SUBCOMMAND() works' '
+ test-parse-options sub4 > output 2> output.err &&
+ test ! -s output.err &&
+ test_cmp expect output
+'
+
+cat > expect <<EOF
+boolean: 0
+subcommand: 0
integer: 12345
timestamp: 0
string: (not set)
@@ -322,6 +352,7 @@ test_expect_success 'OPT_NUMBER_CALLBACK() works' '
cat >expect <<EOF
boolean: 0
+subcommand: 0
integer: 0
timestamp: 0
string: (not set)
diff --git a/test-parse-options.c b/test-parse-options.c
index 36487c4..8d5fcd4 100644
--- a/test-parse-options.c
+++ b/test-parse-options.c
@@ -3,6 +3,7 @@
#include "string-list.h"
static int boolean = 0;
+static int subcommand = 0;
static int integer = 0;
static unsigned long timestamp;
static int abbrev = 7;
@@ -40,6 +41,8 @@ int main(int argc, const char **argv)
OPT_BOOLEAN('b', "boolean", &boolean, "get a boolean"),
OPT_BIT('4', "or4", &boolean,
"bitwise-or boolean with ...0100", 4),
+ OPT_SUBCOMMAND("sub4", &subcommand,
+ "bitwise-or subcommand with ...0100", 4),
OPT_NEGBIT(0, "neg-or4", &boolean, "same as --no-or4", 4),
OPT_GROUP(""),
OPT_INTEGER('i', "integer", &integer, "get a integer"),
@@ -80,6 +83,7 @@ int main(int argc, const char **argv)
argc = parse_options(argc, argv, prefix, options, usage, 0);
printf("boolean: %d\n", boolean);
+ printf("subcommand: %d\n", subcommand);
printf("integer: %u\n", integer);
printf("timestamp: %lu\n", timestamp);
printf("string: %s\n", string ? string : "(not set)");
--
1.7.7.3
^ permalink raw reply related
* [PATCH 1/6] t3040 (subprojects-basic): modernize style
From: Ramkumar Ramachandra @ 2011-12-08 13:10 UTC (permalink / raw)
To: Jonathan Nieder; +Cc: Junio C Hamano, Matthieu Moy, Git List
In-Reply-To: <1323349817-15737-1-git-send-email-artagnon@gmail.com>
Put the opening quote starting each test on the same line as the
test_expect_* invocation. While at it:
- Indent the file with tabs, not spaces.
- Guard commands that prepare test input for individual tests in the
same test_expect_success, so that their scope is clearer and errors
at that stage can be caught.
- Use <<-\EOF in preference to <<EOF to save readers the trouble of
looking for variable interpolations.
- Include "setup" in the titles of test assertions that prepare for
later ones to make it more obvious which tests can be skipped.
- Chain commands with &&. Breaks in a test assertion's && chain can
potentially hide failures from earlier commands in the chain.
- Use test_expect_code() in preference to checking the exit status of
various statements by hand.
Helped-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>
---
t/t3040-subprojects-basic.sh | 144 +++++++++++++++++++++---------------------
1 files changed, 72 insertions(+), 72 deletions(-)
diff --git a/t/t3040-subprojects-basic.sh b/t/t3040-subprojects-basic.sh
index f6973e9..0a4ff6d 100755
--- a/t/t3040-subprojects-basic.sh
+++ b/t/t3040-subprojects-basic.sh
@@ -3,81 +3,81 @@
test_description='Basic subproject functionality'
. ./test-lib.sh
-test_expect_success 'Super project creation' \
- ': >Makefile &&
- git add Makefile &&
- git commit -m "Superproject created"'
-
-
-cat >expected <<EOF
-:000000 160000 00000... A sub1
-:000000 160000 00000... A sub2
-EOF
-test_expect_success 'create subprojects' \
- 'mkdir sub1 &&
- ( cd sub1 && git init && : >Makefile && git add * &&
- git commit -q -m "subproject 1" ) &&
- mkdir sub2 &&
- ( cd sub2 && git init && : >Makefile && git add * &&
- git commit -q -m "subproject 2" ) &&
- git update-index --add sub1 &&
- git add sub2 &&
- git commit -q -m "subprojects added" &&
- git diff-tree --abbrev=5 HEAD^ HEAD |cut -d" " -f-3,5- >current &&
- test_cmp expected current'
-
-git branch save HEAD
-
-test_expect_success 'check if fsck ignores the subprojects' \
- 'git fsck --full'
-
-test_expect_success 'check if commit in a subproject detected' \
- '( cd sub1 &&
- echo "all:" >>Makefile &&
- echo " true" >>Makefile &&
- git commit -q -a -m "make all" ) && {
- git diff-files --exit-code
- test $? = 1
- }'
-
-test_expect_success 'check if a changed subproject HEAD can be committed' \
- 'git commit -q -a -m "sub1 changed" && {
- git diff-tree --exit-code HEAD^ HEAD
- test $? = 1
- }'
-
-test_expect_success 'check if diff-index works for subproject elements' \
- 'git diff-index --exit-code --cached save -- sub1
- test $? = 1'
-
-test_expect_success 'check if diff-tree works for subproject elements' \
- 'git diff-tree --exit-code HEAD^ HEAD -- sub1
- test $? = 1'
-
-test_expect_success 'check if git diff works for subproject elements' \
- 'git diff --exit-code HEAD^ HEAD
- test $? = 1'
-
-test_expect_success 'check if clone works' \
- 'git ls-files -s >expected &&
- git clone -l -s . cloned &&
- ( cd cloned && git ls-files -s ) >current &&
- test_cmp expected current'
-
-test_expect_success 'removing and adding subproject' \
- 'git update-index --force-remove -- sub2 &&
- mv sub2 sub3 &&
- git add sub3 &&
- git commit -q -m "renaming a subproject" && {
- git diff -M --name-status --exit-code HEAD^ HEAD
- test $? = 1
- }'
+test_expect_success 'setup: create superproject' '
+ : >Makefile &&
+ git add Makefile &&
+ git commit -m "Superproject created"
+'
+
+test_expect_success 'setup: create subprojects' '
+ mkdir sub1 &&
+ ( cd sub1 && git init && : >Makefile && git add * &&
+ git commit -q -m "subproject 1" ) &&
+ mkdir sub2 &&
+ ( cd sub2 && git init && : >Makefile && git add * &&
+ git commit -q -m "subproject 2" ) &&
+ git update-index --add sub1 &&
+ git add sub2 &&
+ git commit -q -m "subprojects added" &&
+ git diff-tree --abbrev=5 HEAD^ HEAD |cut -d" " -f-3,5- >current &&
+ git branch save HEAD &&
+ cat >expected <<-\EOF &&
+ :000000 160000 00000... A sub1
+ :000000 160000 00000... A sub2
+ EOF
+ test_cmp expected current
+'
+
+test_expect_success 'check if fsck ignores the subprojects' '
+ git fsck --full
+'
+
+test_expect_success 'check if commit in a subproject detected' '
+ ( cd sub1 &&
+ echo "all:" >>Makefile &&
+ echo " true" >>Makefile &&
+ git commit -q -a -m "make all" ) &&
+ test_expect_code 1 git diff-files --exit-code
+'
+
+test_expect_success 'check if a changed subproject HEAD can be committed' '
+ git commit -q -a -m "sub1 changed" &&
+ test_expect_code 1 git diff-tree --exit-code HEAD^ HEAD
+'
+
+test_expect_success 'check if diff-index works for subproject elements' '
+ test_expect_code 1 git diff-index --exit-code --cached save -- sub1
+'
+
+test_expect_success 'check if diff-tree works for subproject elements' '
+ test_expect_code 1 git diff-tree --exit-code HEAD^ HEAD -- sub1
+'
+
+test_expect_success 'check if git diff works for subproject elements' '
+ test_expect_code 1 git diff --exit-code HEAD^ HEAD
+'
+
+test_expect_success 'check if clone works' '
+ git ls-files -s >expected &&
+ git clone -l -s . cloned &&
+ ( cd cloned && git ls-files -s ) >current &&
+ test_cmp expected current
+'
+
+test_expect_success 'removing and adding subproject' '
+ git update-index --force-remove -- sub2 &&
+ mv sub2 sub3 &&
+ git add sub3 &&
+ git commit -q -m "renaming a subproject" &&
+ test_expect_code 1 git diff -M --name-status --exit-code HEAD^ HEAD
+'
# the index must contain the object name the HEAD of the
# subproject sub1 was at the point "save"
-test_expect_success 'checkout in superproject' \
- 'git checkout save &&
- git diff-index --exit-code --raw --cached save -- sub1'
+test_expect_success 'checkout in superproject' '
+ git checkout save &&
+ git diff-index --exit-code --raw --cached save -- sub1
+'
# just interesting what happened...
# git diff --name-status -M save master
--
1.7.7.3
^ permalink raw reply related
* [PATCH 2/2] bundle: rewrite builtin to use parse-options
From: Ramkumar Ramachandra @ 2011-12-08 13:10 UTC (permalink / raw)
To: Jonathan Nieder; +Cc: Junio C Hamano, Matthieu Moy, Git List
In-Reply-To: <1323349817-15737-1-git-send-email-artagnon@gmail.com>
The git-bundle builtin currently parses command-line options by hand;
this is both fragile and cryptic on failure. Since we now have an
OPT_SUBCOMMAND, make use of it to parse the correct subcommand, while
forbidding the use of more than one subcommand in the same invocation.
Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>
---
builtin/bundle.c | 111 +++++++++++++++++++++++++++++++++++------------------
1 files changed, 73 insertions(+), 38 deletions(-)
diff --git a/builtin/bundle.c b/builtin/bundle.c
index 92a8a60..c977d9f 100644
--- a/builtin/bundle.c
+++ b/builtin/bundle.c
@@ -1,5 +1,6 @@
#include "builtin.h"
#include "cache.h"
+#include "parse-options.h"
#include "bundle.h"
/*
@@ -9,57 +10,91 @@
* bundle supporting "fetch", "pull", and "ls-remote".
*/
-static const char builtin_bundle_usage[] =
- "git bundle create <file> <git-rev-list args>\n"
- " or: git bundle verify <file>\n"
- " or: git bundle list-heads <file> [<refname>...]\n"
- " or: git bundle unbundle <file> [<refname>...]";
+static const char * builtin_bundle_usage[] = {
+ "git bundle create <file> <git-rev-list args>",
+ "git bundle verify <file>",
+ "git bundle list-heads <file> [<refname>...]",
+ "git bundle unbundle <file> [<refname>...]",
+ NULL
+};
+
+enum bundle_subcommand {
+ BUNDLE_NONE = 0,
+ BUNDLE_CREATE = 1,
+ BUNDLE_VERIFY = 2,
+ BUNDLE_LIST_HEADS = 4,
+ BUNDLE_UNBUNDLE = 8
+};
int cmd_bundle(int argc, const char **argv, const char *prefix)
{
- struct bundle_header header;
- const char *cmd, *bundle_file;
+ int prefix_length;
int bundle_fd = -1;
- char buffer[PATH_MAX];
+ const char *bundle_file;
+ struct bundle_header header;
+ enum bundle_subcommand subcommand = BUNDLE_NONE;
- if (argc < 3)
- usage(builtin_bundle_usage);
+ struct option options[] = {
+ OPT_SUBCOMMAND("create", &subcommand,
+ "create a new bundle",
+ BUNDLE_CREATE),
+ OPT_SUBCOMMAND("verify", &subcommand,
+ "verify clean application of the bundle",
+ BUNDLE_VERIFY),
+ OPT_SUBCOMMAND("list-heads", &subcommand,
+ "list references defined in the bundle",
+ BUNDLE_LIST_HEADS),
+ OPT_SUBCOMMAND("unbundle", &subcommand,
+ "pass objects in the bundle to 'git index-pack'",
+ BUNDLE_UNBUNDLE),
+ OPT_END(),
+ };
- cmd = argv[1];
- bundle_file = argv[2];
- argc -= 2;
- argv += 2;
+ argc = parse_options(argc, argv, NULL,
+ options, builtin_bundle_usage,
+ PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN);
- if (prefix && bundle_file[0] != '/') {
- snprintf(buffer, sizeof(buffer), "%s/%s", prefix, bundle_file);
- bundle_file = buffer;
- }
+ if (argc < 2)
+ usage_with_options(builtin_bundle_usage, options);
- memset(&header, 0, sizeof(header));
- if (strcmp(cmd, "create") && (bundle_fd =
- read_bundle_header(bundle_file, &header)) < 0)
- return 1;
+ /* The next parameter on the command line is bundle_file */
+ prefix_length = prefix ? strlen(prefix) : 0;
+ bundle_file = prefix_filename(prefix, prefix_length, argv[1]);
+ argc -= 1;
+ argv += 1;
- if (!strcmp(cmd, "verify")) {
+ /* Read out bundle header, except in BUNDLE_CREATE case */
+ if (subcommand == BUNDLE_VERIFY || subcommand == BUNDLE_LIST_HEADS ||
+ subcommand == BUNDLE_UNBUNDLE) {
+ memset(&header, 0, sizeof(header));
+ bundle_fd = read_bundle_header(bundle_file, &header);
+ if (bundle_fd < 0)
+ die_errno(_("Failed to open bundle file '%s'"), bundle_file);
+ }
+
+ switch (subcommand) {
+ case BUNDLE_CREATE:
+ if (!startup_info->have_repository)
+ die(_("Need a repository to create a bundle."));
+ return create_bundle(&header, bundle_file, argc, argv);
+ case BUNDLE_VERIFY:
close(bundle_fd);
if (verify_bundle(&header, 1))
- return 1;
+ return -1; /* Error already reported */
fprintf(stderr, _("%s is okay\n"), bundle_file);
- return 0;
- }
- if (!strcmp(cmd, "list-heads")) {
+ break;
+ case BUNDLE_LIST_HEADS:
close(bundle_fd);
- return !!list_bundle_refs(&header, argc, argv);
- }
- if (!strcmp(cmd, "create")) {
- if (!startup_info->have_repository)
- die(_("Need a repository to create a bundle."));
- return !!create_bundle(&header, bundle_file, argc, argv);
- } else if (!strcmp(cmd, "unbundle")) {
- if (!startup_info->have_repository)
+ return list_bundle_refs(&header, argc, argv);
+ case BUNDLE_UNBUNDLE:
+ if (!startup_info->have_repository) {
+ close(bundle_fd);
die(_("Need a repository to unbundle."));
- return !!unbundle(&header, bundle_fd, 0) ||
+ }
+ return unbundle(&header, bundle_fd, 0) ||
list_bundle_refs(&header, argc, argv);
- } else
- usage(builtin_bundle_usage);
+ default:
+ usage_with_options(builtin_bundle_usage, options);
+ }
+ return 0;
}
--
1.7.7.3
^ permalink raw reply related
* [PATCH 2/6] t3030 (merge-recursive): use test_expect_code
From: Ramkumar Ramachandra @ 2011-12-08 13:10 UTC (permalink / raw)
To: Jonathan Nieder; +Cc: Junio C Hamano, Matthieu Moy, Git List
In-Reply-To: <1323349817-15737-1-git-send-email-artagnon@gmail.com>
Use test_expect_code in preference to repeatedly checking exit codes
by hand.
Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>
---
t/t3030-merge-recursive.sh | 72 ++++----------------------------------------
1 files changed, 6 insertions(+), 66 deletions(-)
diff --git a/t/t3030-merge-recursive.sh b/t/t3030-merge-recursive.sh
index 55ef189..a5e3da7 100755
--- a/t/t3030-merge-recursive.sh
+++ b/t/t3030-merge-recursive.sh
@@ -285,17 +285,7 @@ test_expect_success 'merge-recursive simple' '
rm -fr [abcd] &&
git checkout -f "$c2" &&
- git merge-recursive "$c0" -- "$c2" "$c1"
- status=$?
- case "$status" in
- 1)
- : happy
- ;;
- *)
- echo >&2 "why status $status!!!"
- false
- ;;
- esac
+ test_expect_code 1 git merge-recursive "$c0" -- "$c2" "$c1"
'
test_expect_success 'merge-recursive result' '
@@ -334,17 +324,7 @@ test_expect_success 'merge-recursive remove conflict' '
rm -fr [abcd] &&
git checkout -f "$c1" &&
- git merge-recursive "$c0" -- "$c1" "$c5"
- status=$?
- case "$status" in
- 1)
- : happy
- ;;
- *)
- echo >&2 "why status $status!!!"
- false
- ;;
- esac
+ test_expect_code 1 git merge-recursive "$c0" -- "$c1" "$c5"
'
test_expect_success 'merge-recursive remove conflict' '
@@ -388,17 +368,7 @@ test_expect_success 'merge-recursive d/f conflict' '
git reset --hard &&
git checkout -f "$c1" &&
- git merge-recursive "$c0" -- "$c1" "$c4"
- status=$?
- case "$status" in
- 1)
- : happy
- ;;
- *)
- echo >&2 "why status $status!!!"
- false
- ;;
- esac
+ test_expect_code 1 git merge-recursive "$c0" -- "$c1" "$c4"
'
test_expect_success 'merge-recursive d/f conflict result' '
@@ -422,17 +392,7 @@ test_expect_success 'merge-recursive d/f conflict the other way' '
git reset --hard &&
git checkout -f "$c4" &&
- git merge-recursive "$c0" -- "$c4" "$c1"
- status=$?
- case "$status" in
- 1)
- : happy
- ;;
- *)
- echo >&2 "why status $status!!!"
- false
- ;;
- esac
+ test_expect_code 1 git merge-recursive "$c0" -- "$c4" "$c1"
'
test_expect_success 'merge-recursive d/f conflict result the other way' '
@@ -456,17 +416,7 @@ test_expect_success 'merge-recursive d/f conflict' '
git reset --hard &&
git checkout -f "$c1" &&
- git merge-recursive "$c0" -- "$c1" "$c6"
- status=$?
- case "$status" in
- 1)
- : happy
- ;;
- *)
- echo >&2 "why status $status!!!"
- false
- ;;
- esac
+ test_expect_code 1 git merge-recursive "$c0" -- "$c1" "$c6"
'
test_expect_success 'merge-recursive d/f conflict result' '
@@ -490,17 +440,7 @@ test_expect_success 'merge-recursive d/f conflict' '
git reset --hard &&
git checkout -f "$c6" &&
- git merge-recursive "$c0" -- "$c6" "$c1"
- status=$?
- case "$status" in
- 1)
- : happy
- ;;
- *)
- echo >&2 "why status $status!!!"
- false
- ;;
- esac
+ test_expect_code 1 git merge-recursive "$c0" -- "$c6" "$c1"
'
test_expect_success 'merge-recursive d/f conflict result' '
--
1.7.7.3
^ permalink raw reply related
* [PATCH 4/6] t3200 (branch): fix '&&' chaining
From: Ramkumar Ramachandra @ 2011-12-08 13:10 UTC (permalink / raw)
To: Jonathan Nieder; +Cc: Junio C Hamano, Matthieu Moy, Git List
In-Reply-To: <1323349817-15737-1-git-send-email-artagnon@gmail.com>
Breaks in a test assertion's && chain can potentially hide failures
from earlier commands in the chain. Fix these breaks.
Additionally, note that 'git branch --help' will fail when git
manpages aren't already installed: guard the line with a
'test_might_fail'.
Helped-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>
---
t/t3200-branch.sh | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh
index bc73c20..95066d0 100755
--- a/t/t3200-branch.sh
+++ b/t/t3200-branch.sh
@@ -22,7 +22,7 @@ test_expect_success \
test_expect_success \
'git branch --help should not have created a bogus branch' '
- git branch --help </dev/null >/dev/null 2>/dev/null;
+ test_might_fail git branch --help </dev/null >/dev/null 2>/dev/null &&
test_path_is_missing .git/refs/heads/--help
'
@@ -88,7 +88,7 @@ test_expect_success \
test_expect_success \
'git branch -m n/n n should work' \
'git branch -l n/n &&
- git branch -m n/n n
+ git branch -m n/n n &&
test_path_is_file .git/logs/refs/heads/n'
test_expect_success 'git branch -m o/o o should fail when o/p exists' '
--
1.7.7.3
^ permalink raw reply related
* [PATCH 3/6] t1006 (cat-file): use test_cmp
From: Ramkumar Ramachandra @ 2011-12-08 13:10 UTC (permalink / raw)
To: Jonathan Nieder; +Cc: Junio C Hamano, Matthieu Moy, Git List
In-Reply-To: <1323349817-15737-1-git-send-email-artagnon@gmail.com>
Use test_cmp in preference to repeatedly comparing command outputs by
hand.
Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>
---
t/t1006-cat-file.sh | 119 ++++++++++++++++++++++++---------------------------
1 files changed, 56 insertions(+), 63 deletions(-)
diff --git a/t/t1006-cat-file.sh b/t/t1006-cat-file.sh
index d8b7f2f..0ca6c43 100755
--- a/t/t1006-cat-file.sh
+++ b/t/t1006-cat-file.sh
@@ -36,66 +36,41 @@ $content"
'
test_expect_success "Type of $type is correct" '
- test $type = "$(git cat-file -t $sha1)"
+ echo $type >expect &&
+ git cat-file -t $sha1 >actual &&
+ test_cmp expect actual
'
test_expect_success "Size of $type is correct" '
- test $size = "$(git cat-file -s $sha1)"
+ echo $size >expect &&
+ git cat-file -s $sha1 >actual &&
+ test_cmp expect actual
'
test -z "$content" ||
test_expect_success "Content of $type is correct" '
- expect="$(maybe_remove_timestamp "$content" $no_ts)"
- actual="$(maybe_remove_timestamp "$(git cat-file $type $sha1)" $no_ts)"
-
- if test "z$expect" = "z$actual"
- then
- : happy
- else
- echo "Oops: expected $expect"
- echo "but got $actual"
- false
- fi
+ maybe_remove_timestamp "$content" $no_ts >expect &&
+ maybe_remove_timestamp "$(git cat-file $type $sha1)" $no_ts >actual &&
+ test_cmp expect actual
'
test_expect_success "Pretty content of $type is correct" '
- expect="$(maybe_remove_timestamp "$pretty_content" $no_ts)"
- actual="$(maybe_remove_timestamp "$(git cat-file -p $sha1)" $no_ts)"
- if test "z$expect" = "z$actual"
- then
- : happy
- else
- echo "Oops: expected $expect"
- echo "but got $actual"
- false
- fi
+ maybe_remove_timestamp "$pretty_content" $no_ts >expect &&
+ maybe_remove_timestamp "$(git cat-file -p $sha1)" $no_ts >actual &&
+ test_cmp expect actual
'
test -z "$content" ||
test_expect_success "--batch output of $type is correct" '
- expect="$(maybe_remove_timestamp "$batch_output" $no_ts)"
- actual="$(maybe_remove_timestamp "$(echo $sha1 | git cat-file --batch)" $no_ts)"
- if test "z$expect" = "z$actual"
- then
- : happy
- else
- echo "Oops: expected $expect"
- echo "but got $actual"
- false
- fi
+ maybe_remove_timestamp "$batch_output" $no_ts >expect &&
+ maybe_remove_timestamp "$(echo $sha1 | git cat-file --batch)" $no_ts >actual &&
+ test_cmp expect actual
'
test_expect_success "--batch-check output of $type is correct" '
- expect="$sha1 $type $size"
- actual="$(echo_without_newline $sha1 | git cat-file --batch-check)"
- if test "z$expect" = "z$actual"
- then
- : happy
- else
- echo "Oops: expected $expect"
- echo "but got $actual"
- false
- fi
+ echo "$sha1 $type $size" >expect &&
+ echo_without_newline $sha1 | git cat-file --batch-check >actual &&
+ test_cmp expect actual
'
}
@@ -144,10 +119,13 @@ tag_size=$(strlen "$tag_content")
run_tests 'tag' $tag_sha1 $tag_size "$tag_content" "$tag_pretty_content" 1
-test_expect_success \
- "Reach a blob from a tag pointing to it" \
- "test '$hello_content' = \"\$(git cat-file blob $tag_sha1)\""
+test_expect_success "Reach a blob from a tag pointing to it" '
+ echo_without_newline "$hello_content" >expect &&
+ git cat-file blob "$tag_sha1" >actual &&
+ test_cmp expect actual
+'
+test_done
for batch in batch batch-check
do
for opt in t s e p
@@ -175,30 +153,41 @@ do
done
test_expect_success "--batch-check for a non-existent named object" '
- test "foobar42 missing
-foobar84 missing" = \
- "$( ( echo foobar42; echo_without_newline foobar84; ) | git cat-file --batch-check)"
+ cat >expect <<\-EOF &&
+foobar42 missing
+foobar84 missing
+EOF
+ $(echo foobar42; echo_without_newline foobar84) \
+ | git cat-file --batch-check >actual &&
+ test_cmp expect actual
'
test_expect_success "--batch-check for a non-existent hash" '
- test "0000000000000000000000000000000000000042 missing
-0000000000000000000000000000000000000084 missing" = \
- "$( ( echo 0000000000000000000000000000000000000042;
- echo_without_newline 0000000000000000000000000000000000000084; ) \
- | git cat-file --batch-check)"
+ cat >expect <<\-EOF &&
+0000000000000000000000000000000000000042 missing
+0000000000000000000000000000000000000084 missing
+EOF
+ $(echo 0000000000000000000000000000000000000042;
+ echo_without_newline 0000000000000000000000000000000000000084) \
+ | git cat-file --batch-check >actual &&
+ test_cmp expect actual
'
test_expect_success "--batch for an existent and a non-existent hash" '
- test "$tag_sha1 tag $tag_size
+ cat >expect <<\-EOF &&
+tag_sha1 tag $tag_size
$tag_content
-0000000000000000000000000000000000000000 missing" = \
- "$( ( echo $tag_sha1;
- echo_without_newline 0000000000000000000000000000000000000000; ) \
- | git cat-file --batch)"
+0000000000000000000000000000000000000000 missing
+EOF
+ $(echo $tag_sha1; echo_without_newline 0000000000000000000000000000000000000000) \
+ | git cat-file --batch >actual &&
+ test_cmp expect_actual
'
test_expect_success "--batch-check for an emtpy line" '
- test " missing" = "$(echo | git cat-file --batch-check)"
+ echo " missing" >expect &&
+ echo | git cat-file --batch-check >actual &&
+ test_cmp expect actual
'
batch_input="$hello_sha1
@@ -218,7 +207,10 @@ deadbeef missing
missing"
test_expect_success '--batch with multiple sha1s gives correct format' '
- test "$(maybe_remove_timestamp "$batch_output" 1)" = "$(maybe_remove_timestamp "$(echo_without_newline "$batch_input" | git cat-file --batch)" 1)"
+ maybe_remove_timestamp "$batch_output" 1 >expect &&
+ maybe_remove_timestamp "$(echo_without_newline "$batch_input" \
+ | git cat-file --batch)" 1 >actual &&
+ test_cmp expect actual
'
batch_check_input="$hello_sha1
@@ -237,8 +229,9 @@ deadbeef missing
missing"
test_expect_success "--batch-check with multiple sha1s gives correct format" '
- test "$batch_check_output" = \
- "$(echo_without_newline "$batch_check_input" | git cat-file --batch-check)"
+ echo "$batch_check_output" >expect &&
+ echo_without_newline "$batch_check_input" | git cat-file --batch-check >actual &&
+ test_cmp expect actual
'
test_done
--
1.7.7.3
^ permalink raw reply related
* [PATCH 6/6] test: fix '&&' chaining
From: Ramkumar Ramachandra @ 2011-12-08 13:10 UTC (permalink / raw)
To: Jonathan Nieder; +Cc: Junio C Hamano, Matthieu Moy, Git List
In-Reply-To: <1323349817-15737-1-git-send-email-artagnon@gmail.com>
Breaks in a test assertion's && chain can potentially hide failures
from earlier commands in the chain. Fix instances of this in the
following tests:
t3419 (rebase-patch-id)
t3310 (notes-merge-manual-resolve)
t3400 (rebase)
t3418 (rebase-continue)
t1511 (rev-parse-caret)
t1510 (repo-setup)
t1007 (hash-object)
t1412 (reflog-loop)
t1300 (repo-config)
t1013 (loose-object-format)
Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>
---
t/t1007-hash-object.sh | 2 +-
t/t1013-loose-object-format.sh | 2 +-
t/t1300-repo-config.sh | 2 +-
t/t1412-reflog-loop.sh | 2 +-
t/t1510-repo-setup.sh | 4 ++--
t/t1511-rev-parse-caret.sh | 2 +-
t/t3310-notes-merge-manual-resolve.sh | 10 +++++-----
t/t3400-rebase.sh | 4 ++--
t/t3418-rebase-continue.sh | 4 ++--
t/t3419-rebase-patch-id.sh | 2 +-
10 files changed, 17 insertions(+), 17 deletions(-)
diff --git a/t/t1007-hash-object.sh b/t/t1007-hash-object.sh
index 6d52b82..f83df8e 100755
--- a/t/t1007-hash-object.sh
+++ b/t/t1007-hash-object.sh
@@ -189,7 +189,7 @@ for args in "-w --stdin-paths" "--stdin-paths -w"; do
done
test_expect_success 'corrupt tree' '
- echo abc >malformed-tree
+ echo abc >malformed-tree &&
test_must_fail git hash-object -t tree malformed-tree
'
diff --git a/t/t1013-loose-object-format.sh b/t/t1013-loose-object-format.sh
index 0a9cedd..fbf5f2f 100755
--- a/t/t1013-loose-object-format.sh
+++ b/t/t1013-loose-object-format.sh
@@ -34,7 +34,7 @@ assert_blob_equals() {
}
test_expect_success setup '
- cp -R "$TEST_DIRECTORY/t1013/objects" .git/
+ cp -R "$TEST_DIRECTORY/t1013/objects" .git/ &&
git --version
'
diff --git a/t/t1300-repo-config.sh b/t/t1300-repo-config.sh
index 51caff0..0690e0e 100755
--- a/t/t1300-repo-config.sh
+++ b/t/t1300-repo-config.sh
@@ -38,7 +38,7 @@ cat > expect << EOF
WhatEver = Second
EOF
test_expect_success 'similar section' '
- git config Cores.WhatEver Second
+ git config Cores.WhatEver Second &&
test_cmp expect .git/config
'
diff --git a/t/t1412-reflog-loop.sh b/t/t1412-reflog-loop.sh
index 647d888..3acd895 100755
--- a/t/t1412-reflog-loop.sh
+++ b/t/t1412-reflog-loop.sh
@@ -20,7 +20,7 @@ test_expect_success 'setup reflog with alternating commits' '
'
test_expect_success 'reflog shows all entries' '
- cat >expect <<-\EOF
+ cat >expect <<-\EOF &&
topic@{0} reset: moving to two
topic@{1} reset: moving to one
topic@{2} reset: moving to two
diff --git a/t/t1510-repo-setup.sh b/t/t1510-repo-setup.sh
index ec50a9a..80aedfc 100755
--- a/t/t1510-repo-setup.sh
+++ b/t/t1510-repo-setup.sh
@@ -603,7 +603,7 @@ test_expect_success '#22a: core.worktree = GIT_DIR = .git dir' '
# like case #6.
setup_repo 22a "$here/22a/.git" "" unset &&
- setup_repo 22ab . "" unset
+ setup_repo 22ab . "" unset &&
mkdir -p 22a/.git/sub 22a/sub &&
mkdir -p 22ab/.git/sub 22ab/sub &&
try_case 22a/.git unset . \
@@ -742,7 +742,7 @@ test_expect_success '#28: core.worktree and core.bare conflict (gitfile case)' '
# Case #29: GIT_WORK_TREE(+core.worktree) overrides core.bare (gitfile case).
test_expect_success '#29: setup' '
setup_repo 29 non-existent gitfile true &&
- mkdir -p 29/sub/sub 29/wt/sub
+ mkdir -p 29/sub/sub 29/wt/sub &&
(
cd 29 &&
GIT_WORK_TREE="$here/29" &&
diff --git a/t/t1511-rev-parse-caret.sh b/t/t1511-rev-parse-caret.sh
index e043cb7..eaefc77 100755
--- a/t/t1511-rev-parse-caret.sh
+++ b/t/t1511-rev-parse-caret.sh
@@ -6,7 +6,7 @@ test_description='tests for ref^{stuff}'
test_expect_success 'setup' '
echo blob >a-blob &&
- git tag -a -m blob blob-tag `git hash-object -w a-blob`
+ git tag -a -m blob blob-tag `git hash-object -w a-blob` &&
mkdir a-tree &&
echo moreblobs >a-tree/another-blob &&
git add . &&
diff --git a/t/t3310-notes-merge-manual-resolve.sh b/t/t3310-notes-merge-manual-resolve.sh
index 4ec4d11..4367197 100755
--- a/t/t3310-notes-merge-manual-resolve.sh
+++ b/t/t3310-notes-merge-manual-resolve.sh
@@ -389,7 +389,7 @@ test_expect_success 'abort notes merge' '
test_must_fail ls .git/NOTES_MERGE_* >output 2>/dev/null &&
test_cmp /dev/null output &&
# m has not moved (still == y)
- test "$(git rev-parse refs/notes/m)" = "$(cat pre_merge_y)"
+ test "$(git rev-parse refs/notes/m)" = "$(cat pre_merge_y)" &&
# Verify that other notes refs has not changed (w, x, y and z)
verify_notes w &&
verify_notes x &&
@@ -525,9 +525,9 @@ EOF
test -f .git/NOTES_MERGE_WORKTREE/$commit_sha3 &&
test -f .git/NOTES_MERGE_WORKTREE/$commit_sha4 &&
# Refs are unchanged
- test "$(git rev-parse refs/notes/m)" = "$(git rev-parse refs/notes/w)"
- test "$(git rev-parse refs/notes/y)" = "$(git rev-parse NOTES_MERGE_PARTIAL^1)"
- test "$(git rev-parse refs/notes/m)" != "$(git rev-parse NOTES_MERGE_PARTIAL^1)"
+ test "$(git rev-parse refs/notes/m)" = "$(git rev-parse refs/notes/w)" &&
+ test "$(git rev-parse refs/notes/y)" = "$(git rev-parse NOTES_MERGE_PARTIAL^1)" &&
+ test "$(git rev-parse refs/notes/m)" != "$(git rev-parse NOTES_MERGE_PARTIAL^1)" &&
# Mention refs/notes/m, and its current and expected value in output
grep -q "refs/notes/m" output &&
grep -q "$(git rev-parse refs/notes/m)" output &&
@@ -545,7 +545,7 @@ test_expect_success 'resolve situation by aborting the notes merge' '
test_must_fail ls .git/NOTES_MERGE_* >output 2>/dev/null &&
test_cmp /dev/null output &&
# m has not moved (still == w)
- test "$(git rev-parse refs/notes/m)" = "$(git rev-parse refs/notes/w)"
+ test "$(git rev-parse refs/notes/m)" = "$(git rev-parse refs/notes/w)" &&
# Verify that other notes refs has not changed (w, x, y and z)
verify_notes w &&
verify_notes x &&
diff --git a/t/t3400-rebase.sh b/t/t3400-rebase.sh
index 6eaecec..c355533 100755
--- a/t/t3400-rebase.sh
+++ b/t/t3400-rebase.sh
@@ -172,8 +172,8 @@ test_expect_success 'fail when upstream arg is missing and not configured' '
test_expect_success 'default to @{upstream} when upstream arg is missing' '
git checkout -b default topic &&
- git config branch.default.remote .
- git config branch.default.merge refs/heads/master
+ git config branch.default.remote . &&
+ git config branch.default.merge refs/heads/master &&
git rebase &&
test "$(git rev-parse default~1)" = "$(git rev-parse master)"
'
diff --git a/t/t3418-rebase-continue.sh b/t/t3418-rebase-continue.sh
index 1e855cd..2680375 100755
--- a/t/t3418-rebase-continue.sh
+++ b/t/t3418-rebase-continue.sh
@@ -51,7 +51,7 @@ test_expect_success 'rebase --continue remembers merge strategy and options' '
test_commit "commit-new-file-F3-on-topic-branch" F3 32 &&
test_when_finished "rm -fr test-bin funny.was.run" &&
mkdir test-bin &&
- cat >test-bin/git-merge-funny <<-EOF
+ cat >test-bin/git-merge-funny <<-EOF &&
#!$SHELL_PATH
case "\$1" in --opt) ;; *) exit 2 ;; esac
shift &&
@@ -77,7 +77,7 @@ test_expect_success 'rebase --continue remembers merge strategy and options' '
test_expect_success 'rebase --continue remembers --rerere-autoupdate' '
rm -fr .git/rebase-* &&
git reset --hard commit-new-file-F3-on-topic-branch &&
- git checkout master
+ git checkout master &&
test_commit "commit-new-file-F3" F3 3 &&
git config rerere.enabled true &&
test_must_fail git rebase -m master topic &&
diff --git a/t/t3419-rebase-patch-id.sh b/t/t3419-rebase-patch-id.sh
index bd8efaf..e70ac10 100755
--- a/t/t3419-rebase-patch-id.sh
+++ b/t/t3419-rebase-patch-id.sh
@@ -39,7 +39,7 @@ run()
}
test_expect_success 'setup' '
- git commit --allow-empty -m initial
+ git commit --allow-empty -m initial &&
git tag root
'
--
1.7.7.3
^ permalink raw reply related
* [PATCH 5/6] t1510 (worktree): fix '&&' chaining
From: Ramkumar Ramachandra @ 2011-12-08 13:10 UTC (permalink / raw)
To: Jonathan Nieder; +Cc: Junio C Hamano, Matthieu Moy, Git List
In-Reply-To: <1323349817-15737-1-git-send-email-artagnon@gmail.com>
Breaks in a test assertion's && chain can potentially hide failures
from earlier commands in the chain. Fix these breaks.
Additionally, note that 'unset' returns non-zero status when the
variable passed was already unset on some shells: change these
instances to 'safe_unset'.
Helped-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>
---
t/t1501-worktree.sh | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/t/t1501-worktree.sh b/t/t1501-worktree.sh
index 6384983..8e04e7c 100755
--- a/t/t1501-worktree.sh
+++ b/t/t1501-worktree.sh
@@ -48,7 +48,7 @@ test_expect_success 'setup: helper for testing rev-parse' '
'
test_expect_success 'setup: core.worktree = relative path' '
- unset GIT_WORK_TREE;
+ safe_unset GIT_WORK_TREE &&
GIT_DIR=repo.git &&
GIT_CONFIG="$(pwd)"/$GIT_DIR/config &&
export GIT_DIR GIT_CONFIG &&
@@ -89,7 +89,7 @@ test_expect_success 'subdir of work tree' '
'
test_expect_success 'setup: core.worktree = absolute path' '
- unset GIT_WORK_TREE;
+ safe_unset GIT_WORK_TREE &&
GIT_DIR=$(pwd)/repo.git &&
GIT_CONFIG=$GIT_DIR/config &&
export GIT_DIR GIT_CONFIG &&
@@ -334,7 +334,7 @@ test_expect_success 'absolute pathspec should fail gracefully' '
'
test_expect_success 'make_relative_path handles double slashes in GIT_DIR' '
- >dummy_file
+ >dummy_file &&
echo git --git-dir="$(pwd)//repo.git" --work-tree="$(pwd)" add dummy_file &&
git --git-dir="$(pwd)//repo.git" --work-tree="$(pwd)" add dummy_file
'
--
1.7.7.3
^ permalink raw reply related
* Re: [PATCH 3/6] t1006 (cat-file): use test_cmp
From: Matthieu Moy @ 2011-12-08 13:28 UTC (permalink / raw)
To: Ramkumar Ramachandra; +Cc: Jonathan Nieder, Junio C Hamano, Git List
In-Reply-To: <1323349817-15737-6-git-send-email-artagnon@gmail.com>
Ramkumar Ramachandra <artagnon@gmail.com> writes:
> test_expect_success "--batch-check with multiple sha1s gives correct format" '
> - test "$batch_check_output" = \
> - "$(echo_without_newline "$batch_check_input" | git cat-file --batch-check)"
> + echo "$batch_check_output" >expect &&
> + echo_without_newline "$batch_check_input" | git cat-file
> + --batch-check >actual &&
> + test_cmp expect actual
> '
Whitespace damage?
--
Matthieu Moy
http://www-verimag.imag.fr/~moy/
^ permalink raw reply
* Re: [PATCH 3/6] t1006 (cat-file): use test_cmp
From: Ramkumar Ramachandra @ 2011-12-08 13:33 UTC (permalink / raw)
To: Matthieu Moy; +Cc: Jonathan Nieder, Junio C Hamano, Git List
In-Reply-To: <vpqiplrchvi.fsf@bauges.imag.fr>
Hi Matthieu,
Matthieu Moy wrote:
> Ramkumar Ramachandra <artagnon@gmail.com> writes:
>
>> test_expect_success "--batch-check with multiple sha1s gives correct format" '
>> - test "$batch_check_output" = \
>> - "$(echo_without_newline "$batch_check_input" | git cat-file --batch-check)"
>> + echo "$batch_check_output" >expect &&
>> + echo_without_newline "$batch_check_input" | git cat-file
>> + --batch-check >actual &&
>> + test_cmp expect actual
>> '
>
> Whitespace damage?
Odd. Email client issue? Seems to be fine in the original message [1].
[1]: http://article.gmane.org/gmane.comp.version-control.git/186558
-- Ram
^ permalink raw reply
* [PATCH 1/2] index_pack: indent find_unresolved_detals one level
From: pclouds @ 2011-12-08 13:40 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Shawn Pearce,
Nguyễn Thái Ngọc Duy
In-Reply-To: <CAJo=hJvrk3Jzg3dQhQnfbmKAFovLuEtJAP4rakHPFeuZ0T5R7g@mail.gmail.com>
From: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
The next patch puts most of the code in one level deeper. By indenting
separately, it'd be easier to see the actual changes.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
builtin/index-pack.c | 47 +++++++++++++++++++++++------------------------
1 files changed, 23 insertions(+), 24 deletions(-)
diff --git a/builtin/index-pack.c b/builtin/index-pack.c
index 103e19c..9855ada 100644
--- a/builtin/index-pack.c
+++ b/builtin/index-pack.c
@@ -585,37 +585,36 @@ static void find_unresolved_deltas(struct base_data *base,
base_spec.offset = base->obj->idx.offset;
find_delta_children(&base_spec,
&ofs_first, &ofs_last, OBJ_OFS_DELTA);
- }
- if (ref_last == -1 && ofs_last == -1) {
- free(base->data);
- return;
- }
+ if (ref_last == -1 && ofs_last == -1) {
+ free(base->data);
+ return;
+ }
- link_base_data(prev_base, base);
+ link_base_data(prev_base, base);
- for (i = ref_first; i <= ref_last; i++) {
- struct object_entry *child = objects + deltas[i].obj_no;
- struct base_data result;
+ for (i = ref_first; i <= ref_last; i++) {
+ struct object_entry *child = objects + deltas[i].obj_no;
+ struct base_data result;
- assert(child->real_type == OBJ_REF_DELTA);
- resolve_delta(child, base, &result);
- if (i == ref_last && ofs_last == -1)
- free_base_data(base);
- find_unresolved_deltas(&result, base);
- }
+ assert(child->real_type == OBJ_REF_DELTA);
+ resolve_delta(child, base, &result);
+ if (i == ref_last && ofs_last == -1)
+ free_base_data(base);
+ find_unresolved_deltas(&result, base);
+ }
- for (i = ofs_first; i <= ofs_last; i++) {
- struct object_entry *child = objects + deltas[i].obj_no;
- struct base_data result;
+ for (i = ofs_first; i <= ofs_last; i++) {
+ struct object_entry *child = objects + deltas[i].obj_no;
+ struct base_data result;
- assert(child->real_type == OBJ_OFS_DELTA);
- resolve_delta(child, base, &result);
- if (i == ofs_last)
- free_base_data(base);
- find_unresolved_deltas(&result, base);
+ assert(child->real_type == OBJ_OFS_DELTA);
+ resolve_delta(child, base, &result);
+ if (i == ofs_last)
+ free_base_data(base);
+ find_unresolved_deltas(&result, base);
+ }
}
-
unlink_base_data(base);
}
--
1.7.8.36.g69ee2
^ permalink raw reply related
* [PATCH 2/2] index-pack: a naive attempt to flatten find_unresolved_deltas
From: pclouds @ 2011-12-08 13:40 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Shawn Pearce,
Nguyễn Thái Ngọc Duy
In-Reply-To: <1323351638-4790-1-git-send-email-y>
From: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
This seems to work for me. But I think this approach uses (much?) more
memory because it turns a tree of calls into a flat list of calls and
keep the list until the end, while the recursive version only has to
keep one call chain at a time.
Any ideas how to improve it?
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
builtin/index-pack.c | 57 +++++++++++++++++++++++++++++++++++++------------
1 files changed, 43 insertions(+), 14 deletions(-)
diff --git a/builtin/index-pack.c b/builtin/index-pack.c
index 9855ada..d4c182f 100644
--- a/builtin/index-pack.c
+++ b/builtin/index-pack.c
@@ -565,18 +565,31 @@ static void resolve_delta(struct object_entry *delta_obj,
nr_resolved_deltas++;
}
+struct fud_stack {
+ struct base_data base_;
+ struct base_data *base;
+ struct base_data *prev_base;
+};
+
static void find_unresolved_deltas(struct base_data *base,
struct base_data *prev_base)
{
+ struct fud_stack **stack = NULL;
+ int stk, stack_nr = 0, stack_alloc = 0;
int i, ref_first, ref_last, ofs_first, ofs_last;
- /*
- * This is a recursive function. Those brackets should help reducing
- * stack usage by limiting the scope of the delta_base union.
- */
- {
+ ALLOC_GROW(stack, stack_nr + 1, stack_alloc);
+ stack[stack_nr] = xmalloc(sizeof(struct fud_stack));
+ stack[stack_nr]->base = base;
+ stack[stack_nr]->prev_base = prev_base;
+ stack_nr++;
+
+ for (stk = 0; stk < stack_nr; stk++) {
union delta_base base_spec;
+ base = stack[stk]->base;
+ prev_base = stack[stk]->prev_base;
+
hashcpy(base_spec.sha1, base->obj->idx.sha1);
find_delta_children(&base_spec,
&ref_first, &ref_last, OBJ_REF_DELTA);
@@ -588,34 +601,50 @@ static void find_unresolved_deltas(struct base_data *base,
if (ref_last == -1 && ofs_last == -1) {
free(base->data);
- return;
+ free(stack[stk]);
+ stack[stk] = NULL;
+ continue;
}
link_base_data(prev_base, base);
+ ALLOC_GROW(stack, stack_nr +
+ (ref_last - ref_first + 1) +
+ (ofs_last - ofs_first + 1),
+ stack_alloc);
+
for (i = ref_first; i <= ref_last; i++) {
struct object_entry *child = objects + deltas[i].obj_no;
- struct base_data result;
assert(child->real_type == OBJ_REF_DELTA);
- resolve_delta(child, base, &result);
+ stack[stack_nr] = xmalloc(sizeof(struct fud_stack));
+ stack[stack_nr]->base = &stack[stack_nr]->base_;
+ resolve_delta(child, base, stack[stack_nr]->base);
if (i == ref_last && ofs_last == -1)
free_base_data(base);
- find_unresolved_deltas(&result, base);
+ stack[stack_nr]->prev_base = base;
+ stack_nr++;
}
for (i = ofs_first; i <= ofs_last; i++) {
struct object_entry *child = objects + deltas[i].obj_no;
- struct base_data result;
-
assert(child->real_type == OBJ_OFS_DELTA);
- resolve_delta(child, base, &result);
+ stack[stack_nr] = xmalloc(sizeof(struct fud_stack));
+ stack[stack_nr]->base = &stack[stack_nr]->base_;
+ resolve_delta(child, base, stack[stack_nr]->base);
if (i == ofs_last)
free_base_data(base);
- find_unresolved_deltas(&result, base);
+ stack[stack_nr]->prev_base = base;
+ stack_nr++;
}
}
- unlink_base_data(base);
+
+ for (stk = stack_nr - 1; stk >= 0; stk--)
+ if (stack[stk]) {
+ unlink_base_data(stack[stk]->base);
+ free(stack[stk]);
+ }
+ free(stack);
}
static int compare_delta_entry(const void *a, const void *b)
--
1.7.8.36.g69ee2
^ permalink raw reply related
* Re: [PATCH 3/6] t1006 (cat-file): use test_cmp
From: Matthieu Moy @ 2011-12-08 13:41 UTC (permalink / raw)
To: Ramkumar Ramachandra; +Cc: Jonathan Nieder, Junio C Hamano, Git List
In-Reply-To: <CALkWK0=NFxAqmOkObqjVmBQ-TQ=hZhWi=ZScMEGibvS2Pu+XqQ@mail.gmail.com>
Ramkumar Ramachandra <artagnon@gmail.com> writes:
> Hi Matthieu,
>
> Matthieu Moy wrote:
>> Ramkumar Ramachandra <artagnon@gmail.com> writes:
>>
>>> test_expect_success "--batch-check with multiple sha1s gives correct format" '
>>> - test "$batch_check_output" = \
>>> - "$(echo_without_newline "$batch_check_input" | git cat-file
>>> --batch-check)"
>>> + echo "$batch_check_output" >expect &&
>>> + echo_without_newline "$batch_check_input" | git cat-file
>>> + --batch-check >actual &&
>>> + test_cmp expect actual
>>> '
>>
>> Whitespace damage?
>
> Odd. Email client issue?
It seems so. Weird, Gnus usually doesn't do this sort of things to me.
Sorry for the noise.
--
Matthieu Moy
http://www-verimag.imag.fr/~moy/
^ permalink raw reply
* Re: [PATCH 0/5] cache-tree revisited
From: Thomas Rast @ 2011-12-08 14:15 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Carlos Martín Nieto
In-Reply-To: <cover.1323191497.git.trast@student.ethz.ch>
Thomas Rast wrote:
> Junio C Hamano wrote:
> > Ahh, I forgot all about that exchange.
> >
> > http://thread.gmane.org/gmane.comp.version-control.git/178480/focus=178515
> >
> > The cache-tree mechanism has traditionally been one of the more important
> > optimizations and it would be very nice if we can resurrect the behaviour
> > for "git commit" too.
>
> Oh, I buried that. Let's try something other than the aggressive
> strategy I had there: only compute cache-tree if
>
> * we know we're going to need it soon, and we're about to write out
> the index anyway (as in git-commit)
I had another idea: we could write out *just* a new cache-tree data
set at the end of git-commit.
Doing it the cheap way would mean rehashing the on-disk data without
actually touching it. (That might not be so bad, but then if your
index is small, why is writing it from scratch expensive?)
Doing it efficiently requires making the sha1 restartable, which is
entirely doable withblock-sha1/sha1.h (I haven't looked into
ppc/sha1.h). As far as I can see it's not feasible with openssl's
sha1.
That is, we would add a new index extension (say PSHA: partial SHA)
and structure the index as
signature
header
cache data
PSHA <sha state up until just before PSHA>
TREE ...
[REUC ...]
sha1 footer
Then it's easy to cheaply replace only the extensions, by restarting
the hashing from the PSHA data and re-emitting only the extension
data.
I think all the bits are in place, and it would be easy to do.
However, for it to make sense, we would have to make BLK_SHA1 the
default for the most-used platforms and also not mind extending the
SHA1 API. Do you think that would fly?
I thought about other ways to make the index writing restartable from
the middle, but the only clean approach I came up with would require a
format change to something like
signature
0 header
1 cache data
2 sha1 of 0..1
3 extension data A
4 sha1 of 2..3
5 extension data B
6 sha1 of 4..5
[possibly more]
7 end-of-index marker
8 sha1 of 6..7
etc.
--
Thomas Rast
trast@{inf,student}.ethz.ch
^ permalink raw reply
* Re: [PATCH 1/2] parse-options: introduce OPT_SUBCOMMAND
From: Jonathan Nieder @ 2011-12-08 16:30 UTC (permalink / raw)
To: Ramkumar Ramachandra; +Cc: Junio C Hamano, Matthieu Moy, Git List
In-Reply-To: <1323349817-15737-2-git-send-email-artagnon@gmail.com>
Hi,
Quick thoughts:
Ramkumar Ramachandra wrote:
> Currently, the parse-options framework forbids the use of
> opts->long_name and OPT_PARSE_NODASH, and the parsing has to be done
> by hand as a result. Lift this restriction
This part seems like a sane idea to me.
> , and create a new
> OPT_SUBCOMMAND; this is built on top of OPTION_BIT to allow for the
> detection of more than one subcommand.
This part I am not convinced about. Usually each subcommand takes its
own options, so I cannot see this OPT_SUBCOMMAND being actually useful
for commands like "git stash" or "git remote".
Hope that helps,
Jonathan
^ 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