* Re: interactive rebase not rebasing
From: Andreas Ericsson @ 2008-10-01 7:50 UTC (permalink / raw)
To: Stephen Haberman; +Cc: git
In-Reply-To: <20081001010306.01cc34eb.stephen@exigencecorp.com>
Stephen Haberman wrote:
>>> # A --C------ <-- origin/stable
>>> # \ | \
>>> # B -- D -- E -- F <-- origin/topic2
>>> # \|
>>> # g -- h <-- topic2
>>>
>>> Nothing has changed. g & h haven't moved...I can keep executing this
>>> operation and the commits never make it on top of origin/topic2's F.
>>>
>>> Frustratingly, if I run non-interactive rebase, it works perfectly.
>> I can imagine. Since you don't want to preserve the merges in this
>> case, you shouldn't be using the -p flag.
>
> No, I do want to preserve most merges. This "most" qualification is
> because the merge "g", if rebased, would have been a no-op, so `rebase
> -i -p` correctly kept it out of the TODO file.
>
> Which is cool, except that later on, when rewriting the other TODO
> commits, some of which were children of "g", it did not remember that
> "g" had gone away, so did nothing to take "g" out of the rewritten
> children's parent list.
>
>> In fact, for this particular scenario (assuming "h" is really the only
>> commit on topic2), you probably want to just cherry-pick that commit
>> into origin/topic2:
>>
>> git checkout topic2
>> git reset --hard origin/topic2
>> git cherry-pick ORIG_HEAD
>
> Agreed. This makes a lot of sense for me, who has been hacking around in
> git-rebase--interactive fixing things, but I'd really like the other
> people on my team to just have to run `git rebase -i -p`.
>
>> I don't think you can have a single command that does all the things
>> you want, because the possible differences in input makes it very
>> nearly impossible to always do "the right thing".
>
> Ah, you are too pessimistic. :-)
>
Perhaps, although I think you're being overly optimistic if you think
rebase can do all of this intelligently while still retaining clear
semantics. I'd start with writing a separate tool for it, probably
based on git sequencer. When that works out ok, get it to do what
rebase does today and then incorporate the new tool as an option to
rebase and get ready to answer complex questions for the cases where
it doesn't do what the user wanted it to do.
Git is stupid very, very much by design. Linus constantly says that
he prefers tools that he can figure out why they did something stupid
over tools that try really hard to get it right, and I agree with him
100%, as do most of the core contributors (insofar as I've understood
it). What you're suggesting is that a git command should try hard to
dwim a lot of complexity about choosing tools away, and that goes
right against the KISS principle which serves git so well. I'm not
saying you shouldn't do it. Merely that you should think hard about
it and then make sure it doesn't break anything people are already
doing today with the current toolset.
--
Andreas Ericsson andreas.ericsson@op5.se
OP5 AB www.op5.se
Tel: +46 8-230225 Fax: +46 8-230231
^ permalink raw reply
* obscure platform autobuilders
From: Jeff King @ 2008-10-01 7:16 UTC (permalink / raw)
To: Mike Ralphson; +Cc: git
In-Reply-To: <e2b179460809290051q8ca76a4k7cf0af2748a5f0fc@mail.gmail.com>
On Mon, Sep 29, 2008 at 08:51:29AM +0100, Mike Ralphson wrote:
> Feel free to push changes to gitbuild.sh, including getting rid of
> anything which looks environment-specific.
I actually went a step further and revamped the architecture a bit.
Check out the "platform" branch in gitbuild.git. My goal was to try to
include more information in the gitbuild repository about exactly what
goes into the test setup for each platform.
I'm currently building, testing, and pushing FreeBSD 6.1 and Solaris 2.8
with it (you can see the copious tests I am skipping in
jk/solaris/config).
If you like this approach, please go ahead and add an "mr/aix" profile
with your setup. See the README for details, and let me know if you have
questions. The script is a mish-mash of yours, mine, and some extra
rewrites. I wouldn't be surprised if it needs a tweak or two. :)
-Peff
^ permalink raw reply
* Re: [QGit] [PATCH] Modify Highlight Color at File Context View.
From: Marco Costalba @ 2008-10-01 6:47 UTC (permalink / raw)
To: Li Frank-B20596; +Cc: git
In-Reply-To: <7FD1F85C96D70C4A89DA1DF7667EAE9605EA4E@zch01exm23.fsl.freescale.net>
On Mon, Sep 29, 2008 at 3:27 AM, Li Frank-B20596 <Frank.Li@freescale.com> wrote:
> Marco:
>
> I don't get my patch by git-pull.
> There are not my patch at
> http://git.kernel.org/?p=qgit/qgit4.git;a=summary.
>
> best regards
> Frank Li
> ________________________________
I have pushed to my local repo, I will be able to push to public repo
only this week end.
Marco
^ permalink raw reply
* Re: [PATCH] git grep: Add "-Z/--null" option as in GNU's grep.
From: Pierre Habouzit @ 2008-10-01 6:12 UTC (permalink / raw)
To: Raphael Zimmerer; +Cc: spearce, git
In-Reply-To: <1222816390-9141-1-git-send-email-killekulla@rdrz.de>
[-- Attachment #1: Type: text/plain, Size: 582 bytes --]
On Tue, Sep 30, 2008 at 11:13:10PM +0000, Raphael Zimmerer wrote:
> + printf("%s%c", name, opt->null_following_name ? 0 : '\n');
I know I'm nitpicking and I don't know what the git custom on this
really is, but I tend to prefer '\0' when in the context of a char.
There is no confusion here of course, but I believe it to be a sane
habit. (In the same vein that it's ugly to use 0 for NULL ;p).
--
·O· Pierre Habouzit
··O madcoder@debian.org
OOO http://www.madism.org
[-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --]
^ permalink raw reply
* [PATCH] Fix interactive rebase on dropped commits.
From: Stephen Haberman @ 2008-10-01 6:11 UTC (permalink / raw)
To: git; +Cc: ae, spearce
Interactive rebase got its rev-list of commits to keep by --left-right and
--cherry-pick. Adding --cherry-pick would throw out commits that were just
duplicating changes already in the rebase target.
Which is desirable, except the dropped commit has forgotten about when it came
to rewriting the parents of its descendents, so the descendents would get
cherry-picked as-in and essentially make the rebase a no-op.
This change adds a $DOTEST/dropped directory to remember dropped commits and
rewrite its children's parents as the children's (possibly rewritten)
grandparents.
Signed-off-by: Stephen Haberman <stephen@exigencecorp.com>
---
git-rebase--interactive.sh | 52 ++++++++++++---
t/t3409-rebase-interactive-cherry-picked.sh | 94 +++++++++++++++++++++++++++
2 files changed, 136 insertions(+), 10 deletions(-)
create mode 100644 t/t3409-rebase-interactive-cherry-picked.sh
diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index 929d681..2d62590 100755
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -37,6 +37,7 @@ DONE="$DOTEST"/done
MSG="$DOTEST"/message
SQUASH_MSG="$DOTEST"/message-squash
REWRITTEN="$DOTEST"/rewritten
+DROPPED="$DOTEST"/dropped
PRESERVE_MERGES=
STRATEGY=
ONTO=
@@ -146,15 +147,7 @@ pick_one () {
pick_one_preserving_merges () {
fast_forward=t
- case "$1" in
- -n)
- fast_forward=f
- sha1=$2
- ;;
- *)
- sha1=$1
- ;;
- esac
+ case "$1" in -n) fast_forward=f sha1=$2 ;; *) sha1=$1 ;; esac
sha1=$(git rev-parse $sha1)
if test -f "$DOTEST"/current-commit
@@ -183,7 +176,28 @@ pick_one_preserving_merges () {
;;
esac
else
- new_parents="$new_parents $p"
+ if test -f "$DROPPED"/$p
+ then
+ fast_forward=f
+ cat "$DROPPED"/$p | while read grandparent
+ do
+ if test -f "$REWRITTEN"/$grandparent
+ then
+ new_p=$(cat "$REWRITTEN"/$grandparent)
+ else
+ new_p=$grandparent
+ fi
+ case "$new_parents" in
+ *$new_p*)
+ ;; # do nothing; that parent is already there
+ *)
+ new_parents="$new_parents $new_p"
+ ;;
+ esac
+ done
+ else
+ new_parents="$new_parents $p"
+ fi
fi
done
case $fast_forward in
@@ -574,6 +588,24 @@ do
#
EOF
+ # Watch for commits that been dropped by --cherry-pick
+ if test t = "$PRESERVE_MERGES"
+ then
+ mkdir "$DROPPED"
+ # drop the --cherry-pick parameter this time
+ git rev-list $MERGES_OPTION --abbrev-commit \
+ --abbrev=7 $UPSTREAM...$HEAD --left-right | \
+ sed -n "s/^>//p" | while read rev
+ do
+ grep --quiet "$rev" "$TODO"
+ if [ $? -ne 0 ]
+ then
+ full=$(git rev-parse $rev)
+ git rev-list --parents -1 $rev | cut -d' ' -f2- | sed 's/ /\n/g' > "$DROPPED"/$full
+ fi
+ done
+ fi
+
has_action "$TODO" ||
die_abort "Nothing to do"
diff --git a/t/t3409-rebase-interactive-cherry-picked.sh b/t/t3409-rebase-interactive-cherry-picked.sh
new file mode 100644
index 0000000..3d20180
--- /dev/null
+++ b/t/t3409-rebase-interactive-cherry-picked.sh
@@ -0,0 +1,94 @@
+#!/bin/sh
+
+test_description='rebase interactive does not rebase'
+
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+ echo "setup" >a &&
+ git add a &&
+ git commit -m "setup" &&
+ git clone ./. server &&
+ rm -fr server/.git/hooks &&
+ git remote add origin ./server &&
+ git config --add branch.master.remote origin &&
+ git config --add branch.master.merge refs/heads/master &&
+ git fetch &&
+
+ git checkout -b stable master &&
+ echo "setup.stable" >a &&
+ git commit -a -m "stable" &&
+ git push origin stable
+'
+#
+# A --C------ <-- origin/stable
+# \ | \
+# B -- D -- E -- F <-- origin/topic2
+# \| \
+# g -- h ------- i <-- topic2
+#
+# Trying to push F..i
+#
+# merge-base(F, h) has two options: B and C
+#
+test_expect_success 'merging in stable with tricky double baserev does not fool the script' '
+ # B: start our topic2 branch, and share it
+ git checkout -b topic2 origin/stable &&
+ git config --add branch.topic2.merge refs/heads/topic2 &&
+ echo "commit B" >a.topic2 &&
+ git add a.topic2 &&
+ git commit -m "commit B created topic2" &&
+ git push origin topic2 &&
+
+ # C: now, separately, move ahead stable, and share it
+ git checkout stable
+ echo "commit C" >a &&
+ git commit -a -m "commit C moved stable" &&
+ git push origin stable &&
+
+ # D: have another client commit (in this case, it is the server, but close enough) moves topic2
+ cd server &&
+ git checkout topic2 &&
+ echo "commit D continuing topic2" >a.client2 &&
+ git add a.client2 &&
+ git commit -m "commit D by client2" &&
+
+ # E: the same other client merges the moved stable
+ git merge stable &&
+
+ # F: the same other client moves topic2 again
+ echo "commit F" >a.client2 &&
+ git commit -a -m "commit F by client2" &&
+ F_hash=$(git rev-parse HEAD) &&
+ cd .. &&
+
+ # g: now locally merge in the moved stable (even though our topic2 is out of date)
+ git checkout topic2 &&
+ git merge stable &&
+ g_hash=$(git rev-parse HEAD) &&
+
+ # h: advance local topic2
+ echo "commit H" >a.topic2 &&
+ git commit -a -m "commit H continues local fork" &&
+ h_hash=$(git rev-parse HEAD) &&
+
+ # i: make a new merge commit
+ git pull --no-rebase &&
+ i_hash=$(git rev-parse HEAD) &&
+
+ # Watch merge rejected as something that should get rebased
+ # ! git push origin topic2
+ test "$i_hash $h_hash $F_hash" = "$(git rev-list --parents --no-walk HEAD)"
+
+ # Now fix it the merge by rebasing it
+ git reset --hard ORIG_HEAD &&
+ GIT_EDITOR=: git rebase -i -p origin/topic2 &&
+ h2_hash=$(git rev-parse HEAD) &&
+
+ # Previously $F_hash was dropped and it was the same $h_hash $g_hash
+ test "$h2_hash $F_hash" = "$(git rev-list --parents --no-walk HEAD)"
+'
+
+test_done
+
+
--
1.6.0.2
^ permalink raw reply related
* [PATCH 3/3] parse-opt: migrate builtin-merge-file.
From: Pierre Habouzit @ 2008-10-01 6:05 UTC (permalink / raw)
To: spearce; +Cc: git, gitster, Pierre Habouzit
In-Reply-To: <1222841106-26148-2-git-send-email-madcoder@debian.org>
Signed-off-by: Pierre Habouzit <madcoder@debian.org>
---
builtin-merge-file.c | 68 +++++++++++++++++++++++++++----------------------
1 files changed, 37 insertions(+), 31 deletions(-)
diff --git a/builtin-merge-file.c b/builtin-merge-file.c
index 45c9853..7736fe8 100644
--- a/builtin-merge-file.c
+++ b/builtin-merge-file.c
@@ -2,21 +2,44 @@
#include "cache.h"
#include "xdiff/xdiff.h"
#include "xdiff-interface.h"
+#include "parse-options.h"
-static const char merge_file_usage[] =
-"git merge-file [-p | --stdout] [--diff3] [-q | --quiet] [-L name1 [-L orig [-L name2]]] file1 orig_file file2";
+static const char *const merge_file_usage[] = {
+ "git merge-file [options] [-L name1 [-L orig [-L name2]]] file1 orig_file file2",
+ NULL
+};
+
+static int label_cb(const struct option *opt, const char *arg, int unset)
+{
+ static int label_count = 0;
+ const char **names = (const char **)opt->value;
+
+ if (label_count >= 3)
+ return error("too many labels on the command like");
+ names[label_count++] = arg;
+ return 0;
+}
int cmd_merge_file(int argc, const char **argv, const char *prefix)
{
- const char *names[3];
+ const char *names[3] = { NULL, NULL, NULL };
mmfile_t mmfs[3];
mmbuffer_t result = {NULL, 0};
xpparam_t xpp = {XDF_NEED_MINIMAL};
int ret = 0, i = 0, to_stdout = 0;
int merge_level = XDL_MERGE_ZEALOUS_ALNUM;
- int merge_style = 0;
+ int merge_style = 0, quiet = 0;
int nongit;
+ struct option options[] = {
+ OPT_BOOLEAN('p', "stdout", &to_stdout, "send results to standard output"),
+ OPT_SET_INT(0, "diff3", &merge_style, "use a diff3 based merge", XDL_MERGE_DIFF3),
+ OPT__QUIET(&quiet),
+ OPT_CALLBACK('L', NULL, names, "name",
+ "set labels for file1/orig_file/file2", &label_cb),
+ OPT_END(),
+ };
+
prefix = setup_git_directory_gently(&nongit);
if (!nongit) {
/* Read the configuration file */
@@ -25,37 +48,20 @@ int cmd_merge_file(int argc, const char **argv, const char *prefix)
merge_style = git_xmerge_style;
}
- while (argc > 4) {
- if (!strcmp(argv[1], "-L") && i < 3) {
- names[i++] = argv[2];
- argc--;
- argv++;
- } else if (!strcmp(argv[1], "-p") ||
- !strcmp(argv[1], "--stdout"))
- to_stdout = 1;
- else if (!strcmp(argv[1], "-q") ||
- !strcmp(argv[1], "--quiet"))
- freopen("/dev/null", "w", stderr);
- else if (!strcmp(argv[1], "--diff3"))
- merge_style = XDL_MERGE_DIFF3;
- else
- usage(merge_file_usage);
- argc--;
- argv++;
- }
-
- if (argc != 4)
- usage(merge_file_usage);
-
- for (; i < 3; i++)
- names[i] = argv[i + 1];
+ argc = parse_options(argc, argv, options, merge_file_usage, 0);
+ if (argc != 3)
+ usage_with_options(merge_file_usage, options);
+ if (quiet)
+ freopen("/dev/null", "w", stderr);
for (i = 0; i < 3; i++) {
- if (read_mmfile(mmfs + i, argv[i + 1]))
+ if (!names[i])
+ names[i] = argv[i];
+ if (read_mmfile(mmfs + i, argv[i]))
return -1;
if (buffer_is_binary(mmfs[i].ptr, mmfs[i].size))
return error("Cannot merge binary files: %s\n",
- argv[i + 1]);
+ argv[i]);
}
ret = xdl_merge(mmfs + 1, mmfs + 0, names[0], mmfs + 2, names[2],
@@ -65,7 +71,7 @@ int cmd_merge_file(int argc, const char **argv, const char *prefix)
free(mmfs[i].ptr);
if (ret >= 0) {
- const char *filename = argv[1];
+ const char *filename = argv[0];
FILE *f = to_stdout ? stdout : fopen(filename, "wb");
if (!f)
--
1.6.0.2.415.g9800c0.dirty
^ permalink raw reply related
* [PATCH 1/3] parse-opt: migrate fmt-merge-msg.
From: Pierre Habouzit @ 2008-10-01 6:05 UTC (permalink / raw)
To: spearce; +Cc: git, gitster, Pierre Habouzit
In-Reply-To: <20080930224623.GQ21310@spearce.org>
Also fix an inefficient printf("%s", ...) where we can use write_in_full.
Signed-off-by: Pierre Habouzit <madcoder@debian.org>
---
builtin-fmt-merge-msg.c | 52 +++++++++++++++++++++-------------------------
1 files changed, 24 insertions(+), 28 deletions(-)
> It may actually be a good idea to rebase this against master.
>
> Reading Junio's notes for sg/merge-options (the branch this conflict
> is coming out of) it sounds like we'd want to revert that anyway.
> Its been around since April and Junio was talking about it needing
> to be in a 1.7.0 release. Its not going to graduate anytime soon.
Fair enough, here it is.
diff --git a/builtin-fmt-merge-msg.c b/builtin-fmt-merge-msg.c
index df02ba7..78c04bf 100644
--- a/builtin-fmt-merge-msg.c
+++ b/builtin-fmt-merge-msg.c
@@ -5,8 +5,10 @@
#include "revision.h"
#include "tag.h"
-static const char *fmt_merge_msg_usage =
- "git fmt-merge-msg [--log] [--no-log] [--file <file>]";
+static const char * const fmt_merge_msg_usage[] = {
+ "git fmt-merge-msg [--log|--no-log] [--file <file>]",
+ NULL
+};
static int merge_summary;
@@ -347,38 +349,32 @@ int fmt_merge_msg(int merge_summary, struct strbuf *in, struct strbuf *out) {
int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix)
{
+ const char *inpath = NULL;
+ struct option options[] = {
+ OPT_BOOLEAN(0, "log", &merge_summary, "populate log with the shortlog"),
+ OPT_BOOLEAN(0, "summary", &merge_summary, "alias for --log"),
+ OPT_STRING('F', "file", &inpath, "file", "file to read from"),
+ OPT_END()
+ };
+
FILE *in = stdin;
struct strbuf input, output;
int ret;
git_config(fmt_merge_msg_config, NULL);
-
- while (argc > 1) {
- if (!strcmp(argv[1], "--log") || !strcmp(argv[1], "--summary"))
- merge_summary = 1;
- else if (!strcmp(argv[1], "--no-log")
- || !strcmp(argv[1], "--no-summary"))
- merge_summary = 0;
- else if (!strcmp(argv[1], "-F") || !strcmp(argv[1], "--file")) {
- if (argc < 3)
- die ("Which file?");
- if (!strcmp(argv[2], "-"))
- in = stdin;
- else {
- fclose(in);
- in = fopen(argv[2], "r");
- if (!in)
- die("cannot open %s", argv[2]);
- }
- argc--; argv++;
- } else
- break;
- argc--; argv++;
+ argc = parse_options(argc, argv, options, fmt_merge_msg_usage, 0);
+ if (argc > 0)
+ usage_with_options(fmt_merge_msg_usage, options);
+
+ if (!inpath || strcmp(inpath, "-"))
+ in = stdin;
+ else {
+ fclose(in);
+ in = fopen(argv[2], "r");
+ if (!in)
+ die("cannot open %s", argv[2]);
}
- if (argc > 1)
- usage(fmt_merge_msg_usage);
-
strbuf_init(&input, 0);
if (strbuf_read(&input, fileno(in), 0) < 0)
die("could not read input file %s", strerror(errno));
@@ -387,6 +383,6 @@ int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix)
ret = fmt_merge_msg(merge_summary, &input, &output);
if (ret)
return ret;
- printf("%s", output.buf);
+ write_in_full(STDOUT_FILENO, output.buf, output.len);
return 0;
}
--
1.6.0.2.415.g9800c0.dirty
^ permalink raw reply related
* [PATCH 2/3] parse-opt: migrate git-merge-base.
From: Pierre Habouzit @ 2008-10-01 6:05 UTC (permalink / raw)
To: spearce; +Cc: git, gitster, Pierre Habouzit
In-Reply-To: <1222841106-26148-1-git-send-email-madcoder@debian.org>
Signed-off-by: Pierre Habouzit <madcoder@debian.org>
---
builtin-merge-base.c | 37 ++++++++++++++++---------------------
1 files changed, 16 insertions(+), 21 deletions(-)
diff --git a/builtin-merge-base.c b/builtin-merge-base.c
index b08da51..03fc1c2 100644
--- a/builtin-merge-base.c
+++ b/builtin-merge-base.c
@@ -1,6 +1,7 @@
#include "builtin.h"
#include "cache.h"
#include "commit.h"
+#include "parse-options.h"
static int show_merge_base(struct commit **rev, int rev_nr, int show_all)
{
@@ -21,8 +22,10 @@ static int show_merge_base(struct commit **rev, int rev_nr, int show_all)
return 0;
}
-static const char merge_base_usage[] =
-"git merge-base [--all] <commit-id> <commit-id>...";
+static const char * const merge_base_usage[] = {
+ "git merge-base [--all] <commit-id> <commit-id>...",
+ NULL
+};
static struct commit *get_commit_reference(const char *arg)
{
@@ -44,25 +47,17 @@ int cmd_merge_base(int argc, const char **argv, const char *prefix)
int rev_nr = 0;
int show_all = 0;
- git_config(git_default_config, NULL);
-
- while (1 < argc && argv[1][0] == '-') {
- const char *arg = argv[1];
- if (!strcmp(arg, "-a") || !strcmp(arg, "--all"))
- show_all = 1;
- else
- usage(merge_base_usage);
- argc--; argv++;
- }
- if (argc < 3)
- usage(merge_base_usage);
-
- rev = xmalloc((argc - 1) * sizeof(*rev));
-
- do {
- rev[rev_nr++] = get_commit_reference(argv[1]);
- argc--; argv++;
- } while (argc > 1);
+ struct option options[] = {
+ OPT_BOOLEAN('a', "all", &show_all, "outputs all common ancestors"),
+ OPT_END()
+ };
+ git_config(git_default_config, NULL);
+ argc = parse_options(argc, argv, options, merge_base_usage, 0);
+ if (argc < 2)
+ usage_with_options(merge_base_usage, options);
+ rev = xmalloc(argc * sizeof(*rev));
+ while (argc-- > 0)
+ rev[rev_nr++] = get_commit_reference(*argv++);
return show_merge_base(rev, rev_nr, show_all);
}
--
1.6.0.2.415.g9800c0.dirty
^ permalink raw reply related
* Re: interactive rebase not rebasing
From: Stephen Haberman @ 2008-10-01 6:03 UTC (permalink / raw)
To: Andreas Ericsson; +Cc: git
In-Reply-To: <48E078BF.5030806@op5.se>
> > # A --C------ <-- origin/stable
> > # \ | \
> > # B -- D -- E -- F <-- origin/topic2
> > # \|
> > # g -- h <-- topic2
> >
> > Nothing has changed. g & h haven't moved...I can keep executing this
> > operation and the commits never make it on top of origin/topic2's F.
> >
> > Frustratingly, if I run non-interactive rebase, it works perfectly.
>
> I can imagine. Since you don't want to preserve the merges in this
> case, you shouldn't be using the -p flag.
No, I do want to preserve most merges. This "most" qualification is
because the merge "g", if rebased, would have been a no-op, so `rebase
-i -p` correctly kept it out of the TODO file.
Which is cool, except that later on, when rewriting the other TODO
commits, some of which were children of "g", it did not remember that
"g" had gone away, so did nothing to take "g" out of the rewritten
children's parent list.
> In fact, for this particular scenario (assuming "h" is really the only
> commit on topic2), you probably want to just cherry-pick that commit
> into origin/topic2:
>
> git checkout topic2
> git reset --hard origin/topic2
> git cherry-pick ORIG_HEAD
Agreed. This makes a lot of sense for me, who has been hacking around in
git-rebase--interactive fixing things, but I'd really like the other
people on my team to just have to run `git rebase -i -p`.
> I don't think you can have a single command that does all the things
> you want, because the possible differences in input makes it very
> nearly impossible to always do "the right thing".
Ah, you are too pessimistic. :-)
> Assuming you're passing a correct input file to rebase -i; yes. At the
> very least, "h" should be moved to the tip of origin/topic2.
Cool, agreed. I've got a patch that gets `rebase -i -p` to do this. I'll
send it to the list soon.
- Stephen
^ permalink raw reply
* [PATCH 9/9] grep: skip files outside sparse checkout area
From: Nguyễn Thái Ngọc Duy @ 2008-10-01 4:04 UTC (permalink / raw)
To: git, Shawn O. Pearce; +Cc: Nguyễn Thái Ngọc Duy
In-Reply-To: <1222833849-22129-9-git-send-email-pclouds@gmail.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
Documentation/git-grep.txt | 4 +++-
builtin-grep.c | 7 ++++++-
2 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/Documentation/git-grep.txt b/Documentation/git-grep.txt
index fa4d133..ee359c9 100644
--- a/Documentation/git-grep.txt
+++ b/Documentation/git-grep.txt
@@ -24,7 +24,9 @@ SYNOPSIS
DESCRIPTION
-----------
Look for specified patterns in the working tree files, blobs
-registered in the index file, or given tree objects.
+registered in the index file, or given tree objects. By default
+it will search in the working tree files. When in sparse checkout
+mode, it only searches checked-out files.
OPTIONS
diff --git a/builtin-grep.c b/builtin-grep.c
index 3a51662..d5507d7 100644
--- a/builtin-grep.c
+++ b/builtin-grep.c
@@ -343,6 +343,8 @@ static int external_grep(struct grep_opt *opt, const char **paths, int cached)
continue;
if (!pathspec_matches(paths, ce->name))
continue;
+ if (ce_no_checkout(ce))
+ continue;
name = ce->name;
if (name[0] == '-') {
int len = ce_namelen(ce);
@@ -404,8 +406,11 @@ static int grep_cache(struct grep_opt *opt, const char **paths, int cached)
continue;
hit |= grep_sha1(opt, ce->sha1, ce->name, 0);
}
- else
+ else {
+ if (ce_no_checkout(ce))
+ continue;
hit |= grep_file(opt, ce->name);
+ }
if (ce_stage(ce)) {
do {
nr++;
--
1.6.0.2.488.gf604a
^ permalink raw reply related
* [PATCH 8/9] checkout_entry(): CE_NO_CHECKOUT on checked out entries.
From: Nguyễn Thái Ngọc Duy @ 2008-10-01 4:04 UTC (permalink / raw)
To: git, Shawn O. Pearce; +Cc: Nguyễn Thái Ngọc Duy
In-Reply-To: <1222833849-22129-8-git-send-email-pclouds@gmail.com>
With this you can just do "git checkout some-files" to
widen your checkout. One caveat though: caller must save
the index.
For all of its callers (unpack_trees(), checkout-index, checkout
and apply), only "git apply" does not write index back.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
entry.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/entry.c b/entry.c
index aa2ee46..305f8d3 100644
--- a/entry.c
+++ b/entry.c
@@ -230,5 +230,6 @@ int checkout_entry(struct cache_entry *ce, const struct checkout *state, char *t
} else if (state->not_new)
return 0;
create_directories(path, state);
+ ce_mark_checkout(ce);
return write_entry(ce, path, state, 0);
}
--
1.6.0.2.488.gf604a
^ permalink raw reply related
* [PATCH 7/9] Prevent diff machinery from examining worktree outside sparse checkout
From: Nguyễn Thái Ngọc Duy @ 2008-10-01 4:04 UTC (permalink / raw)
To: git, Shawn O. Pearce; +Cc: Nguyễn Thái Ngọc Duy
In-Reply-To: <1222833849-22129-7-git-send-email-pclouds@gmail.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
diff-lib.c | 5 +++--
diff.c | 4 +++-
2 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/diff-lib.c b/diff-lib.c
index ae96c64..992280b 100644
--- a/diff-lib.c
+++ b/diff-lib.c
@@ -161,7 +161,7 @@ int run_diff_files(struct rev_info *revs, unsigned int option)
continue;
}
- if (ce_uptodate(ce))
+ if (ce_uptodate(ce) || ce_no_checkout(ce))
continue;
changed = check_removed(ce, &st);
@@ -348,6 +348,8 @@ static void do_oneway_diff(struct unpack_trees_options *o,
struct rev_info *revs = cbdata->revs;
int match_missing, cached;
+ /* if the entry is not checked out, don't examine work tree */
+ cached = o->index_only || (idx && ce_no_checkout(idx));
/*
* Backward compatibility wart - "diff-index -m" does
* not mean "do not ignore merges", but "match_missing".
@@ -355,7 +357,6 @@ static void do_oneway_diff(struct unpack_trees_options *o,
* But with the revision flag parsing, that's found in
* "!revs->ignore_merges".
*/
- cached = o->index_only;
match_missing = !revs->ignore_merges;
if (cached && idx && ce_stage(idx)) {
diff --git a/diff.c b/diff.c
index b001d7b..c001e2c 100644
--- a/diff.c
+++ b/diff.c
@@ -1798,8 +1798,10 @@ static int reuse_worktree_file(const char *name, const unsigned char *sha1, int
/*
* If ce matches the file in the work tree, we can reuse it.
+ * For sparse checkout case, ce_uptodate() may be true although
+ * the file may or may not exist in the work tree.
*/
- if (ce_uptodate(ce) ||
+ if ((ce_uptodate(ce) && ce_checkout(ce)) ||
(!lstat(name, &st) && !ce_match_stat(ce, &st, 0)))
return 1;
--
1.6.0.2.488.gf604a
^ permalink raw reply related
* [PATCH 6/9] ls-files: Add tests for --sparse and friends
From: Nguyễn Thái Ngọc Duy @ 2008-10-01 4:04 UTC (permalink / raw)
To: git, Shawn O. Pearce; +Cc: Nguyễn Thái Ngọc Duy
In-Reply-To: <1222833849-22129-6-git-send-email-pclouds@gmail.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
t/t3004-ls-files-sparse.sh | 40 +++++++++++++++++++++++++++++++++
t/t3004/cached.expected | 5 ++++
t/t3004/deleted.expected | 1 +
t/t3004/everything.expected | 10 ++++++++
t/t3004/modified.expected | 2 +
t/t3004/no-checkout.expected | 2 +
t/t3004/orphaned-no-checkout.expected | 3 ++
t/t3004/orphaned.expected | 1 +
t/t3004/others.expected | 2 +
t/t3004/sparse-cached.expected | 3 ++
t/t3004/sparse-everything.expected | 11 +++++++++
11 files changed, 80 insertions(+), 0 deletions(-)
create mode 100755 t/t3004-ls-files-sparse.sh
create mode 100644 t/t3004/cached.expected
create mode 100644 t/t3004/deleted.expected
create mode 100644 t/t3004/everything.expected
create mode 100644 t/t3004/modified.expected
create mode 100644 t/t3004/no-checkout.expected
create mode 100644 t/t3004/orphaned-no-checkout.expected
create mode 100644 t/t3004/orphaned.expected
create mode 100644 t/t3004/others.expected
create mode 100644 t/t3004/sparse-cached.expected
create mode 100644 t/t3004/sparse-everything.expected
diff --git a/t/t3004-ls-files-sparse.sh b/t/t3004-ls-files-sparse.sh
new file mode 100755
index 0000000..ec2c869
--- /dev/null
+++ b/t/t3004-ls-files-sparse.sh
@@ -0,0 +1,40 @@
+#!/bin/sh
+
+test_description="test ls-files in --sparse mode"
+
+. test-lib.sh
+
+test_ls_files() {
+ T=../t3004/$1.expected
+ shift
+ test_expect_success "ls-files $*" "git ls-files $* > result && test_cmp $T result"
+}
+
+test_expect_success 'setup' '
+ touch other orphaned no-checkout cached modified deleted &&
+ git add orphaned no-checkout cached modified deleted &&
+ git update-index --no-checkout orphaned no-checkout &&
+ echo modified >> modified &&
+ rm no-checkout deleted
+'
+
+test_ls_files cached
+test_ls_files cached --cached
+test_ls_files sparse-cached --sparse
+test_ls_files sparse-cached --sparse --cached
+test_ls_files no-checkout --no-checkout
+test_ls_files no-checkout --sparse --no-checkout
+test_ls_files orphaned --orphaned
+test_ls_files orphaned --sparse --orphaned
+test_ls_files orphaned-no-checkout -v --no-checkout --orphaned
+test_ls_files orphaned-no-checkout -v --sparse --no-checkout --orphaned
+test_ls_files deleted --deleted
+test_ls_files deleted --sparse --deleted
+test_ls_files modified --modified
+test_ls_files modified --sparse --modified
+test_ls_files others --others
+test_ls_files others --sparse --others
+test_ls_files everything -v --cached --deleted --modified --others
+test_ls_files sparse-everything -v --cached --no-checkout --orphaned --deleted --modified --others
+
+test_done
\ No newline at end of file
diff --git a/t/t3004/cached.expected b/t/t3004/cached.expected
new file mode 100644
index 0000000..6fd0c78
--- /dev/null
+++ b/t/t3004/cached.expected
@@ -0,0 +1,5 @@
+cached
+deleted
+modified
+no-checkout
+orphaned
diff --git a/t/t3004/deleted.expected b/t/t3004/deleted.expected
new file mode 100644
index 0000000..71779d2
--- /dev/null
+++ b/t/t3004/deleted.expected
@@ -0,0 +1 @@
+deleted
diff --git a/t/t3004/everything.expected b/t/t3004/everything.expected
new file mode 100644
index 0000000..6000328
--- /dev/null
+++ b/t/t3004/everything.expected
@@ -0,0 +1,10 @@
+? other
+? result
+H cached
+H deleted
+H modified
+H no-checkout
+H orphaned
+R deleted
+C deleted
+C modified
diff --git a/t/t3004/modified.expected b/t/t3004/modified.expected
new file mode 100644
index 0000000..644a96e
--- /dev/null
+++ b/t/t3004/modified.expected
@@ -0,0 +1,2 @@
+deleted
+modified
diff --git a/t/t3004/no-checkout.expected b/t/t3004/no-checkout.expected
new file mode 100644
index 0000000..b2a429f
--- /dev/null
+++ b/t/t3004/no-checkout.expected
@@ -0,0 +1,2 @@
+no-checkout
+orphaned
diff --git a/t/t3004/orphaned-no-checkout.expected b/t/t3004/orphaned-no-checkout.expected
new file mode 100644
index 0000000..d687ef0
--- /dev/null
+++ b/t/t3004/orphaned-no-checkout.expected
@@ -0,0 +1,3 @@
+- no-checkout
+- orphaned
+O orphaned
diff --git a/t/t3004/orphaned.expected b/t/t3004/orphaned.expected
new file mode 100644
index 0000000..571b267
--- /dev/null
+++ b/t/t3004/orphaned.expected
@@ -0,0 +1 @@
+orphaned
diff --git a/t/t3004/others.expected b/t/t3004/others.expected
new file mode 100644
index 0000000..bf5bf2b
--- /dev/null
+++ b/t/t3004/others.expected
@@ -0,0 +1,2 @@
+other
+result
diff --git a/t/t3004/sparse-cached.expected b/t/t3004/sparse-cached.expected
new file mode 100644
index 0000000..3453483
--- /dev/null
+++ b/t/t3004/sparse-cached.expected
@@ -0,0 +1,3 @@
+cached
+deleted
+modified
diff --git a/t/t3004/sparse-everything.expected b/t/t3004/sparse-everything.expected
new file mode 100644
index 0000000..5df0599
--- /dev/null
+++ b/t/t3004/sparse-everything.expected
@@ -0,0 +1,11 @@
+? other
+? result
+H cached
+H deleted
+H modified
+- no-checkout
+- orphaned
+O orphaned
+R deleted
+C deleted
+C modified
--
1.6.0.2.488.gf604a
^ permalink raw reply related
* [PATCH 5/9] update-index: add --checkout/--no-checkout to update CE_NO_CHECKOUT bit
From: Nguyễn Thái Ngọc Duy @ 2008-10-01 4:04 UTC (permalink / raw)
To: git, Shawn O. Pearce; +Cc: Nguyễn Thái Ngọc Duy
In-Reply-To: <1222833849-22129-5-git-send-email-pclouds@gmail.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
.gitignore | 1 +
Documentation/git-checkout.txt | 3 +-
Documentation/git-update-index.txt | 13 ++++++++++++
Makefile | 2 +-
builtin-update-index.c | 16 ++++++++++++++-
t/t2104-update-index-no-checkout.sh | 36 +++++++++++++++++++++++++++++++++++
test-index-version.c | 14 +++++++++++++
7 files changed, 82 insertions(+), 3 deletions(-)
create mode 100755 t/t2104-update-index-no-checkout.sh
create mode 100644 test-index-version.c
diff --git a/.gitignore b/.gitignore
index bbaf9de..0c35577 100644
--- a/.gitignore
+++ b/.gitignore
@@ -147,6 +147,7 @@ test-date
test-delta
test-dump-cache-tree
test-genrandom
+test-index-version
test-match-trees
test-parse-options
test-path-utils
diff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt
index 4bd9eba..2b344e1 100644
--- a/Documentation/git-checkout.txt
+++ b/Documentation/git-checkout.txt
@@ -196,7 +196,8 @@ to index, it will be marked "checkout" unless sparse patterns are
applied. Unmerged files are always "checkout". When you checkout new
files using "git checkout <file>" they will be automatically marked
"checkout". Other commands such as "git apply" can also checkout new
-files if they are needed.
+files if they are needed. linkgit:git-update-index[1] can be used to
+update "checkout/no-checkout" status in index.
"No-checkout" status is very similar to "assume-unchanged bit"
(see linkgit:git-update-index[1]). The main difference between them
diff --git a/Documentation/git-update-index.txt b/Documentation/git-update-index.txt
index 1d9d81a..ec03e05 100644
--- a/Documentation/git-update-index.txt
+++ b/Documentation/git-update-index.txt
@@ -15,6 +15,7 @@ SYNOPSIS
[--cacheinfo <mode> <object> <file>]\*
[--chmod=(+|-)x]
[--assume-unchanged | --no-assume-unchanged]
+ [--checkout | --no-checkout]
[--ignore-submodules]
[--really-refresh] [--unresolve] [--again | -g]
[--info-only] [--index-info]
@@ -99,6 +100,18 @@ in the index e.g. when merging in a commit;
thus, in case the assumed-untracked file is changed upstream,
you will need to handle the situation manually.
+--checkout::
+--no-checkout::
+ When one of these flags is specified, the object name recorded
+ for the paths are not updated. Instead, these options
+ set and unset the "no-checkout" bit for the paths. This
+ bit is used for marking files for sparse checkout. If
+ a path is marked "no-checkout", then it should not be
+ checked out unless requested by user or needed for a git
+ command to function.
+ See linkgit:git-checkout[1] for more information about
+ sparse checkout.
+
-g::
--again::
Runs 'git-update-index' itself on the paths whose index
diff --git a/Makefile b/Makefile
index e0c03c3..edb33cb 100644
--- a/Makefile
+++ b/Makefile
@@ -1327,7 +1327,7 @@ endif
### Testing rules
-TEST_PROGRAMS = test-chmtime$X test-genrandom$X test-date$X test-delta$X test-sha1$X test-match-trees$X test-parse-options$X test-path-utils$X
+TEST_PROGRAMS = test-chmtime$X test-genrandom$X test-date$X test-delta$X test-sha1$X test-match-trees$X test-parse-options$X test-path-utils$X test-index-version$X
all:: $(TEST_PROGRAMS)
diff --git a/builtin-update-index.c b/builtin-update-index.c
index ae94739..7514aff 100644
--- a/builtin-update-index.c
+++ b/builtin-update-index.c
@@ -24,6 +24,7 @@ static int info_only;
static int force_remove;
static int verbose;
static int mark_valid_only;
+static int mark_no_checkout_only;
#define MARK_FLAG 1
#define UNMARK_FLAG 2
@@ -276,6 +277,11 @@ static void update_one(const char *path, const char *prefix, int prefix_length)
die("Unable to mark file %s", path);
goto free_return;
}
+ if (mark_no_checkout_only) {
+ if (mark_ce_flags(p, CE_NO_CHECKOUT, mark_no_checkout_only == MARK_FLAG))
+ die("Unable to mark file %s", path);
+ goto free_return;
+ }
if (force_remove) {
if (remove_file_from_cache(p))
@@ -386,7 +392,7 @@ static void read_index_info(int line_termination)
}
static const char update_index_usage[] =
-"git update-index [-q] [--add] [--replace] [--remove] [--unmerged] [--refresh] [--really-refresh] [--cacheinfo] [--chmod=(+|-)x] [--assume-unchanged] [--info-only] [--force-remove] [--stdin] [--index-info] [--unresolve] [--again | -g] [--ignore-missing] [-z] [--verbose] [--] <file>...";
+"git update-index [-q] [--add] [--replace] [--remove] [--unmerged] [--refresh] [--really-refresh] [--cacheinfo] [--chmod=(+|-)x] [--assume-unchanged] [--checkout|--no-checkout] [--info-only] [--force-remove] [--stdin] [--index-info] [--unresolve] [--again | -g] [--ignore-missing] [-z] [--verbose] [--] <file>...";
static unsigned char head_sha1[20];
static unsigned char merge_head_sha1[20];
@@ -652,6 +658,14 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
mark_valid_only = UNMARK_FLAG;
continue;
}
+ if (!strcmp(path, "--checkout")) {
+ mark_no_checkout_only = UNMARK_FLAG;
+ continue;
+ }
+ if (!strcmp(path, "--no-checkout")) {
+ mark_no_checkout_only = MARK_FLAG;
+ continue;
+ }
if (!strcmp(path, "--info-only")) {
info_only = 1;
continue;
diff --git a/t/t2104-update-index-no-checkout.sh b/t/t2104-update-index-no-checkout.sh
new file mode 100755
index 0000000..be9f913
--- /dev/null
+++ b/t/t2104-update-index-no-checkout.sh
@@ -0,0 +1,36 @@
+#!/bin/sh
+#
+# Copyright (c) 2008 Nguyễn Thái Ngọc Duy
+#
+
+test_description='git update-index no-checkout bits (a.k.a sparse checkout)'
+
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+ mkdir sub &&
+ touch 1 2 sub/1 sub/2 &&
+ git add 1 2 sub/1 sub/2
+'
+
+test_expect_success 'index is at version 2' '
+ test "$(test-index-version < .git/index)" = 2
+'
+
+test_expect_success 'update-index --no-checkout' '
+ git update-index --no-checkout 1 sub/1 &&
+ test -z "$(git ls-files --sparse|grep 1)"'
+
+test_expect_success 'index is at version 3 after having some no-checkout entries' '
+ test "$(test-index-version < .git/index)" = 3
+'
+
+test_expect_success 'update-index --checkout' '
+ git update-index --checkout 1 sub/1 &&
+ test "$(git ls-files)" = "$(git ls-files --sparse)"'
+
+test_expect_success 'index version is back to 2 when there is no no-checkout entry' '
+ test "$(test-index-version < .git/index)" = 2
+'
+
+test_done
diff --git a/test-index-version.c b/test-index-version.c
new file mode 100644
index 0000000..bfaad9e
--- /dev/null
+++ b/test-index-version.c
@@ -0,0 +1,14 @@
+#include "cache.h"
+
+int main(int argc, const char **argv)
+{
+ struct cache_header hdr;
+ int version;
+
+ memset(&hdr,0,sizeof(hdr));
+ if (read(0, &hdr, sizeof(hdr)) != sizeof(hdr))
+ return 0;
+ version = ntohl(hdr.hdr_version);
+ printf("%d\n", version);
+ return 0;
+}
--
1.6.0.2.488.gf604a
^ permalink raw reply related
* [PATCH 4/9] update-index: refactor mark_valid() in preparation for new options
From: Nguyễn Thái Ngọc Duy @ 2008-10-01 4:04 UTC (permalink / raw)
To: git, Shawn O. Pearce; +Cc: Nguyễn Thái Ngọc Duy
In-Reply-To: <1222833849-22129-4-git-send-email-pclouds@gmail.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
builtin-update-index.c | 24 ++++++++++--------------
1 files changed, 10 insertions(+), 14 deletions(-)
diff --git a/builtin-update-index.c b/builtin-update-index.c
index 417f972..ae94739 100644
--- a/builtin-update-index.c
+++ b/builtin-update-index.c
@@ -24,8 +24,8 @@ static int info_only;
static int force_remove;
static int verbose;
static int mark_valid_only;
-#define MARK_VALID 1
-#define UNMARK_VALID 2
+#define MARK_FLAG 1
+#define UNMARK_FLAG 2
static void report(const char *fmt, ...)
{
@@ -40,19 +40,15 @@ static void report(const char *fmt, ...)
va_end(vp);
}
-static int mark_valid(const char *path)
+static int mark_ce_flags(const char *path, int flag, int mark)
{
int namelen = strlen(path);
int pos = cache_name_pos(path, namelen);
if (0 <= pos) {
- switch (mark_valid_only) {
- case MARK_VALID:
- active_cache[pos]->ce_flags |= CE_VALID;
- break;
- case UNMARK_VALID:
- active_cache[pos]->ce_flags &= ~CE_VALID;
- break;
- }
+ if (mark)
+ active_cache[pos]->ce_flags |= flag;
+ else
+ active_cache[pos]->ce_flags &= ~flag;
cache_tree_invalidate_path(active_cache_tree, path);
active_cache_changed = 1;
return 0;
@@ -276,7 +272,7 @@ static void update_one(const char *path, const char *prefix, int prefix_length)
goto free_return;
}
if (mark_valid_only) {
- if (mark_valid(p))
+ if (mark_ce_flags(p, CE_VALID, mark_valid_only == MARK_FLAG))
die("Unable to mark file %s", path);
goto free_return;
}
@@ -649,11 +645,11 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
continue;
}
if (!strcmp(path, "--assume-unchanged")) {
- mark_valid_only = MARK_VALID;
+ mark_valid_only = MARK_FLAG;
continue;
}
if (!strcmp(path, "--no-assume-unchanged")) {
- mark_valid_only = UNMARK_VALID;
+ mark_valid_only = UNMARK_FLAG;
continue;
}
if (!strcmp(path, "--info-only")) {
--
1.6.0.2.488.gf604a
^ permalink raw reply related
* [PATCH 3/9] ls-files: add options to support sparse checkout
From: Nguyễn Thái Ngọc Duy @ 2008-10-01 4:04 UTC (permalink / raw)
To: git, Shawn O. Pearce; +Cc: Nguyễn Thái Ngọc Duy
In-Reply-To: <1222833849-22129-3-git-send-email-pclouds@gmail.com>
The first option to be introduced is --sparse, which puts ls-files
in "sparse mode". In this mode, cached entries are divided into
- checkout entries: shown by --cached (new behavior with --sparse)
- no-checkout entries: show by --no-checkout (new option)
- orphaned entries: shown by --orphaned (new option)
Orphaned entries are themselves no-checkout ones but for some reasons
still be present in working directory.
While at it, fix "--deleted" running out of checkout area.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
Documentation/git-ls-files.txt | 24 +++++++++++++++++++++-
builtin-ls-files.c | 41 ++++++++++++++++++++++++++++++++++++---
2 files changed, 59 insertions(+), 6 deletions(-)
diff --git a/Documentation/git-ls-files.txt b/Documentation/git-ls-files.txt
index 9f85d60..1de68e2 100644
--- a/Documentation/git-ls-files.txt
+++ b/Documentation/git-ls-files.txt
@@ -10,8 +10,9 @@ SYNOPSIS
--------
[verse]
'git ls-files' [-z] [-t] [-v]
- (--[cached|deleted|others|ignored|stage|unmerged|killed|modified])\*
+ (--[cached|deleted|others|ignored|stage|unmerged|killed|modified|orphaned|no-checkout])\*
(-[c|d|o|i|s|u|k|m])\*
+ [--sparse]
[-x <pattern>|--exclude=<pattern>]
[-X <file>|--exclude-from=<file>]
[--exclude-per-directory=<file>]
@@ -32,7 +33,9 @@ OPTIONS
-------
-c::
--cached::
- Show cached files in the output (default)
+ Show cached files in the output (default). When used with --sparse,
+ show only cached files that are marked "checkout", no-checkout
+ entries will be excluded.
-d::
--deleted::
@@ -72,6 +75,21 @@ OPTIONS
to file/directory conflicts for checkout-index to
succeed.
+--no-checkout::
+ Show no-checkout entries. This option implies --sparse.
+
+--orphaned::
+ Show orphaned entries. Orphaned entries are no-checkout
+ entries that are present in working directory. This option
+ implies --sparse.
+
+--sparse::
+ When --sparse is passed, cached files will be divided into two
+ parts: checkout entries and no-checkout entries.
+ --cached will only show checkout entries.
+ No-checkout entries can be shown using --orphaned or
+ --no-checkout (or both).
+
-z::
\0 line termination on output.
@@ -107,6 +125,8 @@ OPTIONS
Identify the file status with the following tags (followed by
a space) at the start of each line:
H:: cached
+ -:: no-checkout entries
+ O:: orphaned entries
M:: unmerged
R:: removed/deleted
C:: modified/changed
diff --git a/builtin-ls-files.c b/builtin-ls-files.c
index 068f424..873de15 100644
--- a/builtin-ls-files.c
+++ b/builtin-ls-files.c
@@ -20,6 +20,9 @@ static int show_unmerged;
static int show_modified;
static int show_killed;
static int show_valid_bit;
+static int show_orphaned;
+static int show_no_checkout;
+static int sparse_checkout;
static int line_terminator = '\n';
static int prefix_len;
@@ -35,6 +38,8 @@ static const char *tag_removed = "";
static const char *tag_other = "";
static const char *tag_killed = "";
static const char *tag_modified = "";
+static const char *tag_orphaned = "";
+static const char *tag_no_checkout = "";
/*
@@ -235,7 +240,7 @@ static void show_files(struct dir_struct *dir, const char *prefix)
if (show_killed)
show_killed_files(dir);
}
- if (show_cached | show_stage) {
+ if (show_cached | show_stage | show_orphaned | show_no_checkout) {
for (i = 0; i < active_nr; i++) {
struct cache_entry *ce = active_cache[i];
int dtype = ce_to_dtype(ce);
@@ -245,6 +250,16 @@ static void show_files(struct dir_struct *dir, const char *prefix)
continue;
if (ce->ce_flags & CE_UPDATE)
continue;
+ if (sparse_checkout && ce_no_checkout(ce)) {
+ struct stat st;
+ if (show_no_checkout)
+ show_ce_entry(tag_no_checkout, ce);
+ if (show_orphaned && !lstat(ce->name, &st))
+ show_ce_entry(tag_orphaned, ce);
+ continue;
+ }
+ if (!(show_cached | show_stage))
+ continue;
show_ce_entry(ce_stage(ce) ? tag_unmerged : tag_cached, ce);
}
}
@@ -257,7 +272,7 @@ static void show_files(struct dir_struct *dir, const char *prefix)
if (excluded(dir, ce->name, &dtype) != dir->show_ignored)
continue;
err = lstat(ce->name, &st);
- if (show_deleted && err)
+ if (show_deleted && err && ce_checkout(ce))
show_ce_entry(tag_removed, ce);
if (show_modified && ce_modified(ce, &st, 0))
show_ce_entry(tag_modified, ce);
@@ -423,7 +438,8 @@ int report_path_error(const char *ps_matched, const char **pathspec, int prefix_
}
static const char ls_files_usage[] =
- "git ls-files [-z] [-t] [-v] (--[cached|deleted|others|stage|unmerged|killed|modified])* "
+ "git ls-files [-z] [-t] [-v] (--[cached|deleted|others|stage|unmerged|killed|modified|orphaned|no-checkout])* "
+ "[ --sparse ] "
"[ --ignored ] [--exclude=<pattern>] [--exclude-from=<file>] "
"[ --exclude-per-directory=<filename> ] [--exclude-standard] "
"[--full-name] [--abbrev] [--] [<file>]*";
@@ -457,6 +473,8 @@ int cmd_ls_files(int argc, const char **argv, const char *prefix)
tag_modified = "C ";
tag_other = "? ";
tag_killed = "K ";
+ tag_orphaned = "O ";
+ tag_no_checkout = "- ";
if (arg[1] == 'v')
show_valid_bit = 1;
continue;
@@ -465,6 +483,21 @@ int cmd_ls_files(int argc, const char **argv, const char *prefix)
show_cached = 1;
continue;
}
+ if (!strcmp(arg, "--sparse")) {
+ sparse_checkout = 1;
+ continue;
+ }
+ if (!strcmp(arg, "--orphaned")) {
+ show_orphaned = 1;
+ sparse_checkout = 1;
+ require_work_tree = 1;
+ continue;
+ }
+ if (!strcmp(arg, "--no-checkout")) {
+ show_no_checkout = 1;
+ sparse_checkout = 1;
+ continue;
+ }
if (!strcmp(arg, "-d") || !strcmp(arg, "--deleted")) {
show_deleted = 1;
continue;
@@ -593,7 +626,7 @@ int cmd_ls_files(int argc, const char **argv, const char *prefix)
/* With no flags, we default to showing the cached files */
if (!(show_stage | show_deleted | show_others | show_unmerged |
- show_killed | show_modified))
+ show_killed | show_modified | show_orphaned | show_no_checkout))
show_cached = 1;
read_cache();
--
1.6.0.2.488.gf604a
^ permalink raw reply related
* [PATCH 2/9] Introduce CE_NO_CHECKOUT bit
From: Nguyễn Thái Ngọc Duy @ 2008-10-01 4:04 UTC (permalink / raw)
To: git, Shawn O. Pearce; +Cc: Nguyễn Thái Ngọc Duy
In-Reply-To: <1222833849-22129-2-git-send-email-pclouds@gmail.com>
This bit is the basis of sparse checkout. If this bit is on, the entry
is outside sparse checkout and therefore should be ignored (similar
to CE_VALID)
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
Documentation/git-checkout.txt | 33 +++++++++++++++++++++++++++++++++
cache.h | 10 +++++++++-
read-cache.c | 6 +++---
3 files changed, 45 insertions(+), 4 deletions(-)
diff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt
index 82e154d..4bd9eba 100644
--- a/Documentation/git-checkout.txt
+++ b/Documentation/git-checkout.txt
@@ -171,6 +171,39 @@ the reflog for HEAD where you were, e.g.
$ git log -g -2 HEAD
------------
+Sparse checkout
+---------------
+
+Normally when you checkout a branch, your working directory
+will be fully populated. In some situations, you just need to
+work on certain files, no full checkout is needed. Sparse
+checkout is a mode that limits the checkout area according to your
+needs. With sparse checkout, you can work on a single file, a
+collection of files, a subdirectory or a collection of separated
+subdirectories.
+
+Because sparse checkout uses a new index format, it will be
+incompatible with git prior to 1.6.0 regarding worktree operations.
+Operations that only need access to the repository itself, such as
+clone, push, or pull/fetch from another (normal) repository... should
+not be affected by sparse checkout.
+
+In sparse checkout mode, checkout status of every files in your
+working directory will be recorded in index. If a file is marked
+"no-checkout", it means that file is not needed to be present in
+working directory by user or any git command. When a new file is added
+to index, it will be marked "checkout" unless sparse patterns are
+applied. Unmerged files are always "checkout". When you checkout new
+files using "git checkout <file>" they will be automatically marked
+"checkout". Other commands such as "git apply" can also checkout new
+files if they are needed.
+
+"No-checkout" status is very similar to "assume-unchanged bit"
+(see linkgit:git-update-index[1]). The main difference between them
+is "assume unchanged" bit just ignores corresponding files in working
+directory while sparse checkout goes a bit farther, remove those files
+when it is safe to do so.
+
EXAMPLES
--------
diff --git a/cache.h b/cache.h
index 5180879..f13ddbc 100644
--- a/cache.h
+++ b/cache.h
@@ -170,10 +170,11 @@ struct cache_entry {
/*
* Extended on-disk flags
*/
+#define CE_NO_CHECKOUT 0x40000000
/* CE_EXTENDED2 is for future extension */
#define CE_EXTENDED2 0x80000000
-#define CE_EXTENDED_FLAGS (0)
+#define CE_EXTENDED_FLAGS (CE_NO_CHECKOUT)
/*
* Safeguard to avoid saving wrong flags:
@@ -185,6 +186,9 @@ struct cache_entry {
#error "CE_EXTENDED_FLAGS out of range"
#endif
+/* "Assume unchanged" mask */
+#define CE_VALID_MASK (CE_VALID | CE_NO_CHECKOUT)
+
/*
* Copy the sha1 and stat state of a cache entry from one to
* another. But we never change the name, or the hash state!
@@ -222,6 +226,10 @@ static inline size_t ce_namelen(const struct cache_entry *ce)
ondisk_cache_entry_size(ce_namelen(ce)))
#define ce_stage(ce) ((CE_STAGEMASK & (ce)->ce_flags) >> CE_STAGESHIFT)
#define ce_uptodate(ce) ((ce)->ce_flags & CE_UPTODATE)
+#define ce_no_checkout(ce) ((ce)->ce_flags & CE_NO_CHECKOUT)
+#define ce_checkout(ce) (!ce_no_checkout(ce))
+#define ce_mark_no_checkout(ce) ((ce)->ce_flags |= CE_NO_CHECKOUT)
+#define ce_mark_checkout(ce) ((ce)->ce_flags &= ~CE_NO_CHECKOUT)
#define ce_mark_uptodate(ce) ((ce)->ce_flags |= CE_UPTODATE)
#define ce_permissions(mode) (((mode) & 0100) ? 0755 : 0644)
diff --git a/read-cache.c b/read-cache.c
index 667c36b..e965a4c 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -254,7 +254,7 @@ int ie_match_stat(const struct index_state *istate,
* If it's marked as always valid in the index, it's
* valid whatever the checked-out copy says.
*/
- if (!ignore_valid && (ce->ce_flags & CE_VALID))
+ if (!ignore_valid && (ce->ce_flags & CE_VALID_MASK))
return 0;
changed = ce_match_stat_basic(ce, st);
@@ -962,10 +962,10 @@ static struct cache_entry *refresh_cache_ent(struct index_state *istate,
return ce;
/*
- * CE_VALID means the user promised us that the change to
+ * CE_VALID_MASK means the user promised us that the change to
* the work tree does not matter and told us not to worry.
*/
- if (!ignore_valid && (ce->ce_flags & CE_VALID)) {
+ if (!ignore_valid && (ce->ce_flags & CE_VALID_MASK)) {
ce_mark_uptodate(ce);
return ce;
}
--
1.6.0.2.488.gf604a
^ permalink raw reply related
* [PATCH 1/9] Extend index to save more flags
From: Nguyễn Thái Ngọc Duy @ 2008-10-01 4:04 UTC (permalink / raw)
To: git, Shawn O. Pearce; +Cc: Nguyễn Thái Ngọc Duy
In-Reply-To: <1222833849-22129-1-git-send-email-pclouds@gmail.com>
The on-disk format of index only saves 16 bit flags, nearly all have
been used. The last bit (CE_EXTENDED) is used to for future extension.
This patch extends index entry format to save more flags in future.
The new entry format will be used when CE_EXTENDED bit is 1.
Because older implementation may not understand CE_EXTENDED bit and
misread the new format, if there is any extended entry in index, index
header version will turn 3, which makes it incompatible for older git.
If there is none, header version will return to 2 again.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
cache.h | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++----
read-cache.c | 51 +++++++++++++++++++++++++++++++++++++++++----------
2 files changed, 95 insertions(+), 14 deletions(-)
diff --git a/cache.h b/cache.h
index f4b8ddf..5180879 100644
--- a/cache.h
+++ b/cache.h
@@ -109,6 +109,26 @@ struct ondisk_cache_entry {
char name[FLEX_ARRAY]; /* more */
};
+/*
+ * This struct is used when CE_EXTENDED bit is 1
+ * The struct must match ondisk_cache_entry exactly from
+ * ctime till flags
+ */
+struct ondisk_cache_entry_extended {
+ struct cache_time ctime;
+ struct cache_time mtime;
+ unsigned int dev;
+ unsigned int ino;
+ unsigned int mode;
+ unsigned int uid;
+ unsigned int gid;
+ unsigned int size;
+ unsigned char sha1[20];
+ unsigned short flags;
+ unsigned short flags2;
+ char name[FLEX_ARRAY]; /* more */
+};
+
struct cache_entry {
unsigned int ce_ctime;
unsigned int ce_mtime;
@@ -130,7 +150,15 @@ struct cache_entry {
#define CE_VALID (0x8000)
#define CE_STAGESHIFT 12
-/* In-memory only */
+/*
+ * Range 0xFFFF0000 in ce_flags is divided into
+ * two parts: in-memory flags and on-disk ones.
+ * Flags in CE_EXTENDED_FLAGS will get saved on-disk
+ * if you want to save a new flag, add it in
+ * CE_EXTENDED_FLAGS
+ *
+ * In-memory only flags
+ */
#define CE_UPDATE (0x10000)
#define CE_REMOVE (0x20000)
#define CE_UPTODATE (0x40000)
@@ -140,6 +168,24 @@ struct cache_entry {
#define CE_UNHASHED (0x200000)
/*
+ * Extended on-disk flags
+ */
+/* CE_EXTENDED2 is for future extension */
+#define CE_EXTENDED2 0x80000000
+
+#define CE_EXTENDED_FLAGS (0)
+
+/*
+ * Safeguard to avoid saving wrong flags:
+ * - CE_EXTENDED2 won't get saved until its semantic is known
+ * - Bits in 0x0000FFFF have been saved in ce_flags already
+ * - Bits in 0x003F0000 are currently in-memory flags
+ */
+#if CE_EXTENDED_FLAGS & 0x803FFFFF
+#error "CE_EXTENDED_FLAGS out of range"
+#endif
+
+/*
* Copy the sha1 and stat state of a cache entry from one to
* another. But we never change the name, or the hash state!
*/
@@ -171,7 +217,9 @@ static inline size_t ce_namelen(const struct cache_entry *ce)
}
#define ce_size(ce) cache_entry_size(ce_namelen(ce))
-#define ondisk_ce_size(ce) ondisk_cache_entry_size(ce_namelen(ce))
+#define ondisk_ce_size(ce) (((ce)->ce_flags & CE_EXTENDED) ? \
+ ondisk_cache_entry_extended_size(ce_namelen(ce)) : \
+ ondisk_cache_entry_size(ce_namelen(ce)))
#define ce_stage(ce) ((CE_STAGEMASK & (ce)->ce_flags) >> CE_STAGESHIFT)
#define ce_uptodate(ce) ((ce)->ce_flags & CE_UPTODATE)
#define ce_mark_uptodate(ce) ((ce)->ce_flags |= CE_UPTODATE)
@@ -214,8 +262,10 @@ static inline int ce_to_dtype(const struct cache_entry *ce)
(S_ISREG(mode) ? (S_IFREG | ce_permissions(mode)) : \
S_ISLNK(mode) ? S_IFLNK : S_ISDIR(mode) ? S_IFDIR : S_IFGITLINK)
-#define cache_entry_size(len) ((offsetof(struct cache_entry,name) + (len) + 8) & ~7)
-#define ondisk_cache_entry_size(len) ((offsetof(struct ondisk_cache_entry,name) + (len) + 8) & ~7)
+#define flexible_size(STRUCT,len) ((offsetof(struct STRUCT,name) + (len) + 8) & ~7)
+#define cache_entry_size(len) flexible_size(cache_entry,len)
+#define ondisk_cache_entry_size(len) flexible_size(ondisk_cache_entry,len)
+#define ondisk_cache_entry_extended_size(len) flexible_size(ondisk_cache_entry_extended,len)
struct index_state {
struct cache_entry **cache;
diff --git a/read-cache.c b/read-cache.c
index c5a8659..667c36b 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -1096,7 +1096,7 @@ static int verify_hdr(struct cache_header *hdr, unsigned long size)
if (hdr->hdr_signature != htonl(CACHE_SIGNATURE))
return error("bad signature");
- if (hdr->hdr_version != htonl(2))
+ if (hdr->hdr_version != htonl(2) && hdr->hdr_version != htonl(3))
return error("bad index version");
SHA1_Init(&c);
SHA1_Update(&c, hdr, size - 20);
@@ -1131,6 +1131,7 @@ int read_index(struct index_state *istate)
static void convert_from_disk(struct ondisk_cache_entry *ondisk, struct cache_entry *ce)
{
size_t len;
+ const char *name;
ce->ce_ctime = ntohl(ondisk->ctime.sec);
ce->ce_mtime = ntohl(ondisk->mtime.sec);
@@ -1143,19 +1144,31 @@ static void convert_from_disk(struct ondisk_cache_entry *ondisk, struct cache_en
/* On-disk flags are just 16 bits */
ce->ce_flags = ntohs(ondisk->flags);
- /* For future extension: we do not understand this entry yet */
- if (ce->ce_flags & CE_EXTENDED)
- die("Unknown index entry format");
hashcpy(ce->sha1, ondisk->sha1);
len = ce->ce_flags & CE_NAMEMASK;
+
+ if (ce->ce_flags & CE_EXTENDED) {
+ struct ondisk_cache_entry_extended *ondisk2;
+ int extended_flags;
+ ondisk2 = (struct ondisk_cache_entry_extended *)ondisk;
+ extended_flags = ntohs(ondisk2->flags2) << 16;
+ /* We do not yet understand any bit out of CE_EXTENDED_FLAGS */
+ if (extended_flags & ~CE_EXTENDED_FLAGS)
+ die("Unknown index entry format %08x", extended_flags);
+ ce->ce_flags |= extended_flags;
+ name = ondisk2->name;
+ }
+ else
+ name = ondisk->name;
+
if (len == CE_NAMEMASK)
- len = strlen(ondisk->name);
+ len = strlen(name);
/*
* NEEDSWORK: If the original index is crafted, this copy could
* go unchecked.
*/
- memcpy(ce->name, ondisk->name, len + 1);
+ memcpy(ce->name, name, len + 1);
}
static inline size_t estimate_cache_size(size_t ondisk_size, unsigned int entries)
@@ -1415,6 +1428,7 @@ static int ce_write_entry(SHA_CTX *c, int fd, struct cache_entry *ce)
{
int size = ondisk_ce_size(ce);
struct ondisk_cache_entry *ondisk = xcalloc(1, size);
+ char *name;
ondisk->ctime.sec = htonl(ce->ce_ctime);
ondisk->ctime.nsec = 0;
@@ -1428,7 +1442,15 @@ static int ce_write_entry(SHA_CTX *c, int fd, struct cache_entry *ce)
ondisk->size = htonl(ce->ce_size);
hashcpy(ondisk->sha1, ce->sha1);
ondisk->flags = htons(ce->ce_flags);
- memcpy(ondisk->name, ce->name, ce_namelen(ce));
+ if (ce->ce_flags & CE_EXTENDED) {
+ struct ondisk_cache_entry_extended *ondisk2;
+ ondisk2 = (struct ondisk_cache_entry_extended *)ondisk;
+ ondisk2->flags2 = htons((ce->ce_flags & CE_EXTENDED_FLAGS) >> 16);
+ name = ondisk2->name;
+ }
+ else
+ name = ondisk->name;
+ memcpy(name, ce->name, ce_namelen(ce));
return ce_write(c, fd, ondisk, size);
}
@@ -1437,16 +1459,25 @@ int write_index(const struct index_state *istate, int newfd)
{
SHA_CTX c;
struct cache_header hdr;
- int i, err, removed;
+ int i, err, removed, extended;
struct cache_entry **cache = istate->cache;
int entries = istate->cache_nr;
- for (i = removed = 0; i < entries; i++)
+ for (i = removed = extended = 0; i < entries; i++) {
if (cache[i]->ce_flags & CE_REMOVE)
removed++;
+ /* reduce extended entries if possible */
+ cache[i]->ce_flags &= ~CE_EXTENDED;
+ if (cache[i]->ce_flags & CE_EXTENDED_FLAGS) {
+ extended++;
+ cache[i]->ce_flags |= CE_EXTENDED;
+ }
+ }
+
hdr.hdr_signature = htonl(CACHE_SIGNATURE);
- hdr.hdr_version = htonl(2);
+ /* for extended format, increase version so older git won't try to read it */
+ hdr.hdr_version = htonl(extended ? 3 : 2);
hdr.hdr_entries = htonl(entries - removed);
SHA1_Init(&c);
--
1.6.0.2.488.gf604a
^ permalink raw reply related
* [PATCH/resent 0/9] Sparse checkout (first half)
From: Nguyễn Thái Ngọc Duy @ 2008-10-01 4:04 UTC (permalink / raw)
To: git, Shawn O. Pearce; +Cc: Nguyễn Thái Ngọc Duy
This is the first half of the series, making git ready for sparse
checkout. The only difference from the last (first half) sent
series is safeguard bitmask fix in 1/9
Nguyá»
n Thái Ngá»c Duy (9):
Extend index to save more flags
Introduce CE_NO_CHECKOUT bit
ls-files: add options to support sparse checkout
update-index: refactor mark_valid() in preparation for new options
update-index: add --checkout/--no-checkout to update CE_NO_CHECKOUT
bit
ls-files: Add tests for --sparse and friends
Prevent diff machinery from examining worktree outside sparse
checkout
checkout_entry(): CE_NO_CHECKOUT on checked out entries.
grep: skip files outside sparse checkout area
.gitignore | 1 +
Documentation/git-checkout.txt | 34 +++++++++++++++++
Documentation/git-grep.txt | 4 +-
Documentation/git-ls-files.txt | 24 +++++++++++-
Documentation/git-update-index.txt | 13 ++++++
Makefile | 2 +-
builtin-grep.c | 7 +++-
builtin-ls-files.c | 41 ++++++++++++++++++--
builtin-update-index.c | 40 ++++++++++++-------
cache.h | 66 +++++++++++++++++++++++++++++++--
diff-lib.c | 5 +-
diff.c | 4 +-
entry.c | 1 +
read-cache.c | 57 ++++++++++++++++++++++------
t/t2104-update-index-no-checkout.sh | 36 ++++++++++++++++++
t/t3004-ls-files-sparse.sh | 40 ++++++++++++++++++++
t/t3004/cached.expected | 5 ++
t/t3004/deleted.expected | 1 +
t/t3004/everything.expected | 10 +++++
t/t3004/modified.expected | 2 +
t/t3004/no-checkout.expected | 2 +
t/t3004/orphaned-no-checkout.expected | 3 +
t/t3004/orphaned.expected | 1 +
t/t3004/others.expected | 2 +
t/t3004/sparse-cached.expected | 3 +
t/t3004/sparse-everything.expected | 11 +++++
test-index-version.c | 14 +++++++
27 files changed, 385 insertions(+), 44 deletions(-)
create mode 100755 t/t2104-update-index-no-checkout.sh
create mode 100755 t/t3004-ls-files-sparse.sh
create mode 100644 t/t3004/cached.expected
create mode 100644 t/t3004/deleted.expected
create mode 100644 t/t3004/everything.expected
create mode 100644 t/t3004/modified.expected
create mode 100644 t/t3004/no-checkout.expected
create mode 100644 t/t3004/orphaned-no-checkout.expected
create mode 100644 t/t3004/orphaned.expected
create mode 100644 t/t3004/others.expected
create mode 100644 t/t3004/sparse-cached.expected
create mode 100644 t/t3004/sparse-everything.expected
create mode 100644 test-index-version.c
^ permalink raw reply
* Re: [PATCH, resent] fix openssl headers conflicting with custom SHA1 implementations
From: Jeff King @ 2008-10-01 3:47 UTC (permalink / raw)
To: Shawn O. Pearce; +Cc: Nicolas Pitre, git
In-Reply-To: <20080930205122.GO21310@spearce.org>
On Tue, Sep 30, 2008 at 01:51:22PM -0700, Shawn O. Pearce wrote:
> Yea, its a bit ugly due to the rats nest of system includes.
> Right now I don't see how we can include your patch, it breaks a
> major platform for us. But obviously my "fix" is also bogus and
> won't get ARM working again.
>
> Any other ideas we can try? 'cause I don't have any right now. :-|
I think you have an inherent conflict. Using openssl is going to end up
including their SHA definition, and we clearly can't include both..
Right now, you are trying to find a way to squeak by because imap-send
is the only thing that uses openssl, and it doesn't actually need our
SHA definition. But any solution that exploits that characteristic is
prone to failing later, when something _does_ need both of them.
You _could_ do something hack-ish like defining HEADER_SHA_H to avoid
theirs being loaded, but:
1. You are relying on their header guard never changing.
2. This actually leaves room for subtle problems, since some code
thinks a SHA_CTX is defined one way, and other code thinks it is
defined another way. If one piece of code passes a SHA_CTX to the
other (say another part of openssl), you risk invoking nasal
demons.
So I think the right way is probably to use a level of indirection. Turn
the ARM implementation into
void ARM_SHA1_Init()
and
#define SHA1_Init ARM_SHA1_Init
making sure not to allow such a macro to be in effect when including
openssl. This is similar to the way we override compat functions.
You can make it even simpler by just having all code call git_SHA1_Init,
and that will expand to whichever implementation has been chosen.
-Peff
^ permalink raw reply
* Re: What's cooking in git.git (Sep 2008, #05; Mon, 29)
From: Jeff King @ 2008-10-01 3:31 UTC (permalink / raw)
To: Shawn O. Pearce; +Cc: git
In-Reply-To: <20080930183759.GF21310@spearce.org>
On Tue, Sep 30, 2008 at 11:37:59AM -0700, Shawn O. Pearce wrote:
> * mw/sendemail (Mon Sep 29 12:41:06 2008 -0500) 8 commits
> - send-email: signedoffcc -> signedoffbycc, but handle both
> - Docs: send-email: Create logical groupings for man text
> - Docs: send-email: Remove unnecessary config variable description
> - Docs: send-email: --chain_reply_to -> --[no-]chain-reply-to
> - send-email: change --no-validate to boolean --[no-]validate
> - Docs: send-email: Man page option ordering
> - Docs: send-email usage text much sexier
> - Docs: send-email's usage text and man page mention same options
>
> This series has already gone through 3 iterations before I could
> start to carry it in-tree. I haven't had a chance to read it yet
> myself, so its sitting around in `pu` for futher review.
I think today's revision is probably ready for 'next'.
> * pb/commit-where (Mon Sep 8 01:05:41 2008 +0200) 1 commit
> + builtin-commit.c: show on which branch a commit was added
>
> [jc: Tentatively kicked back to "still cooking" status after
> Jeff voiced his annoyance. I personally do not like making this
> multi-line as Jeff suggested as an alternative (the message already
> is too verbose to my taste).]
>
> Agree with Junio. Hence its still here.
Definitely leave this out of master for now. I think there is some good
discussion going on, and I am hoping to get comments on Andreas' or my
patches.
-Peff
^ permalink raw reply
* Re: [PATCH 3/9] Docs: send-email: Man page option ordering
From: Jeff King @ 2008-10-01 3:27 UTC (permalink / raw)
To: Michael Witten; +Cc: spearce, git
In-Reply-To: <1222779512-58936-3-git-send-email-mfwitten@mit.edu>
On Tue, Sep 30, 2008 at 07:58:26AM -0500, Michael Witten wrote:
> Now the man page lists the options in alphabetical
> order (in terms of the 'main' part of an option's
> name).
>
> Signed-off-by: Michael Witten <mfwitten@mit.edu>
After following this series through a number of revisions, it looks good
to me now. So
Acked-by: Jeff King <peff@peff.net>
for the whole series.
I believe this particular patch is probably redundant, since 8/9 just
re-orders the manpage again later. So it could be dropped if somebody
feels like doing the work to rebase the later patches.
-Peff
^ permalink raw reply
* Re: Git config not expanding user home directories
From: Jeff King @ 2008-10-01 3:22 UTC (permalink / raw)
To: Jakub Narebski; +Cc: Andreas Ericsson, Tom Lanyon, Karl Chen, Git Mailinglist
In-Reply-To: <m33ajhsw24.fsf@localhost.localdomain>
On Tue, Sep 30, 2008 at 04:38:46AM -0700, Jakub Narebski wrote:
> There was a patch send to git mailing list adding basic '~' support
> (I think via $ENV{HOME}), and IIRC even ~user support. I don't know
> what happened to those patches (check mailing list archive), but
> most probably it was not accepted because it didn't provide a way
> for scripts to use this functionality, for example via --path option.
There were several rounds, and I thought it was shaping up, but then
no more rounds came. I assume that Karl lost interest (or perhaps we
nitpicked him to death), but I thought at the end of the thread Junio
laid out a plan for the next revision. I guess nobody cared enough about
the feature to implement it after that (though I think I found the final
version acceptable with a minor documentation tweak, I think Junio laid
out a cleaner approach).
The last patch is here, with one of the replies from Junio giving the
aforementioned plan:
http://mid.gmane.org/quack.20080829T0229.lthhc94rwyr_-_@roar.cs.berkeley.edu
-Peff
^ permalink raw reply
* Re: [PATCH] Builtin-commit: show on which branch a commit was added
From: Jeff King @ 2008-10-01 3:14 UTC (permalink / raw)
To: Andreas Ericsson
Cc: Wincent Colaiuta, Pieter de Bie, Junio C Hamano, Git Mailinglist
In-Reply-To: <48E1F87D.2010906@op5.se>
On Tue, Sep 30, 2008 at 11:59:25AM +0200, Andreas Ericsson wrote:
> I agree. Obvious solution is to do
>
> subj_len = term_width - (strlen(cruft) + strlen(branch_name))
I think the difficulty is that the printing is sometimes done by our
printf and sometimes by log_tree_commit, and there isn't a convenient
way to hook into log_tree_commit to postprocess the formatted output.
> where strlen(cruft) is just 8 less if we drop 'commit ' from the
> cases. See the patch I just sent though. I sort of like that one.
I like it much better than what is on next (and I thought your commit
message summed up the issue nicely), but...
> Another way would be to write
> <branch>: Created <hash>: "subject line..."
I think I like this even better. My only concern is that many programs
say "program: some error", so you could potentially have a confusing
branch name. But I personally have never used a branch name that would
cause such confusion.
> As <hash> will very, very rarely match anything the user would put
> in his/her commit message themselves. Quoting the subject is probably
> a nice touch, and it can make sense to put it last as it's the least
> interesting of the things we print. Ah well. I'll just await commentary
> on the patch I've already sent before I go ahead and do something like
> that.
Here is a patch for that format on top of next (the patch between this
and what is in master is even more simple, since we are mostly removing
Pieter's helper function).
---
diff --git a/builtin-commit.c b/builtin-commit.c
index 917f638..9954a81 100644
--- a/builtin-commit.c
+++ b/builtin-commit.c
@@ -876,41 +876,17 @@ int cmd_status(int argc, const char **argv, const char *prefix)
rollback_index_files();
return commitable ? 0 : 1;
}
-static char *get_commit_format_string(void)
-{
- unsigned char sha[20];
- const char *head = resolve_ref("HEAD", sha, 0, NULL);
- struct strbuf buf = STRBUF_INIT;
-
- strbuf_addstr(&buf, "format:%h");
-
- /* Are we on a detached HEAD? */
- if (!strcmp("HEAD", head))
- strbuf_addstr(&buf, " on detached HEAD");
- else if (!prefixcmp(head, "refs/heads/")) {
- const char *cp;
- strbuf_addstr(&buf, " on ");
- for (cp = head + 11; *cp; cp++) {
- if (*cp == '%')
- strbuf_addstr(&buf, "%x25");
- else
- strbuf_addch(&buf, *cp);
- }
- }
- strbuf_addstr(&buf, ": %s");
-
- return strbuf_detach(&buf, NULL);
-}
-
static void print_summary(const char *prefix, const unsigned char *sha1)
{
struct rev_info rev;
struct commit *commit;
- char *format = get_commit_format_string();
+ static const char *format = "format:%h: \"%s\"";
+ unsigned char junk_sha1[20];
+ const char *head = resolve_ref("HEAD", junk_sha1, 0, NULL);
commit = lookup_commit(sha1);
if (!commit)
die("couldn't look up newly created commit");
if (!commit || parse_commit(commit))
@@ -931,19 +907,20 @@ static void print_summary(const char *prefix, const unsigned char *sha1)
rev.diffopt.detect_rename = 1;
rev.diffopt.rename_limit = 100;
rev.diffopt.break_opt = 0;
diff_setup_done(&rev.diffopt);
- printf("Created %scommit ", initial_commit ? "initial " : "");
+ printf("%s%s: created ",
+ !prefixcmp(head, "refs/heads/") ? head + 11 : head,
+ initial_commit ? " (initial)" : "");
if (!log_tree_commit(&rev, commit)) {
struct strbuf buf = STRBUF_INIT;
format_commit_message(commit, format + 7, &buf, DATE_NORMAL);
printf("%s\n", buf.buf);
strbuf_release(&buf);
}
- free(format);
}
static int git_commit_config(const char *k, const char *v, void *cb)
{
if (!strcmp(k, "commit.template"))
^ permalink raw reply related
* Re: [GUILT] Use git_editor
From: Josef 'Jeff' Sipek @ 2008-10-01 2:31 UTC (permalink / raw)
To: Alan Jenkins; +Cc: git
In-Reply-To: <48E27366.3080503@tuffmail.co.uk>
On Tue, Sep 30, 2008 at 07:43:50PM +0100, Alan Jenkins wrote:
> Signed-off-by: Alan Jenkins <alan-jenkins@tuffmail.co.uk>
Applied.
Thanks,
Josef 'Jeff' Sipek.
--
Don't drink and derive. Alcohol and algebra don't mix.
^ 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