* Re: cygwin: push/pull takes very long time
From: Alex Riesen @ 2006-03-03 9:10 UTC (permalink / raw)
To: Christopher Faylor; +Cc: Git Mailing List
In-Reply-To: <20060303002806.GB7497@trixie.casa.cgf.cx>
On 3/3/06, Christopher Faylor <me@cgf.cx> wrote:
> On Thu, Mar 02, 2006 at 10:54:08PM +0100, Alex Riesen wrote:
> >Alex Riesen, Thu, Mar 02, 2006 18:09:23 +0100:
> >>I'll cleanup the profiling code and send it as well soon (I had to
> >>instrument x*alloc).
> >
> >This is not exactly the same. It counts free as well, even if that is
> >not really interesting - there are places were there is more frees than
> >allocs. Probably something missed or a result coming from libc.
> >
> >Also it is _not_ the code I used for windows. I had to have a global
> >variable for argv[0], which needs modification of all main()s, which
> >gets too easily out of sync.
>
> I wasn't following this discussion closely so maybe this is useless
> information, but for Cygwin you can either use the undocumented global
> __argv or you can use /proc/cmdline. /proc/self/cmdline is going to be
> pretty slow, however.
Oh, thanks. The speed is of no problem here: it's in atexit callback.
> It looks like pure Windows console apps define _argv in stdlib.h also
> but I've never used this and don't know if it is what it looks like.
It works as usual argv. I used "char **__argv", got the message from linker:
Info: resolving ___argv by linking to __imp____argv (auto-import)
which I almost expected.
^ permalink raw reply
* Re: [PATCH] annotate should number lines starting with 1
From: Junio C Hamano @ 2006-03-03 7:09 UTC (permalink / raw)
To: Luck, Tony; +Cc: git, Martin Langhoff
In-Reply-To: <200603022327.k22NRVek023304@agluck-lia64.sc.intel.com>
"Luck, Tony" <tony.luck@intel.com> writes:
> C programmers are well used to counting from zero, but every
> other text file tool starts counting from 1.
Thanks.
I agree with this patch 100%, so I am going to take this patch.
But git-cvsserver might need some adjustments.
Martin?
^ permalink raw reply
* Re: [PATCH] annotate should number lines starting with 1
From: Junio C Hamano @ 2006-03-03 7:09 UTC (permalink / raw)
To: Luck, Tony; +Cc: git, Martin Langhoff
In-Reply-To: <200603022327.k22NRVek023304@agluck-lia64.sc.intel.com>
"Luck, Tony" <tony.luck@intel.com> writes:
> C programmers are well used to counting from zero, but every
> other text file tool starts counting from 1.
Thanks.
I agree with this patch 100%, so I am going to take this patch.
But git-cvsserver might need some adjustments.
Martin?
^ permalink raw reply
* Re: [PATCH 1/3] cg-mv doesn't work with bash 3.1.7 due to excessive quotes
From: Junio C Hamano @ 2006-03-03 5:27 UTC (permalink / raw)
To: Pavel Roskin; +Cc: git
In-Reply-To: <20060303011154.14619.71590.stgit@dv.roinet.com>
Pavel Roskin <proski@gnu.org> writes:
> - ARGS2["${#ARGS2[@]}"]="$_git_relpath${arg%/}"
> + ARGS2[${#ARGS2[@]}]="$_git_relpath${arg%/}"
Is this an application bug? It looks like a workaround for a
bug in the shell...
Not that I care too much either way -- I do not use shell arrays
myself ;-).
^ permalink raw reply
* Re: [PATCH] Add --temp and --stage=all options to checkout-index.
From: Junio C Hamano @ 2006-03-03 5:25 UTC (permalink / raw)
To: Shawn Pearce; +Cc: git
In-Reply-To: <20060303012032.GC6321@spearce.org>
Shawn Pearce <spearce@spearce.org> writes:
> Unfortunately this change lead me down a path which changed the core
> checkout code also used by apply and read-tree.
... which makes it much harder to swallow without careful
inspection X-<.
I think the patch only appears much bigger than it actually is,
because of reindentation effect coming from "if (to-temp-file)".
However, I am too tired to carefully examine them tonight, so I
hope you do not mind my postponing this for now.
^ permalink raw reply
* Re: [PATCH] fmt-merge-msg: avoid open "-|" list form for Perl 5.6
From: Linus Torvalds @ 2006-03-03 1:52 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7vveuw48uw.fsf@assigned-by-dhcp.cox.net>
On Thu, 2 Mar 2006, Junio C Hamano wrote:
>
> Linus Torvalds <torvalds@osdl.org> writes:
>
> > Yeah, I actually looked at a few examples, so I knew what it was basically
> > trying to do, and then I ignored it as not interesting to the exercise,
> > which was to abuse the new revision listing library in interesting ways by
> > calling it multiple times.
>
> Abuse is exactly the word. The reason it is an abuse is exactly
> why you said "... but to fix it you'd have to actualyl walk the
> parent list yourself, rather than letting get_revision do it all
> for you." Which relates to the fact that object.c layer is not
> designed to be used multiple times...
>
> Maybe we want to make object.c layer reusable first?
No, the "abuse" is actually very much done that way on purpose. It's a bit
strange to do "incremental" prepare_revision_walk() calls, but it all
comes from the fact that the object structures are "persistent" across the
calls, even if we remove them from the list when we walk them.
So it's strange, but that was kind of part of the reason for doing it.
It's a _good_ strangeness.
The thing about handling commits that were already in another branch but
weren't shown is different: the way to handle that is to generate the
_whole_ revision list in one go - instead of incrementally - and then for
each branch you merge you show the top 10 "not yet shown" commits.
IOW, that thing would never use "get_revision()" at all, but would instead
depend on "prepare_revision_walk()" generating the whole tree, and then
you just walk the parent pointers from the branch heads by hand, marking
then "seen" as you print them.
So the object layer and the revision parsing actually does exactly the
right thing, you just have to decide on how to use them..
Linus
^ permalink raw reply
* Re: [PATCH] fmt-merge-msg: avoid open "-|" list form for Perl 5.6
From: Junio C Hamano @ 2006-03-03 1:25 UTC (permalink / raw)
To: Linus Torvalds; +Cc: git
In-Reply-To: <Pine.LNX.4.64.0603021643560.22647@g5.osdl.org>
Linus Torvalds <torvalds@osdl.org> writes:
> Yeah, I actually looked at a few examples, so I knew what it was basically
> trying to do, and then I ignored it as not interesting to the exercise,
> which was to abuse the new revision listing library in interesting ways by
> calling it multiple times.
Abuse is exactly the word. The reason it is an abuse is exactly
why you said "... but to fix it you'd have to actualyl walk the
parent list yourself, rather than letting get_revision do it all
for you." Which relates to the fact that object.c layer is not
designed to be used multiple times...
Maybe we want to make object.c layer reusable first?
^ permalink raw reply
* [PATCH] Add --temp and --stage=all options to checkout-index.
From: Shawn Pearce @ 2006-03-03 1:20 UTC (permalink / raw)
To: git
Sometimes it is convient for a Porcelain to be able to checkout all
unmerged files in all stages so that an external merge tool can be
executed by the Porcelain or the end-user. Using git-unpack-file
on each stage individually incurs a rather high penalty due to the
need to fork for each file version obtained. git-checkout-index -a
--stage=all will now do the same thing, but faster.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
This spawned out of the discussion of my prior --suffix patch
and replaces it entirely.
The output format is Junio's idea, which I happened to like a lot.
I think I have faithfully implemented it here, but added a case
where you can obtain temporary files for only a specific stage
without needing to read the 'wider' 3-stage format.
Unfortunately this change lead me down a path which changed the core
checkout code also used by apply and read-tree. So those commands
could now checkout to temporary files if they wanted to. :-)
It currently passes all test cases, including the new one provided
by this patch.
Documentation/git-checkout-index.txt | 51 ++++++++
apply.c | 3
cache.h | 5 -
checkout-index.c | 84 ++++++++++++-
entry.c | 92 +++++++++------
read-tree.c | 3
t/t2004-checkout-cache-temp.sh | 212 ++++++++++++++++++++++++++++++++++
7 files changed, 396 insertions(+), 54 deletions(-)
create mode 100755 t/t2004-checkout-cache-temp.sh
base c6b84bc40310f8e0cf2fe290b5f291e31cf688ef
last 022659f9b239fd5513a883e09ac0e0688b69dbe1
diff --git a/Documentation/git-checkout-index.txt b/Documentation/git-checkout-index.txt
index b0b6588..09bd6a5 100644
--- a/Documentation/git-checkout-index.txt
+++ b/Documentation/git-checkout-index.txt
@@ -10,7 +10,8 @@ SYNOPSIS
--------
[verse]
'git-checkout-index' [-u] [-q] [-a] [-f] [-n] [--prefix=<string>]
- [--stage=<number>]
+ [--stage=<number>|all]
+ [--temp]
[-z] [--stdin]
[--] [<file>]\*
@@ -43,9 +44,15 @@ OPTIONS
When creating files, prepend <string> (usually a directory
including a trailing /)
---stage=<number>::
+--stage=<number>|all::
Instead of checking out unmerged entries, copy out the
files from named stage. <number> must be between 1 and 3.
+ Note: --stage=all automatically implies --temp.
+
+--temp::
+ Instead of copying the files to the working directory
+ write the content to temporary files. The temporary name
+ associations will be written to stdout.
--stdin::
Instead of taking list of paths from the command line,
@@ -87,6 +94,46 @@ it will prevent problems with a filename
Using `--` is probably a good policy in scripts.
+Using --temp or --stage=all
+---------------------------
+When `--temp` is used (or implied by `--stage=all`)
+`git-checkout-index` will create a temporary file for each index
+entry being checked out. The index will not be updated with stat
+information. These options can be useful if the caller needs all
+stages of all unmerged entries so that the unmerged files can be
+processed by an external merge tool.
+
+A listing will be written to stdout providing the association of
+temporary file names to tracked path names. The listing format
+has two variations:
+
+ . tempname TAB path RS
++
+The first format is what gets used when `--stage` is omitted or
+is not `--stage=all`. The field tempname is the temporary file
+name holding the file content and path is the tracked path name in
+the index. Only the requested entries are output.
+
+ . stage1temp SP stage2temp SP stage3tmp TAB path RS
++
+The second format is what gets used when `--stage=all`. The three
+stage temporary fields (stage1temp, stage2temp, stage3temp) list the
+name of the temporary file if there is a stage entry in the index
+or `.` if there is no stage entry. Paths which only have a stage 0
+entry will always be omitted from the output.
+
+In both formats RS (the record separator) is newline by default
+but will be the null byte if -z was passed on the command line.
+The temporary file names are always safe strings; they will never
+contain directory separators or whitespace characters. The path
+field is always relative to the current directory and the temporary
+file names are always relative to the top level directory.
+
+If the object being copied out to a temporary file is a symbolic
+link the content of the link will be written to a normal file. It is
+up to the end-user or the Porcelain to make use of this information.
+
+
EXAMPLES
--------
To update and refresh only the files already checked out::
diff --git a/apply.c b/apply.c
index c369966..5583a80 100644
--- a/apply.c
+++ b/apply.c
@@ -1376,6 +1376,7 @@ static int apply_data(struct patch *patc
static int check_patch(struct patch *patch)
{
struct stat st;
+ static char topath[MAXPATHLEN+1];
const char *old_name = patch->old_name;
const char *new_name = patch->new_name;
const char *name = old_name ? old_name : new_name;
@@ -1402,7 +1403,7 @@ static int check_patch(struct patch *pat
costate.not_new = 0;
costate.refresh_cache = 1;
if (checkout_entry(active_cache[pos],
- &costate) ||
+ &costate, topath) ||
lstat(old_name, &st))
return -1;
}
diff --git a/cache.h b/cache.h
index 0d3b244..f87744c 100644
--- a/cache.h
+++ b/cache.h
@@ -259,10 +259,11 @@ struct checkout {
unsigned force:1,
quiet:1,
not_new:1,
- refresh_cache:1;
+ refresh_cache:1,
+ to_tempfile:1;
};
-extern int checkout_entry(struct cache_entry *ce, struct checkout *state);
+extern int checkout_entry(struct cache_entry *ce, struct checkout *state, char *topath);
extern struct alternate_object_database {
struct alternate_object_database *next;
diff --git a/checkout-index.c b/checkout-index.c
index f54c606..24845c3 100644
--- a/checkout-index.c
+++ b/checkout-index.c
@@ -40,9 +40,12 @@
#include "strbuf.h"
#include "quote.h"
+#define CHECKOUT_ALL 4
static const char *prefix;
static int prefix_length;
+static int line_termination = '\n';
static int checkout_stage; /* default to checkout stage0 */
+static char topath[4][MAXPATHLEN+1];
static struct checkout state = {
.base_dir = "",
@@ -51,13 +54,42 @@ static struct checkout state = {
.quiet = 0,
.not_new = 0,
.refresh_cache = 0,
+ .to_tempfile = 0,
};
+static void write_tempfile_record (const char *name)
+{
+ int i;
+
+ if (CHECKOUT_ALL == checkout_stage) {
+ for (i = 1; i < 4; i++) {
+ if (i > 1)
+ putchar(' ');
+ if (topath[i][0])
+ fputs(topath[i], stdout);
+ else
+ putchar('.');
+ }
+ } else
+ fputs(topath[checkout_stage], stdout);
+
+ putchar('\t');
+ write_name_quoted("", 0, name + prefix_length,
+ line_termination, stdout);
+ putchar(line_termination);
+
+ for (i = 0; i < 4; i++) {
+ topath[i][0] = 0;
+ }
+}
+
static int checkout_file(const char *name)
{
int namelen = strlen(name);
int pos = cache_name_pos(name, namelen);
int has_same_name = 0;
+ int did_checkout = 0;
+ int errs = 0;
if (pos < 0)
pos = -pos - 1;
@@ -68,9 +100,19 @@ static int checkout_file(const char *nam
memcmp(ce->name, name, namelen))
break;
has_same_name = 1;
- if (checkout_stage == ce_stage(ce))
- return checkout_entry(ce, &state);
pos++;
+ if (ce_stage(ce) != checkout_stage
+ && (CHECKOUT_ALL != checkout_stage || !ce_stage(ce)))
+ continue;
+ did_checkout = 1;
+ if (checkout_entry(ce, &state, topath[ce_stage(ce)]) < 0)
+ errs++;
+ }
+
+ if (did_checkout) {
+ if (state.to_tempfile)
+ write_tempfile_record(name);
+ return errs > 0 ? -1 : 0;
}
if (!state.quiet) {
@@ -90,18 +132,28 @@ static int checkout_file(const char *nam
static int checkout_all(void)
{
int i, errs = 0;
+ struct cache_entry* last_ce = 0;
for (i = 0; i < active_nr ; i++) {
struct cache_entry *ce = active_cache[i];
- if (ce_stage(ce) != checkout_stage)
+ if (ce_stage(ce) != checkout_stage
+ && (CHECKOUT_ALL != checkout_stage || !ce_stage(ce)))
continue;
if (prefix && *prefix &&
(ce_namelen(ce) <= prefix_length ||
memcmp(prefix, ce->name, prefix_length)))
continue;
- if (checkout_entry(ce, &state) < 0)
+ if (last_ce && state.to_tempfile) {
+ if (ce_namelen(last_ce) != ce_namelen(ce)
+ || memcmp(last_ce->name, ce->name, ce_namelen(ce)))
+ write_tempfile_record(last_ce->name);
+ }
+ if (checkout_entry(ce, &state, topath[ce_stage(ce)]) < 0)
errs++;
+ last_ce = ce;
}
+ if (last_ce && state.to_tempfile)
+ write_tempfile_record(last_ce->name);
if (errs)
/* we have already done our error reporting.
* exit with the same code as die().
@@ -111,7 +163,7 @@ static int checkout_all(void)
}
static const char checkout_cache_usage[] =
-"git-checkout-index [-u] [-q] [-a] [-f] [-n] [--stage=[123]] [--prefix=<string>] [--] <file>...";
+"git-checkout-index [-u] [-q] [-a] [-f] [-n] [--stage=[123]|all] [--prefix=<string>] [--temp] [--] <file>...";
static struct cache_file cache_file;
@@ -121,7 +173,6 @@ int main(int argc, char **argv)
int newfd = -1;
int all = 0;
int read_from_stdin = 0;
- int line_termination = '\n';
prefix = setup_git_directory();
git_config(git_default_config);
@@ -175,17 +226,26 @@ int main(int argc, char **argv)
i++; /* do not consider arg as a file name */
break;
}
+ if (!strcmp(arg, "--temp")) {
+ state.to_tempfile = 1;
+ continue;
+ }
if (!strncmp(arg, "--prefix=", 9)) {
state.base_dir = arg+9;
state.base_dir_len = strlen(state.base_dir);
continue;
}
if (!strncmp(arg, "--stage=", 8)) {
- int ch = arg[8];
- if ('1' <= ch && ch <= '3')
- checkout_stage = arg[8] - '0';
- else
- die("stage should be between 1 and 3");
+ if (!strcmp(arg + 8, "all")) {
+ state.to_tempfile = 1;
+ checkout_stage = CHECKOUT_ALL;
+ } else {
+ int ch = arg[8];
+ if ('1' <= ch && ch <= '3')
+ checkout_stage = arg[8] - '0';
+ else
+ die("stage should be between 1 and 3 or all");
+ }
continue;
}
if (arg[0] == '-')
@@ -193,7 +253,7 @@ int main(int argc, char **argv)
break;
}
- if (state.base_dir_len) {
+ if (state.base_dir_len || state.to_tempfile) {
/* when --prefix is specified we do not
* want to update cache.
*/
diff --git a/entry.c b/entry.c
index 8fb99bc..c33a35d 100644
--- a/entry.c
+++ b/entry.c
@@ -63,7 +63,7 @@ static int create_file(const char *path,
return open(path, O_WRONLY | O_CREAT | O_EXCL, mode);
}
-static int write_entry(struct cache_entry *ce, const char *path, struct checkout *state)
+static int write_entry(struct cache_entry *ce, char *path, struct checkout *state)
{
int fd;
void *new;
@@ -80,7 +80,11 @@ static int write_entry(struct cache_entr
}
switch (ntohl(ce->ce_mode) & S_IFMT) {
case S_IFREG:
- fd = create_file(path, ntohl(ce->ce_mode));
+ if (state->to_tempfile) {
+ strcpy(path, ".merge_file_XXXXXX");
+ fd = mkstemp(path);
+ } else
+ fd = create_file(path, ntohl(ce->ce_mode));
if (fd < 0) {
free(new);
return error("git-checkout-index: unable to create file %s (%s)",
@@ -93,12 +97,27 @@ static int write_entry(struct cache_entr
return error("git-checkout-index: unable to write file %s", path);
break;
case S_IFLNK:
- if (symlink(new, path)) {
+ if (state->to_tempfile) {
+ strcpy(path, ".merge_link_XXXXXX");
+ fd = mkstemp(path);
+ if (fd < 0) {
+ free(new);
+ return error("git-checkout-index: unable to create "
+ "file %s (%s)", path, strerror(errno));
+ }
+ wrote = write(fd, new, size);
+ close(fd);
free(new);
- return error("git-checkout-index: unable to create "
- "symlink %s (%s)", path, strerror(errno));
+ if (wrote != size)
+ return error("git-checkout-index: unable to write file %s",
+ path);
+ } else {
+ wrote = symlink(new, path);
+ free(new);
+ if (wrote)
+ return error("git-checkout-index: unable to create "
+ "symlink %s (%s)", path, strerror(errno));
}
- free(new);
break;
default:
free(new);
@@ -113,41 +132,42 @@ static int write_entry(struct cache_entr
return 0;
}
-int checkout_entry(struct cache_entry *ce, struct checkout *state)
+int checkout_entry(struct cache_entry *ce, struct checkout *state, char *topath)
{
struct stat st;
- static char path[MAXPATHLEN+1];
int len = state->base_dir_len;
- memcpy(path, state->base_dir, len);
- strcpy(path + len, ce->name);
-
- if (!lstat(path, &st)) {
- unsigned changed = ce_match_stat(ce, &st, 1);
- if (!changed)
+ if (!state->to_tempfile) {
+ memcpy(topath, state->base_dir, len);
+ strcpy(topath + len, ce->name);
+
+ if (!lstat(topath, &st)) {
+ unsigned changed = ce_match_stat(ce, &st, 1);
+ if (!changed)
+ return 0;
+ if (!state->force) {
+ if (!state->quiet)
+ fprintf(stderr, "git-checkout-index: %s already exists\n", topath);
+ return -1;
+ }
+
+ /*
+ * We unlink the old file, to get the new one with the
+ * right permissions (including umask, which is nasty
+ * to emulate by hand - much easier to let the system
+ * just do the right thing)
+ */
+ unlink(topath);
+ if (S_ISDIR(st.st_mode)) {
+ if (!state->force)
+ return error("%s is a directory", topath);
+ remove_subtree(topath);
+ }
+ } else if (state->not_new)
return 0;
- if (!state->force) {
- if (!state->quiet)
- fprintf(stderr, "git-checkout-index: %s already exists\n", path);
- return -1;
- }
-
- /*
- * We unlink the old file, to get the new one with the
- * right permissions (including umask, which is nasty
- * to emulate by hand - much easier to let the system
- * just do the right thing)
- */
- unlink(path);
- if (S_ISDIR(st.st_mode)) {
- if (!state->force)
- return error("%s is a directory", path);
- remove_subtree(path);
- }
- } else if (state->not_new)
- return 0;
- create_directories(path, state);
- return write_entry(ce, path, state);
+ create_directories(topath, state);
+ }
+ return write_entry(ce, topath, state);
}
diff --git a/read-tree.c b/read-tree.c
index be29b3f..e88d69e 100644
--- a/read-tree.c
+++ b/read-tree.c
@@ -279,6 +279,7 @@ static void progress_interval(int signum
static void check_updates(struct cache_entry **src, int nr)
{
+ static char topath[MAXPATHLEN+1];
static struct checkout state = {
.base_dir = "",
.force = 1,
@@ -337,7 +338,7 @@ static void check_updates(struct cache_e
if (ce->ce_flags & mask) {
ce->ce_flags &= ~mask;
if (update)
- checkout_entry(ce, &state);
+ checkout_entry(ce, &state, topath);
}
}
if (total) {
diff --git a/t/t2004-checkout-cache-temp.sh b/t/t2004-checkout-cache-temp.sh
new file mode 100755
index 0000000..c100959
--- /dev/null
+++ b/t/t2004-checkout-cache-temp.sh
@@ -0,0 +1,212 @@
+#!/bin/sh
+#
+# Copyright (c) 2006 Shawn Pearce
+#
+
+test_description='git-checkout-index --temp test.
+
+With --temp flag, git-checkout-index writes to temporary merge files
+rather than the tracked path.'
+
+. ./test-lib.sh
+
+test_expect_success \
+'preparation' '
+mkdir asubdir &&
+echo tree1path0 >path0 &&
+echo tree1path1 >path1 &&
+echo tree1path3 >path3 &&
+echo tree1path4 >path4 &&
+echo tree1asubdir/path5 >asubdir/path5 &&
+git-update-index --add path0 path1 path3 path4 asubdir/path5 &&
+t1=$(git-write-tree) &&
+rm -f path* .merge_* out .git/index &&
+echo tree2path0 >path0 &&
+echo tree2path1 >path1 &&
+echo tree2path2 >path2 &&
+echo tree2path4 >path4 &&
+git-update-index --add path0 path1 path2 path4 &&
+t2=$(git-write-tree) &&
+rm -f path* .merge_* out .git/index &&
+echo tree2path0 >path0 &&
+echo tree3path1 >path1 &&
+echo tree3path2 >path2 &&
+echo tree3path3 >path3 &&
+git-update-index --add path0 path1 path2 path3 &&
+t3=$(git-write-tree)'
+
+test_expect_success \
+'checkout one stage 0 to temporary file' '
+rm -f path* .merge_* out .git/index &&
+git-read-tree $t1 &&
+git-checkout-index --temp -- path1 >out &&
+test $(wc -l <out) = 1 &&
+test $(cut "-d " -f2 out) = path1 &&
+p=$(cut "-d " -f1 out) &&
+test -f $p &&
+test $(cat $p) = tree1path1'
+
+test_expect_success \
+'checkout all stage 0 to temporary files' '
+rm -f path* .merge_* out .git/index &&
+git-read-tree $t1 &&
+git-checkout-index -a --temp >out &&
+test $(wc -l <out) = 5 &&
+for f in path0 path1 path3 path4 asubdir/path5
+do
+ test $(grep $f out | cut "-d " -f2) = $f &&
+ p=$(grep $f out | cut "-d " -f1) &&
+ test -f $p &&
+ test $(cat $p) = tree1$f
+done'
+
+test_expect_success \
+'prepare 3-way merge' '
+rm -f path* .merge_* out .git/index &&
+git-read-tree -m $t1 $t2 $t3'
+
+test_expect_success \
+'checkout one stage 2 to temporary file' '
+rm -f path* .merge_* out &&
+git-checkout-index --stage=2 --temp -- path1 >out &&
+test $(wc -l <out) = 1 &&
+test $(cut "-d " -f2 out) = path1 &&
+p=$(cut "-d " -f1 out) &&
+test -f $p &&
+test $(cat $p) = tree2path1'
+
+test_expect_success \
+'checkout all stage 2 to temporary files' '
+rm -f path* .merge_* out &&
+git-checkout-index --all --stage=2 --temp >out &&
+test $(wc -l <out) = 3 &&
+for f in path1 path2 path4
+do
+ test $(grep $f out | cut "-d " -f2) = $f &&
+ p=$(grep $f out | cut "-d " -f1) &&
+ test -f $p &&
+ test $(cat $p) = tree2$f
+done'
+
+test_expect_success \
+'checkout all stages/one file to nothing' '
+rm -f path* .merge_* out &&
+git-checkout-index --stage=all --temp -- path0 >out &&
+test $(wc -l <out) = 0'
+
+test_expect_success \
+'checkout all stages/one file to temporary files' '
+rm -f path* .merge_* out &&
+git-checkout-index --stage=all --temp -- path1 >out &&
+test $(wc -l <out) = 1 &&
+test $(cut "-d " -f2 out) = path1 &&
+cut "-d " -f1 out | (read s1 s2 s3 &&
+test -f $s1 &&
+test -f $s2 &&
+test -f $s3 &&
+test $(cat $s1) = tree1path1 &&
+test $(cat $s2) = tree2path1 &&
+test $(cat $s3) = tree3path1)'
+
+test_expect_success \
+'checkout some stages/one file to temporary files' '
+rm -f path* .merge_* out &&
+git-checkout-index --stage=all --temp -- path2 >out &&
+test $(wc -l <out) = 1 &&
+test $(cut "-d " -f2 out) = path2 &&
+cut "-d " -f1 out | (read s1 s2 s3 &&
+test $s1 = . &&
+test -f $s2 &&
+test -f $s3 &&
+test $(cat $s2) = tree2path2 &&
+test $(cat $s3) = tree3path2)'
+
+test_expect_success \
+'checkout all stages/all files to temporary files' '
+rm -f path* .merge_* out &&
+git-checkout-index -a --stage=all --temp >out &&
+test $(wc -l <out) = 5'
+
+test_expect_success \
+'-- path0: no entry' '
+test x$(grep path0 out | cut "-d " -f2) = x'
+
+test_expect_success \
+'-- path1: all 3 stages' '
+test $(grep path1 out | cut "-d " -f2) = path1 &&
+grep path1 out | cut "-d " -f1 | (read s1 s2 s3 &&
+test -f $s1 &&
+test -f $s2 &&
+test -f $s3 &&
+test $(cat $s1) = tree1path1 &&
+test $(cat $s2) = tree2path1 &&
+test $(cat $s3) = tree3path1)'
+
+test_expect_success \
+'-- path2: no stage 1, have stage 2 and 3' '
+test $(grep path2 out | cut "-d " -f2) = path2 &&
+grep path2 out | cut "-d " -f1 | (read s1 s2 s3 &&
+test $s1 = . &&
+test -f $s2 &&
+test -f $s3 &&
+test $(cat $s2) = tree2path2 &&
+test $(cat $s3) = tree3path2)'
+
+test_expect_success \
+'-- path3: no stage 2, have stage 1 and 3' '
+test $(grep path3 out | cut "-d " -f2) = path3 &&
+grep path3 out | cut "-d " -f1 | (read s1 s2 s3 &&
+test -f $s1 &&
+test $s2 = . &&
+test -f $s3 &&
+test $(cat $s1) = tree1path3 &&
+test $(cat $s3) = tree3path3)'
+
+test_expect_success \
+'-- path4: no stage 3, have stage 1 and 3' '
+test $(grep path4 out | cut "-d " -f2) = path4 &&
+grep path4 out | cut "-d " -f1 | (read s1 s2 s3 &&
+test -f $s1 &&
+test -f $s2 &&
+test $s3 = . &&
+test $(cat $s1) = tree1path4 &&
+test $(cat $s2) = tree2path4)'
+
+test_expect_success \
+'-- asubdir/path5: no stage 2 and 3 have stage 1' '
+test $(grep asubdir/path5 out | cut "-d " -f2) = asubdir/path5 &&
+grep asubdir/path5 out | cut "-d " -f1 | (read s1 s2 s3 &&
+test -f $s1 &&
+test $s2 = . &&
+test $s3 = . &&
+test $(cat $s1) = tree1asubdir/path5)'
+
+test_expect_success \
+'checkout --temp within subdir' '
+(cd asubdir &&
+ git-checkout-index -a --stage=all >out &&
+ test $(wc -l <out) = 1 &&
+ test $(grep path5 out | cut "-d " -f2) = path5 &&
+ grep path5 out | cut "-d " -f1 | (read s1 s2 s3 &&
+ test -f ../$s1 &&
+ test $s2 = . &&
+ test $s3 = . &&
+ test $(cat ../$s1) = tree1asubdir/path5)
+)'
+
+test_expect_success \
+'checkout --temp symlink' '
+rm -f path* .merge_* out .git/index &&
+ln -s b a &&
+git-update-index --add a &&
+t4=$(git-write-tree) &&
+rm -f .git/index &&
+git-read-tree $t4 &&
+git-checkout-index --temp -a >out &&
+test $(wc -l <out) = 1 &&
+test $(cut "-d " -f2 out) = a &&
+p=$(cut "-d " -f1 out) &&
+test -f $p &&
+test $(cat $p) = b'
+
+test_done
--
1.2.3.g5f0e
^ permalink raw reply related
* [PATCH] Added Packing Heursitics IRC writeup.
From: Jon Loeliger @ 2006-03-03 1:19 UTC (permalink / raw)
To: git
Signed-off-by: Jon Loeliger <jdl@jdl.com>
---
Documentation/technical/pack-heuristics.txt | 466 +++++++++++++++++++++++++++
1 files changed, 466 insertions(+), 0 deletions(-)
create mode 100644 Documentation/technical/pack-heuristics.txt
0cbbcac437be6f8a0249f6cf83b90a6fe9d2362e
diff --git a/Documentation/technical/pack-heuristics.txt b/Documentation/technical/pack-heuristics.txt
new file mode 100644
index 0000000..eaab3ee
--- /dev/null
+++ b/Documentation/technical/pack-heuristics.txt
@@ -0,0 +1,466 @@
+ Concerning Git's Packing Heuristics
+ ===================================
+
+ Oh, here's a really stupid question:
+
+ Where do I go
+ to learn the details
+ of git's packing heuristics?
+
+Be careful what you ask!
+
+Followers of the git, please open the git IRC Log and turn to
+February 10, 2006.
+
+It's a rare occasion, and we are joined by the King Git Himself,
+Linus Torvalds (linus). Nathaniel Smith, (njs`), has the floor
+and seeks enlightenment. Others are present, but silent.
+
+Let's listen in!
+
+ <njs`> Oh, here's a really stupid question -- where do I go to
+ learn the details of git's packing heuristics? google avails
+ me not, reading the source didn't help a lot, and wading
+ through the whole mailing list seems less efficient than any
+ of that.
+
+It is a bold start! A plea for help combined with a simultaneous
+tri-part attack on some of the tried and true mainstays in the quest
+for enlightenment. Brash accusations of google being useless. Hubris!
+Maligning the source. Heresy! Disdain for the mailing list archives.
+Woe.
+
+ <pasky> yes, the packing-related delta stuff is somewhat
+ mysterious even for me ;)
+
+Ah! Modesty after all.
+
+ <linus> njs, I don't think the docs exist. That's something where
+ I don't think anybody else than me even really got involved.
+ Most of the rest of git others have been busy with (especially
+ Junio), but packing nobody touched after I did it.
+
+It's cryptic, yet vague. Linus in style for sure. Wise men
+interpret this as an apology. A few argue it is merely a
+statement of fact.
+
+ <njs`> I guess the next step is "read the source again", but I
+ have to build up a certain level of gumption first :-)
+
+Indeed! On both points.
+
+ <linus> The packing heuristic is actually really really simple.
+
+Bait...
+
+ <linus> But strange.
+
+And switch. That ought to do it!
+
+ <linus> Remember: git really doesn't follow files. So what it does is
+ - generate a list of all objects
+ - sort the list according to magic heuristics
+ - walk the list, using a sliding window, seeing if an object
+ can be diffed against another object in the window
+ - write out the list in recency order
+
+The traditional understatement:
+
+ <njs`> I suspect that what I'm missing is the precise definition of
+ the word "magic"
+
+The traditional insight:
+
+ <pasky> yes
+
+And Bable-like confusion flowed.
+
+ <njs`> oh, hmm, and I'm not sure what this sliding window means either
+
+ <pasky> iirc, it appeared to me to be just the sha1 of the object
+ when reading the code casually ...
+
+ ... which simply doesn't sound as a very good heuristics, though ;)
+
+ <njs`> .....and recency order. okay, I think it's clear I didn't
+ even realize how much I wasn't realizing :-)
+
+Ah, grasshopper! And thus the enlightenment begins anew.
+
+ <linus> The "magic" is actually in theory totally arbitrary.
+ ANY order will give you a working pack, but no, it's not
+ ordered by SHA1.
+
+ Before talking about the ordering for the sliding delta
+ window, let's talk about the recency order. That's more
+ important in one way.
+
+ <njs`> Right, but if all you want is a working way to pack things
+ together, you could just use cat and save yourself some
+ trouble...
+
+Waaait for it....
+
+ <linus> The recency ordering (which is basically: put objects
+ _physically_ into the pack in the order that they are
+ "reachable" from the head) is important.
+
+ <njs`> okay
+
+ <linus> It's important because that's the thing that gives packs
+ good locality. It keeps the objects close to the head (whether
+ they are old or new, but they are _reachable_ from the head)
+ at the head of the pack. So packs actually have absolutely
+ _wonderful_ IO patterns.
+
+Read that again, because it is important.
+
+ <linus> But recency ordering is totally useless for deciding how
+ to actually generate the deltas, so the delta ordering is
+ something else.
+
+ The delta ordering is (wait for it):
+ - first sort by the "basename" of the object, as defined by
+ the name the object was _first_ reached through when
+ generating the object list
+ - within the same basename, sort by size of the object
+ - but always sort different types separately (commits first).
+
+ That's not exactly it, but it's very close.
+
+ <njs`> The "_first_ reached" thing is not too important, just you
+ need some way to break ties since the same objects may be
+ reachable many ways, yes?
+
+And as if to clarify:
+
+ <linus> The point is that it's all really just any random
+ heuristic, and the ordering is totally unimportant for
+ correctness, but it helps a lot if the heuristic gives
+ "clumping" for things that are likely to delta well against
+ each other.
+
+It is an important point, so secretly, I did my own research and have
+included my results below. To be fair, it has changed some over time.
+And through the magic of Revisionistic History, I draw upon this entry
+from The Git IRC Logs on my father's birthday, March 1:
+
+ <gitster> The quote from the above linus should be rewritten a
+ bit (wait for it):
+ - first sort by type. Different objects never delta with
+ each other.
+ - then sort by filename/dirname. hash of the basename
+ occupies the top BITS_PER_INT-DIR_BITS bits, and bottom
+ DIR_BITS are for the hash of leading path elements.
+ - then if we are doing "thin" pack, the objects we are _not_
+ going to pack but we know about are sorted earlier than
+ other objects.
+ - and finally sort by size, larger to smaller.
+
+In one swell-foop, clarification and obscurification! Nonetheless,
+authoritative. Cryptic, yet concise. It even solicits notions of
+quotes from The Source Code. Clearly, more study is needed.
+
+ <gitster> That's the sort order. What this means is:
+ - we do not delta different object types.
+ - we prefer to delta the objects with the same full path, but
+ allow files with the same name from different directories.
+ - we always prefer to delta against objects we are not going
+ to send, if there are some.
+ - we prefer to delta against larger objects, so that we have
+ lots of removals.
+
+ The penultimate rule is for "thin" packs. It is used when
+ the other side is known to have such objects.
+
+There it is again. "Thin" packs. I'm thinking to myself, "What
+is a 'thin' pack?" So I ask:
+
+ <jdl> What is a "thin" pack?
+
+ <gitster> Use of --objects-edge to rev-list as the upstream of
+ pack-objects. The pack transfer protocol negotiates that.
+
+Woo hoo! Cleared that _right_ up!
+
+ <gitster> There are two directions - push and fetch.
+
+There! Did you see it? It is not '"push" and "pull"'! How often the
+confusion has started here. So casually mentioned, too!
+
+ <gitster> For push, git-send-pack invokes git-receive-pack on the
+ other end. The receive-pack says "I have up to these commits".
+ send-pack looks at them, and computes what are missing from
+ the other end. So "thin" could be the default there.
+
+ In the other direction, fetch, git-fetch-pack and
+ git-clone-pack invokes git-upload-pack on the other end
+ (via ssh or by talking to the daemon).
+
+ There are two cases: fetch-pack with -k and clone-pack is one,
+ fetch-pack without -k is the other. clone-pack and fetch-pack
+ with -k will keep the downloaded packfile without expanded, so
+ we do not use thin pack transfer. Otherwise, the generated
+ pack will have delta without base object in the same pack.
+
+ But fetch-pack without -k will explode the received pack into
+ individual objects, so we automatically ask upload-pack to
+ give us a thin pack if upload-pack supports it.
+
+OK then.
+
+Uh.
+
+Let's return to the previous conversation still in progress.
+
+ <njs`> and "basename" means something like "the tail of end of
+ path of file objects and dir objects, as per basename(3), and
+ we just declare all commit and tag objects to have the same
+ basename" or something?
+
+Luckily, that too is a point that gitster clarified for us!
+
+If I might add, the trick is to make files that _might_ be similar be
+located close to each other in the hash buckets based on their file
+names. It used to be that "foo/Makefile", "bar/baz/quux/Makefile" and
+"Makefile" all landed in the same bucket due to their common basename,
+"Makefile". However, now they land in "close" buckets.
+
+The algorithm allows not just for the _same_ bucket, but for _close_
+buckets to be considered delta candidates. The rationale is
+essentially that files, like Makefiles, often have very similar
+content no matter what directory they live in.
+
+ <linus> I played around with different delta algorithms, and with
+ making the "delta window" bigger, but having too big of a
+ sliding window makes it very expensive to generate the pack:
+ you need to compare every object with a _ton_ of other objects.
+
+ There are a number of other trivial heuristics too, which
+ basically boil down to "don't bother even trying to delta this
+ pair" if we can tell before-hand that the delta isn't worth it
+ (due to size differences, where we can take a previous delta
+ result into account to decide that "ok, no point in trying
+ that one, it will be worse").
+
+ End result: packing is actually very size efficient. It's
+ somewhat CPU-wasteful, but on the other hand, since you're
+ really only supposed to do it maybe once a month (and you can
+ do it during the night), nobody really seems to care.
+
+Nice Engineering Touch, there. Find when it doesn't matter, and
+proclaim it a non-issue. Good style too!
+
+ <njs`> So, just to repeat to see if I'm following, we start by
+ getting a list of the objects we want to pack, we sort it by
+ this heuristic (basically lexicographically on the tuple
+ (type, basename, size)).
+
+ Then we walk through this list, and calculate a delta of
+ each object against the last n (tunable paramater) objects,
+ and pick the smallest of these deltas.
+
+Vastly simplified, but the essence is there!
+
+ <linus> Correct.
+
+ <njs`> And then once we have picked a delta or fulltext to
+ represent each object, we re-sort by recency, and write them
+ out in that order.
+
+ <linus> Yup. Some other small details:
+
+And of course there is the "Other Shoe" Factor too.
+
+ <linus> - We limit the delta depth to another magic value (right
+ now both the window and delta depth magic values are just "10")
+
+ <njs`> Hrm, my intuition is that you'd end up with really _bad_ IO
+ patterns, because the things you want are near by, but to
+ actually reconstruct them you may have to jump all over in
+ random ways.
+
+ <linus> - When we write out a delta, and we haven't yet written
+ out the object it is a delta against, we write out the base
+ object first. And no, when we reconstruct them, we actually
+ get nice IO patterns, because:
+ - larger objects tend to be "more recent" (Linus' law: files grow)
+ - we actively try to generate deltas from a larger object to a
+ smaller one
+ - this means that the top-of-tree very seldom has deltas
+ (ie deltas in _practice_ are "backwards deltas")
+
+Again, we should reread that whole paragraph. Not just because
+Linus has slipped Linus's Law in there on us, but because it is
+important. Let's make sure we clarify some of the points here:
+
+ <njs`> So the point is just that in practice, delta order and
+ recency order match each other quite well.
+
+ <linus> Yes. There's another nice side to this (and yes, it was
+ designed that way ;):
+ - the reason we generate deltas against the larger object is
+ actually a big space saver too!
+
+ <njs`> Hmm, but your last comment (if "we haven't yet written out
+ the object it is a delta against, we write out the base object
+ first"), seems like it would make these facts mostly
+ irrelevant because even if in practice you would not have to
+ wander around much, in fact you just brute-force say that in
+ the cases where you might have to wander, don't do that :-)
+
+ <linus> Yes and no. Notice the rule: we only write out the base
+ object first if the delta against it was more recent. That
+ means that you can actually have deltas that refer to a base
+ object that is _not_ close to the delta object, but that only
+ happens when the delta is needed to generate an _old_ object.
+
+ <linus> See?
+
+Yeah, no. I missed that on the first two or three readings myself.
+
+ <linus> This keeps the front of the pack dense. The front of the
+ pack never contains data that isn't relevant to a "recent"
+ object. The size optimization comes from our use of xdelta
+ (but is true for many other delta algorithms): removing data
+ is cheaper (in size) than adding data.
+
+ When you remove data, you only need to say "copy bytes n--m".
+ In contrast, in a delta that _adds_ data, you have to say "add
+ these bytes: 'actual data goes here'"
+
+ *** njs` has quit: Read error: 104 (Connection reset by peer)
+
+ <linus> Uhhuh. I hope I didn't blow njs` mind.
+
+ *** njs` has joined channel #git
+
+ <pasky> :)
+
+The silent observers are amused. Of course.
+
+And as if njs` was expected to be omniscient:
+
+ <linus> njs - did you miss anything?
+
+OK, I'll spell it out. That's Geek Humor. If njs` was not actually
+connected for a little bit there, how would he know if missed anything
+while he was disconnected? He's a benevolent dictator with a sense of
+humor! Well noted!
+
+ <njs`> Stupid router. Or gremlins, or whatever.
+
+It's a cheap shot at Cisco. Take 'em when you can.
+
+ <njs`> Yes and no. Notice the rule: we only write out the base
+ object first if the delta against it was more recent.
+
+ I'm getting lost in all these orders, let me re-read :-)
+ So the write-out order is from most recent to least recent?
+ (Conceivably it could be the opposite way too, I'm not sure if
+ we've said) though my connection back at home is logging, so I
+ can just read what you said there :-)
+
+And for those of you paying attention, the Omniscient Trick has just
+been detailed!
+
+ <linus> Yes, we always write out most recent first
+
+For the other record:
+
+ <pasky> njs`: http://pastebin.com/547965
+
+The 'net never forgets, so that should be good until the end of time.
+
+ <njs`> And, yeah, I got the part about deeper-in-history stuff
+ having worse IO characteristics, one sort of doesn't care.
+
+ <linus> With the caveat that if the "most recent" needs an older
+ object to delta against (hey, shrinking sometimes does
+ happen), we write out the old object with the delta.
+
+ <njs`> (if only it happened more...)
+
+ <linus> Anyway, the pack-file could easily be denser still, but
+ because it's used both for streaming (the git protocol) and
+ for on-disk, it has a few pessimizations.
+
+Actually, it is a made-up word. But it is a made-up word being
+used as setup for a later optimization, which is a real word:
+
+ <linus> In particular, while the pack-file is then compressed,
+ it's compressed just one object at a time, so the actual
+ compression factor is less than it could be in theory. But it
+ means that it's all nice random-access with a simple index to
+ do "object name->location in packfile" translation.
+
+ <njs`> I'm assuming the real win for delta-ing large->small is
+ more homogenous statistics for gzip to run over?
+
+ (You have to put the bytes in one place or another, but
+ putting them in a larger blob wins on compression)
+
+ Actually, what is the compression strategy -- each delta
+ individually gzipped, the whole file gzipped, somewhere in
+ between, no compression at all, ....?
+
+ Right.
+
+Reality IRC sets in. For example:
+
+ <pasky> I'll read the rest in the morning, I really have to go
+ sleep or there's no hope whatsoever for me at the today's
+ exam... g'nite all.
+
+Heh.
+
+ <linus> pasky: g'nite
+
+ <njs`> pasky: 'luck
+
+ <linus> Right: large->small matters exactly because of compression
+ behaviour. If it was non-compressed, it probably wouldn't make
+ any difference.
+
+ <njs`> yeah
+
+ <linus> Anyway: I'm not even trying to claim that the pack-files
+ are perfect, but they do tend to have a nice balance of
+ density vs ease-of use.
+
+Gasp! OK, saved. That's a fair Engineering trade off. Close call!
+In fact, Linus reflects on some Basic Engineering Fundamentals,
+design options, etc.
+
+ <linus> More importantly, they allow git to still _conceptually_
+ never deal with deltas at all, and be a "whole object" store.
+
+ Which has some problems (we discussed bad huge-file
+ behaviour on the git lists the other day), but it does mean
+ that the basic git concepts are really really simple and
+ straightforward.
+
+ It's all been quite stable.
+
+ Which I think is very much a result of having very simple
+ basic ideas, so that there's never any confusion about what's
+ going on.
+
+ Bugs happen, but they are "simple" bugs. And bugs that
+ actually get some object store detail wrong are almost always
+ so obious that they never go anywhere.
+
+ <njs`> Yeah.
+
+Nuff said.
+
+ <linus> Anyway. I'm off for bed. It's not 6AM here, but I've got
+ three kids, and have to get up early in the morning to send
+ them off. I need my beauty sleep.
+
+ <njs`> :-)
+
+ <njs`> appreciate the infodump, I really was failing to find the
+ details on git packs :-)
+
+And now you know the rest of the story.
--
1.0.7.g2b74
^ permalink raw reply related
* [PATCH 1/3] cg-mv doesn't work with bash 3.1.7 due to excessive quotes
From: Pavel Roskin @ 2006-03-03 1:11 UTC (permalink / raw)
To: git, Petr Baudis
Signed-off-by: Pavel Roskin <proski@gnu.org>
---
cg-mv | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/cg-mv b/cg-mv
index c42853c..d5618ba 100755
--- a/cg-mv
+++ b/cg-mv
@@ -38,7 +38,7 @@ done
# Strip trailing / which is something GIT does not bear well.
ARGS2=()
for arg in "${ARGS[@]}"; do
- ARGS2["${#ARGS2[@]}"]="$_git_relpath${arg%/}"
+ ARGS2[${#ARGS2[@]}]="$_git_relpath${arg%/}"
done
git-mv $force "${ARGS2[@]}"
^ permalink raw reply related
* [PATCH 2/3] Make tutorial-script work with current cogito
From: Pavel Roskin @ 2006-03-03 1:11 UTC (permalink / raw)
To: git, Petr Baudis
In-Reply-To: <20060303011154.14619.71590.stgit@dv.roinet.com>
Labels on merge conflict lines have changed. There is no "git rename",
use cg-mv instead. In one case stack.h is not created, so copy
stack.h~master to stack.h before fixing it.
Also fix comments in script.sh to use the new labels.
Signed-off-by: Pavel Roskin <proski@gnu.org>
---
.../tutorial-script/0010-alice-bob-fixup.ed | 2 +
.../tutorial-script/0017-alice-bob-fixup.ed | 2 +
.../tutorial-script/0018-alice-charlie-fixup1.ed | 4 +--
.../tutorial-script/0019-alice-charlie-fixup2.ed | 4 +--
.../tutorial-script/0021-bob-alice-fixup1.ed | 4 +--
.../tutorial-script/0022-bob-alice-fixup2.ed | 2 +
Documentation/tutorial-script/script.sh | 31 ++++++++++----------
7 files changed, 25 insertions(+), 24 deletions(-)
diff --git a/Documentation/tutorial-script/0010-alice-bob-fixup.ed b/Documentation/tutorial-script/0010-alice-bob-fixup.ed
index ca2047c..81b1360 100644
--- a/Documentation/tutorial-script/0010-alice-bob-fixup.ed
+++ b/Documentation/tutorial-script/0010-alice-bob-fixup.ed
@@ -1,3 +1,3 @@
-/^<<<<<<< rpn\.c/,/^>>>>>>> \.merge_file_/d
+/^<<<<<<< bob/,/^>>>>>>> bobswork/d
w
q
diff --git a/Documentation/tutorial-script/0017-alice-bob-fixup.ed b/Documentation/tutorial-script/0017-alice-bob-fixup.ed
index ad04eb7..6353328 100644
--- a/Documentation/tutorial-script/0017-alice-bob-fixup.ed
+++ b/Documentation/tutorial-script/0017-alice-bob-fixup.ed
@@ -1,4 +1,4 @@
-/^<<<<<<< Makefile/d
+/^<<<<<<< \.merge_file_/d
/^=======/,/^=======/+1d
/^>>>>>>> \.merge_file_/d
w
diff --git a/Documentation/tutorial-script/0018-alice-charlie-fixup1.ed b/Documentation/tutorial-script/0018-alice-charlie-fixup1.ed
index 65f5ef5..20c25c8 100644
--- a/Documentation/tutorial-script/0018-alice-charlie-fixup1.ed
+++ b/Documentation/tutorial-script/0018-alice-charlie-fixup1.ed
@@ -1,7 +1,7 @@
-/^<<<<<<< Makefile/d
+/^<<<<<<< master/d
/^rpn\.o:/s/\.h.*$/.h lexer.h/
/^lexer\.o:/s/:.*$/: lexer.h/
-/^=======/,/^>>>>>>> \.merge_file_/d
+/^=======/,/^>>>>>>> charlie/d
w
q
diff --git a/Documentation/tutorial-script/0019-alice-charlie-fixup2.ed b/Documentation/tutorial-script/0019-alice-charlie-fixup2.ed
index f1aadb4..5d531de 100644
--- a/Documentation/tutorial-script/0019-alice-charlie-fixup2.ed
+++ b/Documentation/tutorial-script/0019-alice-charlie-fixup2.ed
@@ -1,5 +1,5 @@
-/^<<<<<<< rpn\.c/,/^=======/d
-/^>>>>>>> \.merge_file_/d
+/^<<<<<<< master/,/^=======/d
+/^>>>>>>> charlie/d
w
q
diff --git a/Documentation/tutorial-script/0021-bob-alice-fixup1.ed b/Documentation/tutorial-script/0021-bob-alice-fixup1.ed
index 2783f73..df703d5 100644
--- a/Documentation/tutorial-script/0021-bob-alice-fixup1.ed
+++ b/Documentation/tutorial-script/0021-bob-alice-fixup1.ed
@@ -1,4 +1,4 @@
-/^<<<<<<< Makefile/,/^=======/d
-/^>>>>>>> \.merge_file_/d
+/^<<<<<<< master/,/^=======/d
+/^>>>>>>> origin/d
w
q
diff --git a/Documentation/tutorial-script/0022-bob-alice-fixup2.ed b/Documentation/tutorial-script/0022-bob-alice-fixup2.ed
index 18c90d4..d8c5746 100644
--- a/Documentation/tutorial-script/0022-bob-alice-fixup2.ed
+++ b/Documentation/tutorial-script/0022-bob-alice-fixup2.ed
@@ -1,5 +1,5 @@
/^#include "stack\.h"/+1d
/^#include "lexer\.h"/+1,/^#include "stack\.h"/d
-/^<<<<<<< rpn\.c/-1,/^>>>>>>> \.merge_file_/d
+/^<<<<<<< master/-1,/^>>>>>>> origin/d
w
q
diff --git a/Documentation/tutorial-script/script.sh b/Documentation/tutorial-script/script.sh
index bc70b77..edcebda 100755
--- a/Documentation/tutorial-script/script.sh
+++ b/Documentation/tutorial-script/script.sh
@@ -120,13 +120,13 @@ cg-update bobswork && should_fail
# difference between her version and Bob's:
#: ...
-#: <<<<<<< rpn.c
+#: <<<<<<< bob
#: extern double pop(void);
#: extern void push(double);
#: extern void clear(void);
#:
#: =======
-#: >>>>>>> .merge_file_5wCNZT
+#: >>>>>>> bobswork
#: extern int getsym(void);
#: ...
@@ -216,7 +216,7 @@ cg-merge bob && should_fail
# Merge fails:
#: ...
-#: <<<<<<< Makefile
+#: <<<<<<< .merge_file_l54ztH
#: $(CC) $(CFLAGS) $^ -lm -o $@
#: =======
#: $(CC) $(CFLAGS) $^ -o $@
@@ -235,31 +235,31 @@ cg-merge charlie && should_fail
# Merge conflicts!
#: ...
-#: <<<<<<< Makefile
-#: $(CC) $(CFLAGS) $^ -lm -o $@
-#:
+#: <<<<<<< master
+#: $(CC) $(CFLAGS) $^ -lm -o $@
+#:
#: rpn.o: stack.h
#: stack.o: stack.h
-#: lexer.o:
+#: lexer.o:
#: =======
-#: $(CC) $(CFLAGS) $^ -o $@
-#:
+#: $(CC) $(CFLAGS) $^ -o $@
+#:
#: rpn.o lexer.o: lexer.h
-#:
-#: >>>>>>> .merge_file_huuX9C
+#:
+#: >>>>>>> charlie
ed Makefile < $TOP/0018-alice-charlie-fixup1.ed
#: ...
-#: <<<<<<< rpn.c
+#: <<<<<<< master
#: extern int getsym(void);
#:
#: =======
#: extern double pop(void);
#: extern void push(double);
#: extern void clear(void);
-#:
-#: >>>>>> .merge_file_qtv6VA
+#:
+#: >>>>>>> charlie
#: ...
ed rpn.c < $TOP/0019-alice-charlie-fixup2.ed
@@ -273,7 +273,7 @@ cg-add CONTRIBUTORS
cg-commit -m "Add CONTRIBUTORS"
# Wrong file name...
-git rename CONTRIBUTORS CREDITS
+cg-mv CONTRIBUTORS CREDITS
cg-commit -m "Rename CONTRIBUTORS to CREDITS"
@@ -308,6 +308,7 @@ echo "Merge with 0.4" | cg-merge && shou
# Mishandled stack.h
ed Makefile < $TOP/0021-bob-alice-fixup1.ed
ed rpn.c < $TOP/0022-bob-alice-fixup2.ed
+cp stack.h~master stack.h
ed stack.h < $TOP/0023-bob-alice-fixup3.ed
cg-add stack.h
^ permalink raw reply related
* [PATCH 3/3] Allow the tutorial script to be run by "make test"
From: Pavel Roskin @ 2006-03-03 1:11 UTC (permalink / raw)
To: git, Petr Baudis
In-Reply-To: <20060303011154.14619.71590.stgit@dv.roinet.com>
Signed-off-by: Pavel Roskin <proski@gnu.org>
---
Documentation/Makefile | 4 ++++
Documentation/tutorial-script/Makefile | 5 +++++
Makefile | 1 +
3 files changed, 10 insertions(+), 0 deletions(-)
diff --git a/Documentation/Makefile b/Documentation/Makefile
index 3aad2fb..e5508e8 100644
--- a/Documentation/Makefile
+++ b/Documentation/Makefile
@@ -55,7 +55,11 @@ install-html: html
$(INSTALL) -m755 -d $(DESTDIR)/$(htmldir)
$(INSTALL) $(DOC_HTML) $(DESTDIR)/$(htmldir)
+test:
+ make -C tutorial-script test
+
clean:
+ make -C tutorial-script clean
rm -f *.xml *.html *.1 *.7 cg*.txt $(PACKAGE).txt
.PRECIOUS: cg%.txt
diff --git a/Documentation/tutorial-script/Makefile b/Documentation/tutorial-script/Makefile
new file mode 100644
index 0000000..bdf384f
--- /dev/null
+++ b/Documentation/tutorial-script/Makefile
@@ -0,0 +1,5 @@
+test:
+ ./script.sh
+
+clean:
+ rm -rf Playground
diff --git a/Makefile b/Makefile
index 994b182..2b53641 100644
--- a/Makefile
+++ b/Makefile
@@ -59,6 +59,7 @@ doc:
test: all
$(MAKE) -C t/ all
+ $(MAKE) -C Documentation/ test
^ permalink raw reply related
* Re: [PATCH] fmt-merge-msg: avoid open "-|" list form for Perl 5.6
From: Linus Torvalds @ 2006-03-03 0:49 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7v1wxk5ptf.fsf@assigned-by-dhcp.cox.net>
On Thu, 2 Mar 2006, Junio C Hamano wrote:
>
> And you had lt/rev-list branch first listed in FETCH_HEAD. In
> this particular example, lt/rev-list has only 3 commits on top
> of common things, but if your max were 3 instead of 10, the
> first round would actually show the tip 3 without showing any
> common stuff, and then the next round to show fk/blame branch
> would show only the remaining two, without ever showing the
> common stuff, even though it _could_ say the latest of the
> common stuff.
Yes. I considered it briefly, and it's fixable, but to fix it you'd
have to actualyl walk the parent list yourself, rather than letting
get_revision do it all for you.
And what my simple thing shows isn't really technically "wrong", since it
has shown that there are commits missing from the output with the "..."
The question is just whether shared commits should be "balanced out", or
shown as part of the first branch that merged them. I chose the latter,
because it's not only simple, it's unambiguous (any balancing algorithm
will depend on some random heuristic or other, and on how many commits are
shown.
> > - the old one did some formatting of the branch message that I don't
> > follow because I'm not a perl user. The new one just takes the
> > explanatory message for the branch merging as-is.
>
> FETCH_HEAD has explanatory message in more or less "canonical"
> form. It has noise word "branch", and the current repository is
> typically " of .".
Yeah, I actually looked at a few examples, so I knew what it was basically
trying to do, and then I ignored it as not interesting to the exercise,
which was to abuse the new revision listing library in interesting ways by
calling it multiple times.
Linus
^ permalink raw reply
* Re: [PATCH] fmt-merge-msg: avoid open "-|" list form for Perl 5.6
From: Junio C Hamano @ 2006-03-03 0:34 UTC (permalink / raw)
To: Linus Torvalds; +Cc: git
In-Reply-To: <Pine.LNX.4.64.0603021521250.22647@g5.osdl.org>
Linus Torvalds <torvalds@osdl.org> writes:
> For example, afaik, when merging multiple branches that had partially been
> merged already (ie they had overlapping new stuff), if I read the old perl
> code correctly, it would talk about the new stuff multiple times. This one
> doesn't.
I think this is not quite right, even though it only matters in
Octopus and not many people do Octopus anyway. Suppose you are
merging lt/rev-list and fk/blame branches into master, starting
from this state:
! [master] GIT-VERSION-GEN: squelch unneed
! [lt/rev-list] setup_revisions(): handle
! [fk/blame] git-blame, take 2
---
+ [lt/rev-list] setup_revisions(): handl
+ [lt/rev-list^] git-log (internal): mor
+ [lt/rev-list~2] git-log (internal): ad
+ [fk/blame] git-blame, take 2
- [fk/blame^] Merge part of 'lt/rev-list
++ [lt/rev-list~3] Rip out merge-order an
++ [lt/rev-list~4] Tie it all together: "
++ [lt/rev-list~5] Introduce trivial new
++ [lt/rev-list~6] git-rev-list libificat
++ [lt/rev-list~7] Splitting rev-list int
++ [lt/rev-list~8] rev-list split: minimu
++ [lt/rev-list~9] First cut at libifying
+ [fk/blame~2] Add git-blame, a tool for
--- [lt/rev-list~10] Merge branch 'maint'
And you had lt/rev-list branch first listed in FETCH_HEAD. In
this particular example, lt/rev-list has only 3 commits on top
of common things, but if your max were 3 instead of 10, the
first round would actually show the tip 3 without showing any
common stuff, and then the next round to show fk/blame branch
would show only the remaining two, without ever showing the
common stuff, even though it _could_ say the latest of the
common stuff.
> The things it doesn't do:
> - the old one had a limit of 20, the new one has a limit of 10 commits
> reported
Good change I would say, except for the above.
> - the old one was tested, the new one is written by me.
> - the old one honored the "merge.summary" git config option. The new one
> doesn't.
Easily rectifiable ;-).
> - the old one did some formatting of the branch message that I don't
> follow because I'm not a perl user. The new one just takes the
> explanatory message for the branch merging as-is.
FETCH_HEAD has explanatory message in more or less "canonical"
form. It has noise word "branch", and the current repository is
typically " of .". These are removed by the code, so that you would
not have to see:
Merge branch 'jc/delta' of .
Instead you would see:
Merge 'jc/delta' into 'next'.
The last part, " into 'next'", is also missing from your
version. I can distinguish a merge into 'master' (which does
not have " into 'master'") and other branches easily that way,
and I find it handy.
Other things the Perl code does are purely for Octopus support:
things like coalescing multiple branches taken from the same
repositories. You would get something like:
Merge 'lt/rev-list' and 'fk/blame' into 'next'.
* lt/rev-list:
commit 1
commit 2
* fk/blame:
commit 3
commit 4
instead of (your version):
Merge branch 'lt/rev-list' of .
* commit 1
* commit 2
Merge branch 'fk/blame' of .
* commit 3
* commit 4
^ permalink raw reply
* Re: cygwin: push/pull takes very long time
From: Christopher Faylor @ 2006-03-03 0:28 UTC (permalink / raw)
To: Git Mailing List
In-Reply-To: <20060302215408.GC6183@steel.home>
On Thu, Mar 02, 2006 at 10:54:08PM +0100, Alex Riesen wrote:
>Alex Riesen, Thu, Mar 02, 2006 18:09:23 +0100:
>>I'll cleanup the profiling code and send it as well soon (I had to
>>instrument x*alloc).
>
>This is not exactly the same. It counts free as well, even if that is
>not really interesting - there are places were there is more frees than
>allocs. Probably something missed or a result coming from libc.
>
>Also it is _not_ the code I used for windows. I had to have a global
>variable for argv[0], which needs modification of all main()s, which
>gets too easily out of sync.
I wasn't following this discussion closely so maybe this is useless
information, but for Cygwin you can either use the undocumented global
__argv or you can use /proc/cmdline. /proc/self/cmdline is going to be
pretty slow, however.
It looks like pure Windows console apps define _argv in stdlib.h also
but I've never used this and don't know if it is what it looks like.
cgf
^ permalink raw reply
* Re: [PATCH] fmt-merge-msg: avoid open "-|" list form for Perl 5.6
From: Christopher Faylor @ 2006-03-03 0:14 UTC (permalink / raw)
To: git
In-Reply-To: <20060302220930.GE6183@steel.home>
On Thu, Mar 02, 2006 at 11:09:30PM +0100, Alex Riesen wrote:
>Shawn Pearce, Thu, Mar 02, 2006 17:55:10 +0100:
>>Maybe I missed this but why are people using the native Windows
>>ActiveState Perl with GIT+Cygwin when Cygwin has a Cygwin-ized Perl
>>installation available?
>
>because the people _can't_ use cygwin's perl. There are a lot of
>reasons mainly: administrative, perl script incompatibilities and
>cygwin.dll incompatibilities (if you use perl from cygwin, it'll need
>the correct cygwin.dll. And if a build process uses cygwin tools from,
>for example, QNX Momentics it often comes to clashes).
(Hmm. I wonder if QNX Momentics is YA GPL violator)
If you have multiple versions of the Cygwin DLL on your system and try
to use them all jumbled up together then, yes, you will have problems.
This isn't a perl-specific issue. The solution is to put the latest
version of your Cygwin DLL in your path (presumably in /bin) and delete
all of the older ones.
The newest version is undoubtedly going to be the one downloaded from
the Cygwin web site (http://cygwin.com/) but you can get version
information from the cygwin DLL by using grep:
grep -a "^%%% Cygwin" WHEREEVER/cygwin1.dll
if you are not inclined to install the newest version of Cygwin.
I'm sure that there are incompatibilities between ActiveState perl and
Cygwin's perl which make it hard to use the same scripts in each so I am
not doubting that some people might want to use only ActiveState perl.
I don't see how the multiple Cygwin DLL issue can be a problem only for
Cygwin perl vs. ActiveState perl.
cgf
(who sees a new full-time job looming in the git list)
^ permalink raw reply
* Re: Problems with using git
From: Greg KH @ 2006-03-02 23:58 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Andreas Ericsson, git
In-Reply-To: <7vr75k5s4y.fsf@assigned-by-dhcp.cox.net>
On Thu, Mar 02, 2006 at 03:44:13PM -0800, Junio C Hamano wrote:
> Andreas Ericsson <ae@op5.se> writes:
>
> > Joseph Wakeling wrote:
> >> Thanks very much to all who offered advice on this. :-)
> >> Unfortunately openSUSE is somewhat out of sync not just with git but
> >> in
> >> libraries necessary to install the latest version (libcrypto.so.4,
> >> libssl.so.4). The openssl (0.9.7g-2.4) and openssl-devel (0.9.7g-2)
> >> packages don't contain these but rather contain libcrypto.so.0.9.7 and
> >> libssl.0.9.7. Just in case it's important to future git development.
> >
> > It might be useful for the openSuSE developers, but for git this is
> > totally irrelevant.
>
> True, but I had an impression that we had active developers in
> git community who are close to Suse, and I wonder why this
> hadn't come up earlier. Maybe our userbase and Suse's userbase
> do not overlap much?
Yes, some of us are quite close to SuSE :)
Anyway, the issue is that 10.0 was released about 6 months ago, and
contains the version of git at that time. The latest development tree,
and the latest public betas contain 1.1.3. If you think this should be
newer, I can easily go poke the proper people...
thanks,
greg k-h
^ permalink raw reply
* Re: Problems with using git
From: Junio C Hamano @ 2006-03-02 23:44 UTC (permalink / raw)
To: Andreas Ericsson; +Cc: git
In-Reply-To: <4406FA46.7080608@op5.se>
Andreas Ericsson <ae@op5.se> writes:
> Joseph Wakeling wrote:
>> Thanks very much to all who offered advice on this. :-)
>> Unfortunately openSUSE is somewhat out of sync not just with git but
>> in
>> libraries necessary to install the latest version (libcrypto.so.4,
>> libssl.so.4). The openssl (0.9.7g-2.4) and openssl-devel (0.9.7g-2)
>> packages don't contain these but rather contain libcrypto.so.0.9.7 and
>> libssl.0.9.7. Just in case it's important to future git development.
>
> It might be useful for the openSuSE developers, but for git this is
> totally irrelevant.
True, but I had an impression that we had active developers in
git community who are close to Suse, and I wonder why this
hadn't come up earlier. Maybe our userbase and Suse's userbase
do not overlap much?
^ permalink raw reply
* Re: Problems with using git
From: Greg KH @ 2006-03-02 23:21 UTC (permalink / raw)
To: Joseph Wakeling; +Cc: git
In-Reply-To: <4406F8B1.9050303@webdrake.net>
On Thu, Mar 02, 2006 at 01:52:49PM +0000, Joseph Wakeling wrote:
> Thanks very much to all who offered advice on this. :-)
>
> Unfortunately openSUSE is somewhat out of sync not just with git but in
> libraries necessary to install the latest version (libcrypto.so.4,
> libssl.so.4). The openssl (0.9.7g-2.4) and openssl-devel (0.9.7g-2)
> packages don't contain these but rather contain libcrypto.so.0.9.7 and
> libssl.0.9.7. Just in case it's important to future git development.
If you use the latest openSUSE betas or the FACTORY tree, git 1.1.3 is
available there.
10.0 was released six months or so ago, so that is why it contains an
older version of git.
thanks,
greg k-h
^ permalink raw reply
* Re: [PATCH] fmt-merge-msg: avoid open "-|" list form for Perl 5.6
From: Linus Torvalds @ 2006-03-02 23:27 UTC (permalink / raw)
To: Alex Riesen; +Cc: Shawn Pearce, git
In-Reply-To: <20060302220930.GE6183@steel.home>
On Thu, 2 Mar 2006, Alex Riesen wrote:
> Shawn Pearce, Thu, Mar 02, 2006 17:55:10 +0100:
>
> > I've been using the Cygwin Perl with GIT without any problems
> > whatsoever. Including the open(I, "-|")... exec(@argv) code that
> > doesn't work correctly in ActiveState and started this whole thread.
>
> Unfortunately...
Here's a stupid first cut at git-fmt-merge-msg in C using the new revlist
library interface.
It's not actually doing exactly the same thing, because I'm a lazy
bastard, but some things it does better.
For example, afaik, when merging multiple branches that had partially been
merged already (ie they had overlapping new stuff), if I read the old perl
code correctly, it would talk about the new stuff multiple times. This one
doesn't.
The things it doesn't do:
- the old one had a limit of 20, the new one has a limit of 10 commits
reported
- the old one was tested, the new one is written by me.
- the old one honored the "merge.summary" git config option. The new one
doesn't.
- the old one did some formatting of the branch message that I don't
follow because I'm not a perl user. The new one just takes the
explanatory message for the branch merging as-is.
But hey, this is all part of my cunning plan to make people get involved
with the new rev-list libification, by giving them things that _almost_
work, but might need some tweaking.
Linus
--- snip snip for "fmt-merge-msg.c" snip snip---
/*
* fmt-merge-msg.c
*
* Magic auto-generation of merge messages.
*
* Copyright (C) 2006 Linus Torvalds and his army of programming ferrets
*/
#include "cache.h"
#include "commit.h"
#include "revision.h"
static void show_commit(struct commit *commit)
{
char buffer[256];
pretty_print_commit(CMIT_FMT_ONELINE, commit, ~0, buffer, sizeof(buffer), 0);
printf(" * %s\n", buffer);
}
int main(int argc, char **argv)
{
struct rev_info revs;
struct commit *commit;
unsigned char sha1[20];
char buffer[256];
setup_revisions(0, NULL, &revs, NULL);
if (get_sha1("HEAD", sha1) < 0)
die("no HEAD revision");
commit = lookup_commit_reference(sha1);
if (!commit)
die("no HEAD revision");
commit->object.flags |= UNINTERESTING;
insert_by_date(commit, &revs.commits);
revs.topo_order = 1;
revs.limited = 1;
while (fgets(buffer, sizeof(buffer), stdin)) {
int max;
char *marker;
if (get_sha1_hex(buffer, sha1) < 0)
continue;
commit = lookup_commit_reference(sha1);
if (!commit)
continue;
/*
* Format after the SHA1:
* <tab>marker<tab><type>'<name>' of <src>'
*
* where string is "not-for-merge" if
* we're not interested in this one,
* and empty otherwise.
*/
marker = buffer + 40;
if (*marker++ != '\t')
continue;
if (*marker++ != '\t')
continue;
printf("Merge %s", marker);
insert_by_date(commit, &revs.commits);
prepare_revision_walk(&revs);
max = 10;
while ((commit = get_revision(&revs)) != NULL) {
int n = --max;
if (n > 0)
show_commit(commit);
else if (!n)
printf(" ...");
}
}
}
^ permalink raw reply
* [PATCH] annotate should number lines starting with 1
From: Luck, Tony @ 2006-03-02 23:27 UTC (permalink / raw)
To: git
C programmers are well used to counting from zero, but every
other text file tool starts counting from 1.
Signed-off-by: Tony Luck <tony.luck@intel.com>
---
diff --git a/git-annotate.perl b/git-annotate.perl
index 08d479f..d93ee19 100755
--- a/git-annotate.perl
+++ b/git-annotate.perl
@@ -128,7 +128,7 @@ foreach my $l (@filelines) {
}
printf("%s\t(%10s\t%10s\t%d)%s\n", $rev, $committer,
- format_date($date), $i++, $output);
+ format_date($date), ++$i, $output);
}
sub init_claim {
^ permalink raw reply related
* Re: git-cvsimport broken?
From: Martin Langhoff @ 2006-03-02 22:56 UTC (permalink / raw)
To: H. Peter Anvin; +Cc: git
In-Reply-To: <440775FB.4000300@zytor.com>
On 3/3/06, H. Peter Anvin <hpa@zytor.com> wrote:
> Have other people seen this problem?
Been running imports recently (with a cvsimport not more that 3 days
old). No problem.
m
^ permalink raw reply
* Re: git-cvsimport broken?
From: H. Peter Anvin @ 2006-03-02 22:54 UTC (permalink / raw)
To: H. Peter Anvin; +Cc: git
In-Reply-To: <440775FB.4000300@zytor.com>
H. Peter Anvin wrote:
> I have started consistently getting the following error trying to do a
> git-cvsimport into an empty directory:
>
> + git cvsimport -C /home/hpa/local/kernel-cvs-import -k -u -m -A
> /home/hpa/local/authors -d /home/hpa/local/cvsroot
> project/sw/kernel/linux-2.6
> cp: cannot stat `/export/hpa/kernel-cvs-import/.git/refs/heads/origin':
> No such file or directory
> fatal: master: not a valid SHA1
> fatal: 'HEAD': No such file or directory
> usage: git-read-tree (<sha> | -m [-u | -i] <sha1> [<sha2> [<sha3>]])
> checkout failed: 256
>
Turns out to be user error (the CVS module is "projects", not
"project"), but that probably indicates something that could use a
better error message, in particular: if there are zero changesets.
-hpa
^ permalink raw reply
* git-cvsimport broken?
From: H. Peter Anvin @ 2006-03-02 22:47 UTC (permalink / raw)
To: git
I have started consistently getting the following error trying to do a
git-cvsimport into an empty directory:
+ git cvsimport -C /home/hpa/local/kernel-cvs-import -k -u -m -A
/home/hpa/local/authors -d /home/hpa/local/cvsroot
project/sw/kernel/linux-2.6
cp: cannot stat `/export/hpa/kernel-cvs-import/.git/refs/heads/origin':
No such file or directory
fatal: master: not a valid SHA1
fatal: 'HEAD': No such file or directory
usage: git-read-tree (<sha> | -m [-u | -i] <sha1> [<sha2> [<sha3>]])
checkout failed: 256
After failing, the directory in question contains the output of
git-init-db, including a HEAD file which contains a symbolic reference
to a nonexistent branch (which makes sense, since there has been no
checkins yet.)
Have other people seen this problem?
-hpa
^ permalink raw reply
* Re: impure renames / history tracking
From: linux @ 2006-03-02 22:24 UTC (permalink / raw)
To: git, paul
>> Yes, but imo a poor one, as you're losing all the history.
>
> Well, not per se. You might keep the original 'detail' branch. It's a
> terminal branch obviously, you can't pull master's changes to it once
> the aggregate patch goes into master. But you can keep it around.
Actually, you can! That's what the "ours" merge stratgy is for!
It creates a merge whose result is a verbatim copy of the first parent.
The intended use is for when you've cherry-picked or otherwise manually
merged everything interesting from a branch and want to tie up the loose
end so you can delete the branch name.
^ 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