* [PATCH] Fix debian doc-base
From: Kalle Valo @ 2005-08-03 23:39 UTC (permalink / raw)
To: git
Fixed location of HTML documents in debian doc-base file.
Without this fix debian package won't install properly (complains
about missing /usr/share/doc/git-core/html directory).
---
debian/git-core.doc-base | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
194759c0447f88804dfb43615bdf7a6e412c3240
diff --git a/debian/git-core.doc-base b/debian/git-core.doc-base
--- a/debian/git-core.doc-base
+++ b/debian/git-core.doc-base
@@ -5,8 +5,8 @@ Abstract: This manual describes git
Section: Devel
Format: HTML
-Index: /usr/share/doc/git-core/html/git.html
-Files: /usr/share/doc/git-core/html/*.html
+Index: /usr/share/doc/git-core/git.html
+Files: /usr/share/doc/git-core/*.html
Format: text
Files: /usr/share/doc/git-core/git-core.txt
^ permalink raw reply
* [PATCH] (preview) Renaming push.
From: Junio C Hamano @ 2005-08-03 23:25 UTC (permalink / raw)
To: git; +Cc: Linus Torvalds
In-Reply-To: <Pine.LNX.4.58.0508031102590.3258@g5.osdl.org>
Linus Torvalds <torvalds@osdl.org> writes:
> The real problem with git-send-pack is that the local and remote names
> have to be the same, which is a bug, really. It _should_ be perfectly fine
> to do something like
>
> git-send-pack ..dest.. localname:remotename
>
> which would push the local "localname" branch to the remote "remotename"
> branch.
Yes, and that is what I have been cooking today ;-).
This patch is a preview, only because I have not converted the
pull side yet. My limited testing shows that you can push refs
under different names fine with this patch.
The plan is to also let people say the renaming for pull side
like this.
git-fetch-pack <remote> remotename:localname...
Note that remote/local is confusing when we consider both pull
and push sides, so we should call them srcname and dstname. The
commit message uses these words.
-jc
------------
This allows git-send-pack to push local refs to a destination
repository under different names.
Here is the name mapping rules for refs.
* If there is no ref mapping on the command line:
- if '--all' is specified, it is equivalent to specifying
<local> ":" <local> for all the existing local refs on the
command line
- otherwise, it is equivalent to specifying <ref> ":" <ref> for
all the refs that exist on both sides.
* <name> is just a shorthand for <name> ":" <name>
* <src> ":" <dst>
push ref that matches <src> to ref that matches <dst>.
- It is an error if <src> does not match exactly one of local
refs.
- It is an error if <dst> matches more than one remote refs.
- If <dst> does not match any remote refs, either
- it has to start with "refs/"; <dst> is used as the
destination literally in this case.
- <src> == <dst> and the ref that matched the <src> must not
exist in the set of remote refs; the ref matched <src>
locally is used as the name of the destination.
For example,
- "git-send-pack --all <remote>" works exactly as before;
- "git-send-pack <remote> master:upstream" pushes local master
to remote ref that matches "upstream". If there is no such
ref, it is an error.
- "git-send-pack <remote> master:refs/heads/upstream" pushes
local master to remote refs/heads/upstream, even when
refs/heads/upstream does not exist.
- "git-send-pack <remote> master" into an empty remote
repository pushes the local ref/heads/master to the remote
ref/heads/master.
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
cache.h | 3 +
connect.c | 172 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
send-pack.c | 146 ++++++++++++++++++++------------------------------
3 files changed, 230 insertions(+), 91 deletions(-)
b959d297c7206b0b634160ac015122f70389415b
diff --git a/cache.h b/cache.h
--- a/cache.h
+++ b/cache.h
@@ -298,12 +298,15 @@ struct ref {
struct ref *next;
unsigned char old_sha1[20];
unsigned char new_sha1[20];
+ struct ref *peer_ref; /* when renaming */
char name[0];
};
extern int git_connect(int fd[2], char *url, const char *prog);
extern int finish_connect(pid_t pid);
extern int path_match(const char *path, int nr, char **match);
+extern int match_refs(struct ref *src, struct ref *dst, struct ref ***dst_tail,
+ int nr_refspec, char **refspec, int all);
extern int get_ack(int fd, unsigned char *result_sha1);
extern struct ref **get_remote_heads(int in, struct ref **list, int nr_match, char **match);
diff --git a/connect.c b/connect.c
--- a/connect.c
+++ b/connect.c
@@ -31,11 +31,9 @@ struct ref **get_remote_heads(int in, st
name = buffer + 41;
if (nr_match && !path_match(name, nr_match, match))
continue;
- ref = xmalloc(sizeof(*ref) + len - 40);
+ ref = xcalloc(1, sizeof(*ref) + len - 40);
memcpy(ref->old_sha1, old_sha1, 20);
- memset(ref->new_sha1, 0, 20);
memcpy(ref->name, buffer + 41, len - 40);
- ref->next = NULL;
*list = ref;
list = &ref->next;
}
@@ -81,6 +79,174 @@ int path_match(const char *path, int nr,
return 0;
}
+struct refspec {
+ char *src;
+ char *dst;
+};
+
+static struct refspec *parse_ref_spec(int nr_refspec, char **refspec)
+{
+ int i;
+ struct refspec *rs = xmalloc(sizeof(*rs) * (nr_refspec + 1));
+ for (i = 0; i < nr_refspec; i++) {
+ char *sp, *dp, *ep;
+ sp = refspec[i];
+ ep = strchr(sp, ':');
+ if (ep) {
+ dp = ep + 1;
+ *ep = 0;
+ }
+ else
+ dp = sp;
+ rs[i].src = sp;
+ rs[i].dst = dp;
+ }
+ rs[nr_refspec].src = rs[nr_refspec].dst = NULL;
+ return rs;
+}
+
+static int count_refspec_match(const char *pattern,
+ struct ref *refs,
+ struct ref **matched_ref)
+{
+ int match;
+ int patlen = strlen(pattern);
+
+ for (match = 0; refs; refs = refs->next) {
+ char *name = refs->name;
+ int namelen = strlen(name);
+ if (namelen < patlen ||
+ memcmp(name + namelen - patlen, pattern, patlen))
+ continue;
+ if (namelen != patlen && name[namelen - patlen - 1] != '/')
+ continue;
+ match++;
+ *matched_ref = refs;
+ }
+ return match;
+}
+
+static void link_dst_tail(struct ref *ref, struct ref ***tail)
+{
+ **tail = ref;
+ *tail = &ref->next;
+ **tail = NULL;
+}
+
+static int match_explicit_refs(struct ref *src, struct ref *dst,
+ struct ref ***dst_tail, struct refspec *rs)
+{
+ int i, errs;
+ for (i = errs = 0; rs[i].src; i++) {
+ struct ref *matched_src, *matched_dst;
+
+ matched_src = matched_dst = NULL;
+ switch (count_refspec_match(rs[i].src, src, &matched_src)) {
+ case 1:
+ break;
+ case 0:
+ errs = 1;
+ error("src refspec %s does not match any.");
+ break;
+ default:
+ errs = 1;
+ error("src refspec %s matches more than one.",
+ rs[i].src);
+ break;
+ }
+ switch (count_refspec_match(rs[i].dst, dst, &matched_dst)) {
+ case 1:
+ break;
+ case 0:
+ if (!memcmp(rs[i].dst, "refs/", 5)) {
+ int len = strlen(rs[i].dst) + 1;
+ matched_dst = xcalloc(1, sizeof(*dst) + len);
+ memcpy(matched_dst->name, rs[i].dst, len);
+ link_dst_tail(matched_dst, dst_tail);
+ }
+ else if (!strcmp(rs[i].src, rs[i].dst) &&
+ matched_src) {
+ /* pushing "master:master" when
+ * remote does not have master yet.
+ */
+ int len = strlen(matched_src->name);
+ matched_dst = xcalloc(1, sizeof(*dst) + len);
+ memcpy(matched_dst->name, matched_src->name,
+ len);
+ link_dst_tail(matched_dst, dst_tail);
+ }
+ else {
+ errs = 1;
+ error("dst refspec %s does not match any "
+ "existing ref on the remote and does "
+ "not start with refs/.", rs[i].dst);
+ }
+ break;
+ default:
+ errs = 1;
+ error("dst refspec %s matches more than one.",
+ rs[i].dst);
+ break;
+ }
+ if (errs)
+ continue;
+ if (matched_src->peer_ref) {
+ errs = 1;
+ error("src ref %s is sent to more than one dst.",
+ matched_src->name);
+ }
+ else
+ matched_src->peer_ref = matched_dst;
+ if (matched_dst->peer_ref) {
+ errs = 1;
+ error("dst ref %s receives from more than one src.",
+ matched_dst->name);
+ }
+ else
+ matched_dst->peer_ref = matched_src;
+ }
+ return -errs;
+}
+
+static struct ref *find_ref_by_name(struct ref *list, const char *name)
+{
+ for ( ; list; list = list->next)
+ if (!strcmp(list->name, name))
+ return list;
+ return NULL;
+}
+
+int match_refs(struct ref *src, struct ref *dst, struct ref ***dst_tail,
+ int nr_refspec, char **refspec, int all)
+{
+ struct refspec *rs = parse_ref_spec(nr_refspec, refspec);
+
+ if (nr_refspec)
+ return match_explicit_refs(src, dst, dst_tail, rs);
+
+ /* pick the remainder */
+ for ( ; src; src = src->next) {
+ struct ref *dst_peer;
+ if (src->peer_ref)
+ continue;
+ dst_peer = find_ref_by_name(dst, src->name);
+ if (dst_peer && dst_peer->peer_ref)
+ continue;
+ if (!dst_peer) {
+ if (!all)
+ continue;
+ /* Create a new one and link it */
+ int len = strlen(src->name) + 1;
+ dst_peer = xcalloc(1, sizeof(*dst_peer) + len);
+ memcpy(dst_peer->name, src->name, len);
+ memcpy(dst_peer->new_sha1, src->new_sha1, 20);
+ link_dst_tail(dst_peer, dst_tail);
+ }
+ dst_peer->peer_ref = src;
+ }
+ return 0;
+}
+
enum protocol {
PROTO_LOCAL = 1,
PROTO_SSH,
diff --git a/send-pack.c b/send-pack.c
--- a/send-pack.c
+++ b/send-pack.c
@@ -43,7 +43,8 @@ static void exec_rev_list(struct ref *re
char *buf = malloc(100);
if (i > 900)
die("git-rev-list environment overflow");
- if (!is_zero_sha1(refs->old_sha1)) {
+ if (!is_zero_sha1(refs->old_sha1) &&
+ has_sha1_file(refs->old_sha1)) {
args[i++] = buf;
snprintf(buf, 50, "^%s", sha1_to_hex(refs->old_sha1));
buf += 50;
@@ -103,21 +104,6 @@ static int pack_objects(int fd, struct r
return 0;
}
-static int read_ref(const char *ref, unsigned char *sha1)
-{
- int fd, ret;
- char buffer[60];
-
- fd = open(git_path("%s", ref), O_RDONLY);
- if (fd < 0)
- return -1;
- ret = -1;
- if (read(fd, buffer, sizeof(buffer)) >= 40)
- ret = get_sha1_hex(buffer, sha1);
- close(fd);
- return ret;
-}
-
static int ref_newer(const unsigned char *new_sha1, const unsigned char *old_sha1)
{
struct commit *new, *old;
@@ -143,108 +129,92 @@ static int ref_newer(const unsigned char
return 0;
}
-static int local_ref_nr_match;
-static char **local_ref_match;
-static struct ref *local_ref_list;
-static struct ref **local_last_ref;
+static struct ref *local_refs, **local_tail;
+static struct ref *remote_refs, **remote_tail;
-static int try_to_match(const char *refname, const unsigned char *sha1)
+static int one_local_ref(const char *refname, const unsigned char *sha1)
{
struct ref *ref;
- int len;
-
- if (!path_match(refname, local_ref_nr_match, local_ref_match)) {
- if (!send_all)
- return 0;
-
- /* If we have it listed already, skip it */
- for (ref = local_ref_list ; ref ; ref = ref->next) {
- if (!strcmp(ref->name, refname))
- return 0;
- }
- }
-
- len = strlen(refname)+1;
- ref = xmalloc(sizeof(*ref) + len);
- memset(ref->old_sha1, 0, 20);
+ int len = strlen(refname) + 1;
+ ref = xcalloc(1, sizeof(*ref) + len);
memcpy(ref->new_sha1, sha1, 20);
memcpy(ref->name, refname, len);
- ref->next = NULL;
- *local_last_ref = ref;
- local_last_ref = &ref->next;
+ *local_tail = ref;
+ local_tail = &ref->next;
return 0;
}
-static int send_pack(int in, int out, int nr_match, char **match)
+static void get_local_heads(void)
+{
+ local_tail = &local_refs;
+ for_each_ref(one_local_ref);
+}
+
+static int send_pack(int in, int out, int nr_refspec, char **refspec)
{
- struct ref *ref_list, **last_ref;
struct ref *ref;
int new_refs;
- /* First we get all heads, whether matching or not.. */
- last_ref = get_remote_heads(in, &ref_list, 0, NULL);
-
+ /* No funny business with the matcher */
+ remote_tail = get_remote_heads(in, &remote_refs, 0, NULL);
+ get_local_heads();
+
+ /* match them up */
+ if (!remote_tail)
+ remote_tail = &remote_refs;
+ if (match_refs(local_refs, remote_refs, &remote_tail,
+ nr_refspec, refspec, send_all))
+ return -1;
/*
- * Go through the refs, see if we want to update
- * any of them..
+ * Finally, tell the other end!
*/
- for (ref = ref_list; ref; ref = ref->next) {
- unsigned char new_sha1[20];
- char *name = ref->name;
-
- if (nr_match && !path_match(name, nr_match, match))
- continue;
-
- if (read_ref(name, new_sha1) < 0)
- continue;
-
- if (!memcmp(ref->old_sha1, new_sha1, 20)) {
- fprintf(stderr, "'%s' unchanged\n", name);
+ new_refs = 0;
+ for (ref = remote_refs; ref; ref = ref->next) {
+ char old_hex[60], *new_hex;
+ if (!ref->peer_ref)
continue;
+ if (!is_zero_sha1(ref->old_sha1)) {
+ if (!has_sha1_file(ref->old_sha1)) {
+ error("remote '%s' object %s does not "
+ "exist on local",
+ ref->name, sha1_to_hex(ref->old_sha1));
+ continue;
+ }
+ if (!ref_newer(ref->peer_ref->new_sha1,
+ ref->old_sha1)) {
+ error("remote ref '%s' is not a strict "
+ "subset of local ref '%s'.", ref->name,
+ ref->peer_ref->name);
+ continue;
+ }
}
-
- if (!ref_newer(new_sha1, ref->old_sha1)) {
- error("remote '%s' isn't a strict parent of local", name);
+ if (!memcmp(ref->old_sha1, ref->peer_ref->new_sha1, 20)) {
+ fprintf(stderr, "'%s': up-to-date\n", ref->name);
continue;
}
-
- /* Ok, mark it for update */
- memcpy(ref->new_sha1, new_sha1, 20);
- }
-
- /*
- * See if we have any refs that the other end didn't have
- */
- if (nr_match || send_all) {
- local_ref_nr_match = nr_match;
- local_ref_match = match;
- local_ref_list = ref_list;
- local_last_ref = last_ref;
- for_each_ref(try_to_match);
- }
-
- /*
- * Finally, tell the other end!
- */
- new_refs = 0;
- for (ref = ref_list; ref; ref = ref->next) {
- char old_hex[60], *new_hex;
- if (is_zero_sha1(ref->new_sha1))
+ memcpy(ref->new_sha1, ref->peer_ref->new_sha1, 20);
+ if (is_zero_sha1(ref->new_sha1)) {
+ error("cannot happen anymore");
continue;
+ }
new_refs++;
strcpy(old_hex, sha1_to_hex(ref->old_sha1));
new_hex = sha1_to_hex(ref->new_sha1);
packet_write(out, "%s %s %s", old_hex, new_hex, ref->name);
- fprintf(stderr, "'%s': updating from %s to %s\n", ref->name, old_hex, new_hex);
+ fprintf(stderr, "updating '%s'", ref->name);
+ if (strcmp(ref->name, ref->peer_ref->name))
+ fprintf(stderr, " using '%s'", ref->peer_ref->name);
+ fprintf(stderr, "\n from %s\n to %s\n", old_hex, new_hex);
}
-
+
packet_flush(out);
if (new_refs)
- pack_objects(out, ref_list);
+ pack_objects(out, remote_refs);
close(out);
return 0;
}
+
int main(int argc, char **argv)
{
int i, nr_heads = 0;
^ permalink raw reply
* Re: Users of git-check-files?
From: Johannes Schindelin @ 2005-08-03 22:09 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Junio C Hamano, git
In-Reply-To: <Pine.LNX.4.58.0508031055090.3258@g5.osdl.org>
[-- Attachment #1: Type: TEXT/PLAIN, Size: 2354 bytes --]
Hi,
On Wed, 3 Aug 2005, Linus Torvalds wrote:
> On Wed, 3 Aug 2005, Johannes Schindelin wrote:
>>
>> I try to write a "git annotate" based on the output of git-whatchanged.
>
> You can't. It's fundamentally not doable, because you lose the merge
> information.
That's why I said I need git-rev-tree. In the meantime I discovered, that
git-rev-list has a "--parents" option which suits me just fine. Therefore
I'd say: kill git-rev-tree.
> So you need to use a combination of git-rev-list _and_ git-whatchanged.
I tried to do without the ugly "script is calling script is calling
program" idiom. That is why my attempt at git-annotate (see attached) is
so slow.
> I have been thinking of adding a "follow this file" mode to git-rev-list,
> which just ignores all children of merges that used the file directly from
> one of the other children. Exactly because then you could have a
> git-rev-list that prunes based on filename, and would potentially be a lot
> more efficient (not follow the "uninteresting" side of a merge).
Let's sit and see if people pick it up at all. If yes, I'd rather rewrite
the whole thing in C eventually (it is in perl now and uses hashes quite
extensively...).
>> P.S.: My only unsolved problem is that git-whatchanged sometimes shows
>> the diffs in the wrong order (clock-skew problem?)
>
> Nope, this is a direct result of two branches modifying the same file in
> parallel. There is no "right" or "wrong" order.
Exactly. But there is a "you probably meant that": the branch in which it
was modified last (not counting merges, of course).
Notes:
- You can either annotate by commit (this is the default), or show
some other informations with the "-f" flag: Try "-f author,commit:8".
- If you don't specify any files, it assumes you mean all files
(Attention: slow).
- You can start at a commit instead of the current state by specifying
"-c other_commit".
- The list of commits is traversed as output by git-rev-list, i.e.
chronologically. Each line is marked with the commit whose parent does not
contain that line.
- I am not at all sure if my handling of merges is sane. The logic is like
this: If the commit is parent to more than one commit (i.e. a merge), then
the touched lines are tentatively marked as changed in that commit, but
are possibly overridden at a later stage.
Ciao,
Dscho
[-- Attachment #2: Type: TEXT/PLAIN, Size: 8032 bytes --]
#!/usr/bin/perl
use Getopt::Std;
sub usage() {
print STDERR 'Usage: ${\basename $0} [-s] [-f format] [-c commit] [files...]
-s only look at first parent in case of a merge
-f format revision format (e.g. "author,commit:8")
-c commit start looking at this commit
';
exit(1);
}
getopts("hsf:c:") or usage();
$opt_h && usage();
$first_parent_only=$opt_s;
sub read_file ($) {
my $file=$_[0];
open IN, $file || return 1;
$orig_line_count=0;
@lines=();
@line_handled=();
@revisions=();
while(<IN>) {
$orig_line_count++;
$lines[$orig_line_count]=$_;
}
close IN;
$orig_line_count>0 || return 2;
@mapping[1..$orig_line_count]=(1..$orig_line_count);
return 0;
}
sub init_file($$) {
my $file=$_[0];
my $head=$_[1];
if($head eq "") {
# read current file
my $ret=read_file("<".$file);
$ret==0 || return $ret;
$current_revision="*"x($revision_string_length-1).";";
handle_diff("git-diff-files -p ".$file."|",1);
} else {
if(`git-ls-tree $head $file`=~/^\S+\s+\S+\s+(\S+)/) {
$sha1=$1;
my $ret=read_file("git-cat-file blob ".$sha1."|");
$ret==0 || return $ret;
} else {
usage();
}
}
$file_version=0;
return 0;
}
# mark all lines still unaccounted for
sub mark_all ($) {
my $mark_lines_as_handled=$_[0];
foreach $line (@mapping) {
if($line_handled{$line}==undef) {
$revisions[$line]=get_revision();
if($mark_lines_as_handled) {
$line_handled{$line}=1;
}
}
}
if($mark_lines_as_handled) {
$orig_line_count=0;
@mapping=();
}
}
# this sub only handles unified diffs
sub handle_diff($$) {
my $diff=$_[0];
my $mark_lines_as_handled=$_[1];
open DIFF, $diff;
my @new_mapping=();
my $current_line_nr_minus=1;
my $current_line_nr_plus=1;
while(<DIFF>) {
if(/^@@ -(\d+),(\d+) \+(\d+),(\d+) @@/) {
$empty_diff=0;
$start_minus=$1;
$count_minus=$2;
$start_plus=$3;
$count_plus=$4;
# if file was created here, were finished
if($start_minus==0) {
mark_all($mark_lines_as_handled);
return;
}
# sane check
$start_minus-$current_line_nr_minus==$start_plus-$current_line_nr_plus
|| die "invalid diff: $start_minus,$current_line_nr_minus,$start_plus,$current_line_nr_plus";
if($start_minus-$current_line_nr_minus>0) {
@new_mapping[$current_line_nr_minus..$start_minus]
=@mapping[$current_line_nr_plus..$start_plus];
$current_line_nr_minus=$start_minus;
$current_line_nr_plus=$start_plus;
}
while($count_minus>0 || $count_plus>0) {
$_=<DIFF>;
if(/^-/) {
$new_mapping[$current_line_nr_minus]=undef;
$current_line_nr_minus++;
$count_minus--;
} else {
if(/^\+/) {
$orig=$mapping[$current_line_nr_plus];
if($orig>0 && $line_handled[$orig]==undef) {
$revisions[$orig]=get_revision();
if($mark_lines_as_handled) {
$line_handled[$orig]=1;
$orig_line_count--;
if($orig_line_count==0) {
@mapping=@new_mapping;
return;
}
}
}
$current_line_nr_plus++;
$count_plus--;
} else {
$orig_line_nr=$mapping[$current_line_nr_plus];
$new_mapping[$current_line_nr_minus]=$orig_line_nr;
if($orig_line_nr>0) {
# sane check
if(substr($_,1) ne $lines[$orig_line_nr]) {
print "--\n";
print @lines[($orig_line_nr-3)..($orig_line_nr+3)];
print "--\n";
die "invalid diff ($orig_line_nr:$current_line_nr_plus): ".substr($_,1)." is not ".$lines[$orig_line_nr];
}
substr($_,1) eq $lines[$orig_line_nr] ||
die "invalid diff ($diff): ".substr($_,1)." is not ".$lines[$orig_line_nr].$lines[1..$#lines];
}
$current_line_nr_minus++;
$current_line_nr_plus++;
$count_minus--;
$count_plus--;
}
}
}
}
}
close DIFF;
$rest_lines=$#mapping-$current_line_nr_plus;
if($rest_lines>0) {
@new_mapping[$current_line_nr_minus..($current_line_nr_minus+$rest_lines)]
=@mapping[$current_line_nr_plus..($current_line_nr_plus+$rest_lines)];
}
$file_version++;
@mapping=@new_mapping;
return;
}
sub get_revision() {
if($current_revision eq "") {
%commit_values=('fileversion','V-'.$file_version);
$commit_values{'commit'}=$current_commit;
open COMMIT, "git-cat-file commit $current_commit|";
while(($_=<COMMIT>) && !/^$/) {
if(/^parent ([0-9a-f]{40})/) {
$commit_values{'parents'}.=$1." ";
} elsif(/^author (.*)/) {
$commit_values{'author'}=$1;
} elsif(/^committer (.*)/) {
$commit_values{'committer'}=$1;
}
}
close COMMIT;
for($i=0;$i<$#revision_format;$i+=2) {
my $temp=$commit_values{$revision_format[$i]};
my $length=length($temp);
if($length>$revision_format[$i+1]) {
$temp=substr($temp,0,$revision_format[$i+1]);
} elsif($length<$revision_format[$i+1]) {
$temp.=" "x($revision_format[$i+1]-$length);
}
$current_revision.=$temp.";";
}
}
return $current_revision;
}
sub show_current {
for($i=1;$i<=$#lines;$i++) {
print $revisions[$i].$lines[$i];
}
}
sub annotate_file($$) {
my $file=$_[0];
my $head=$_[1];
init_file($file,$head);
my @new_mapping=@mapping;
%commit_mappings=($commits[0]=>\@new_mapping);
my $index;
for($index=0;$index<$#commits;$index++) {
$current_commit=$commits[$index];
$current_revision="";
if($orig_line_count==0 || $children_count{$current_commit}==0) {
mark_all(1);
show_current();
return;
} else {
$next_commit=$commits[$index+1];
if($parent_tree{$next_commit} ne $current_commit) {
# current_commit has children, so save the line mapping
my @new_mapping=@mapping; # force copy
$commit_mappings{$current_commit}=\@new_mapping;
# get current_commit (which is the parent of next_commit)
$current_commit=$parent_tree{$next_commit};
if($commit_mappings{$current_commit}==undef) {
die "fatal";
}
@mapping=@{$commit_mappings{$current_commit}};
# free memory
if($children_count{$current_commit}==1) {
$commit_mappings{$current_commit}=undef;
}
}
handle_diff("git-diff-tree -p $next_commit $current_commit $file|",$children_count{$current_commit}==1);
# if there are multiple children, save the line mapping
if($children_count{$next_commit}>1) {
my @new_mapping=@mapping; # force copy
$commit_mappings{$next_commit}=\@new_mapping;
}
}
}
show_current();
}
sub parse_revision_format($) {
my $format=$_[0];
$revision_string_length=0;
@revision_format=();
foreach $f (split(",",$format)) {
if($f=~/^(.*):(.*)/) {
push @revision_format,($1,$2);
} else {
push @revision_format,($f,16);
}
$revision_string_length+=$revision_format[$#revision_format]+1;
}
if($#revision_format<1) {
push @revision_format,("commit",40);
$revision_string_length=$revision_format[$#revision_format]+1;
}
}
sub get_parent_tree($) {
my $head=$_[0];
my $i;
%parent_tree=();
%children_count=();
@commits=();
$next_commit="";
open REVS, "git-rev-list --parents ".($head eq ""?"HEAD":$head)."|";
LOOP: while(<REVS>) {
if($first_parent_only && $next_commit ne "") {
while(!/^$next_commit/) {
if(!($_=<REVS>)) {
last LOOP;
}
}
}
my @list=split /[ \n]/;
push @commits, $list[0];
for($i=1;$i<=$#list;$i++) {
$parent_tree{$list[$i]}=$list[0];
}
$children_count{$list[0]}=$#list;
if($first_parent_only) {
$next_commit=$list[1];
}
}
close REVS;
}
get_parent_tree($opt_c);
parse_revision_format($opt_f);
if($#ARGV<0) {
open FILES, 'git-ls-tree -r '.($opt_c eq ''?'HEAD':$opt_c).'|';
while(<FILES>) {
if(/^\S+\s+\S+\s+\S+\s+(.*)$/) {
push @ARGV, $1;
}
}
close FILES;
}
for($i=0;$i<=$#ARGV;$i++) {
if($#ARGV>1) {
print "File: ".$ARGV[$i]."\n";
}
annotate_file($ARGV[$i],$opt_c);
}
^ permalink raw reply
* Re: Very limited pathspec wildcards..
From: Linus Torvalds @ 2005-08-03 19:38 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7voe8ec08j.fsf@assigned-by-dhcp.cox.net>
On Wed, 3 Aug 2005, Junio C Hamano wrote:
>
> Wouldn't something like this work equally well?
Nope, for several reasons:
- it's _horribly_ inefficient (ie it traverses directories that it
doesn't need to)
- it shows all the changeset comments, regardless of whether they are
releant or not. It just removes the diffs.
Try it out.
Junio, name-based filters _have_ to be done early. This is why
"diffcore-pathspec" isn't used any more - it's _much_ too inefficient to
do it later.
Linus
^ permalink raw reply
* Re: [PATCH] GIT_SSH alternate ssh name or helper
From: Junio C Hamano @ 2005-08-03 19:29 UTC (permalink / raw)
To: Martin Sivak; +Cc: git
In-Reply-To: <20050803185621.GA20645@medusa>
Martin Sivak <mars@nomi.cz> writes:
> I mean, how would you setup different identities for more user
> accounts on the same server (it doesn't happen often, but..)?
I do not claim the way I do is the best way, but I do that all
the time.
I just use different "name" to connect, by setting up the ssh
client configuration file to give me the protocol parameters I
want depending on the name I use. The wildcard support handles
permutations quite nicely. Something like this:
$ cat .ssh/config
Host *-1-*
Protocol 1
Host *-2-*
Protocol 2
Host lucia-*
Hostname lucia.example.xz
Host myriam-*
Hostname myriam.example.xz
Host *-junio
IdentityFile ~/.ssh/identity-junio
IdentityFile ~/.ssh/id_dsa-junio
Host *-junkio
IdentityFile ~/.ssh/identity-junkio
IdentityFile ~/.ssh/id_dsa-junkio
$ ssh lucia-2-junio ;# go to lucia over protocol 2, use id_dsa-junio
$ ssh myriam-1-junkio ;# to myriam over protocol 1, use identity-junkio
^ permalink raw reply
* Re: Very limited pathspec wildcards..
From: Junio C Hamano @ 2005-08-03 19:02 UTC (permalink / raw)
To: Linus Torvalds; +Cc: git
In-Reply-To: <Pine.LNX.4.58.0508031038320.3258@g5.osdl.org>
Linus Torvalds <torvalds@osdl.org> writes:
> Btw, I'm not sure this is a wonderful idea. I found it useful for doing
>
> git-whatchanged -p drivers/scsi/aic7xxx/aic79xx*
>
> since I was interested in seeign if only that particular driver had had
> changes. But it's hacky and pretty limited, so I throw this patch out more
> as a "maybe others think it is a good idea" thing.
Wouldn't something like this work equally well?
#!/bin/sh
git-whatchanged -r |
sed -ne '
/^:/s|aic7xxx/aic79xx|&|p
/^:/d
p' | git-diff-helper
^ permalink raw reply
* Re: [PATCH] GIT_SSH alternate ssh name or helper
From: Martin Sivak @ 2005-08-03 18:56 UTC (permalink / raw)
To: git
In-Reply-To: <7viryndjvu.fsf@assigned-by-dhcp.cox.net>
[-- Attachment #1: Type: text/plain, Size: 852 bytes --]
> I understand why you would want this if your ssh binary is
> called something other than ssh [*1*], but I doubt the example
> you gave needs this patch. Could you explain why having
> something like this in your .ssh/config file is not enough?
>
> Host foo.bar.xz
> Protocol 1
> IdentityFile ~/.ssh/privatekey.key
The example was of course about the simpliest thing i thought of.
I would find that variable (GIT_SSH) usefull, and actually it does no
harm, because you already have GIT_SSH_PULL & PUSH variables, for the
same purpose (to define different name).
Actually I think there is at least one case, when helper script is useful.
I mean, how would you setup different identities for more user accounts on the
same server (it doesn't happen often, but..)?
Best regards
--
Martin Sivak
mars@nomi.cz
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* Re: Users of git-check-files?
From: Josef Weidendorfer @ 2005-08-03 18:31 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7vy87ic2sd.fsf@assigned-by-dhcp.cox.net>
On Wednesday 03 August 2005 20:07, Junio C Hamano wrote:
> Josef, could you give it a try please?
Perfect. Thanks.
Josef
^ permalink raw reply
* Re: Users of git-check-files?
From: Linus Torvalds @ 2005-08-03 18:10 UTC (permalink / raw)
To: Josef Weidendorfer; +Cc: git
In-Reply-To: <200508031946.01017.Josef.Weidendorfer@gmx.de>
On Wed, 3 Aug 2005, Josef Weidendorfer wrote:
>
> But my example shows that the error happens even with 2 branches totally
> unrelated to each other: if branch1 got a new commit, you can not push to
> branch2 from another clone.
Sure you can.
git-send-pack remote branch2
and you've just done so.
The shorthand of "no branches listed" expands to _all_ branches, and if
you try to send all branches, then you're trying to update "branch1" with
something you don't have. That's your usage error.
Linus
^ permalink raw reply
* Re: Users of git-check-files?
From: Linus Torvalds @ 2005-08-03 18:08 UTC (permalink / raw)
To: Josef Weidendorfer; +Cc: git
In-Reply-To: <200508031908.22562.Josef.Weidendorfer@gmx.de>
On Wed, 3 Aug 2005, Josef Weidendorfer wrote:
>
> Yes it is. To reproduce:
> Create a repository with 2 branches.
> Make 2 clones of the 2 branches via SSH.
> Make a commit on one clone and push.
> Make another commit on the other clone and push => ERROR
This works perfectly fine, you just have to make sure that you update the
right head.
If you try to update a head that is ahead of you, that is driver error.
Admittedly one that could have nicer error messages ;)
This is why git-send-pack takes the name of the branch to update..
The real problem with git-send-pack is that the local and remote names
have to be the same, which is a bug, really. It _should_ be perfectly fine
to do something like
git-send-pack ..dest.. localname:remotename
which would push the local "localname" branch to the remote "remotename"
branch.
Linus
^ permalink raw reply
* Re: Users of git-check-files?
From: Junio C Hamano @ 2005-08-03 18:07 UTC (permalink / raw)
To: git; +Cc: Linus Torvalds, Josef Weidendorfer
In-Reply-To: <Pine.LNX.4.58.0508031048360.3258@g5.osdl.org>
This patch seems to fix the problem.
* If the original value of remote ref refers to an object we do
not have, and if the ref is one of the branches we are trying
to push, we refuse to update it.
* Otherwise, we do not attempt to use such an value when
computing what objects to put in pack, since rev-list would
fail.
I've tested Josef's two-branches case, one repo updates one
branch and pushes to the central repo, another repo updates the
other branch and pushed to the central repo. The old code
barfed when invoking rev-list, but this does not seem to.
Josef, could you give it a try please?
---
cd /opt/packrat/playpen/public/in-place/git/git.junio/
jit-diff
# - master: git-send-email-script: minimum whitespace cleanup.
# + (working tree)
diff --git a/send-pack.c b/send-pack.c
--- a/send-pack.c
+++ b/send-pack.c
@@ -43,7 +43,8 @@ static void exec_rev_list(struct ref *re
char *buf = malloc(100);
if (i > 900)
die("git-rev-list environment overflow");
- if (!is_zero_sha1(refs->old_sha1)) {
+ if (!is_zero_sha1(refs->old_sha1) &&
+ has_sha1_file(refs->old_sha1)) {
args[i++] = buf;
snprintf(buf, 50, "^%s", sha1_to_hex(refs->old_sha1));
buf += 50;
@@ -208,6 +209,12 @@ static int send_pack(int in, int out, in
continue;
}
+ if (!has_sha1_file(ref->old_sha1)) {
+ error("remote '%s' object %s does not exist on local",
+ name, sha1_to_hex(ref->old_sha1));
+ continue;
+ }
+
/* Ok, mark it for update */
memcpy(ref->new_sha1, new_sha1, 20);
}
Compilation finished at Wed Aug 3 11:02:15
^ permalink raw reply
* Re: Users of git-check-files?
From: Linus Torvalds @ 2005-08-03 18:02 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: Junio C Hamano, git
In-Reply-To: <Pine.LNX.4.63.0508031849270.24318@wgmdd8.biozentrum.uni-wuerzburg.de>
On Wed, 3 Aug 2005, Johannes Schindelin wrote:
>
> On Wed, 3 Aug 2005, Linus Torvalds wrote:
>
> > Are you sure you have a good git version on master? I've never seen
> > anything like that, and I push all the time..
>
> Call him Zaphod: he has two heads (master and pu). You don't.
Oh, but I most definitely do. I update several heads at a time when I
create a new tag etc.
What I don't do is to rewrite my history, though..
Linus
^ permalink raw reply
* Re: Users of git-check-files?
From: Linus Torvalds @ 2005-08-03 18:00 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: Junio C Hamano, git
In-Reply-To: <Pine.LNX.4.63.0508031618500.23728@wgmdd8.biozentrum.uni-wuerzburg.de>
On Wed, 3 Aug 2005, Johannes Schindelin wrote:
>
> I try to write a "git annotate" based on the output of git-whatchanged.
You can't. It's fundamentally not doable, because you lose the merge
information.
So you need to use a combination of git-rev-list _and_ git-whatchanged.
Use the "--parents" flag to git-rev-list to get the parents output for
doing your own graph, if you want to.
I have been thinking of adding a "follow this file" mode to git-rev-list,
which just ignores all children of merges that used the file directly from
one of the other children. Exactly because then you could have a
git-rev-list that prunes based on filename, and would potentially be a lot
more efficient (not follow the "uninteresting" side of a merge).
I haven't gotten around to it, partly because I wonder if it would be
better as a separate program - even if that would mean that you'd lose all
the cool features of git-rev-list (the ability to limit it to certain
versions, and the ability to sort the output in relevant orders).
Partly because I'm just too friggin lazy.
> P.S.: My only unsolved problem is that git-whatchanged sometimes shows
> the diffs in the wrong order (clock-skew problem?)
Nope, this is a direct result of two branches modifying the same file in
parallel. There is no "right" or "wrong" order.
Linus
^ permalink raw reply
* Re: Users of git-check-files?
From: Linus Torvalds @ 2005-08-03 17:48 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7virymdirb.fsf@assigned-by-dhcp.cox.net>
On Wed, 3 Aug 2005, Junio C Hamano wrote:
>
> I think in addition to the existing ref_newer() check, which
> makes sure you are advancing the remote head, not just replacing
> with something unrelated, making sure that we have objects
> referenced by ref->old_sha1 we obtained from the remote on our
> end for all branches involved would be the only thing needed.
Yes.
Linus
^ permalink raw reply
* Very limited pathspec wildcards..
From: Linus Torvalds @ 2005-08-03 17:48 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Git Mailing List
I ended up looking at wildcards in pathspecs, but wasn't quite ready
enough to pay the price of real wildcards. This limited form is the end
result.
It allows a final '*' in the path matching to indicate that we don't care
about the "match exact files/subdirectories only" rule.
So while
git-whatchanged git
will only show the file called "git" (or any changes under a subdirectory
called "git"),
git-whatchanged git*
will show anything that starts with "git".
Note that this _only_ works at the very end. You can't say
git-whatchanged git-*-script
even though maybe it would be good if we allowed full wildcards some day.
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
---
Btw, I'm not sure this is a wonderful idea. I found it useful for doing
git-whatchanged -p drivers/scsi/aic7xxx/aic79xx*
since I was interested in seeign if only that particular driver had had
changes. But it's hacky and pretty limited, so I throw this patch out more
as a "maybe others think it is a good idea" thing.
So Junio, if you feel this is ugly, just drop it, I certainly won't mind.
As it is you can't even escape the '*', so if you actually only want to
match a filename that literally ends in an asterisk, this makes that
impossible, and will match that file _and_ anything that shares the same
prefix..
diff --git a/diff-tree.c b/diff-tree.c
--- a/diff-tree.c
+++ b/diff-tree.c
@@ -163,6 +163,12 @@ static int interesting(void *tree, unsig
for (i=0; i < nr_paths; i++) {
const char *match = paths[i];
int matchlen = pathlens[i];
+ int wildcard = 0;
+
+ if (matchlen && match[matchlen-1] == '*') {
+ matchlen--;
+ wildcard = 1;
+ }
if (baselen >= matchlen) {
/* If it doesn't match, move along... */
@@ -183,7 +189,7 @@ static int interesting(void *tree, unsig
if (pathlen > matchlen)
continue;
- if (matchlen > pathlen) {
+ if (!wildcard && matchlen > pathlen) {
if (match[pathlen] != '/')
continue;
if (!S_ISDIR(mode))
diff --git a/read-cache.c b/read-cache.c
--- a/read-cache.c
+++ b/read-cache.c
@@ -183,10 +183,17 @@ int ce_path_match(const struct cache_ent
name = ce->name;
while ((match = *pathspec++) != NULL) {
int matchlen = strlen(match);
+ int wildcard = 0;
+ if (matchlen && match[matchlen-1]) {
+ matchlen--;
+ wildcard = 1;
+ }
if (matchlen > len)
continue;
if (memcmp(name, match, matchlen))
continue;
+ if (wildcard)
+ return 1;
if (matchlen && name[matchlen-1] == '/')
return 1;
if (name[matchlen] == '/' || !name[matchlen])
^ permalink raw reply
* Re: Users of git-check-files?
From: Josef Weidendorfer @ 2005-08-03 17:46 UTC (permalink / raw)
To: git
In-Reply-To: <200508031908.22562.Josef.Weidendorfer@gmx.de>
On Wednesday 03 August 2005 19:08, you wrote:
> Yes it is. To reproduce:
You do not need 2 clones.
It is enough to have one clone with a branch, and you make a commit in the
original repository.
Afterwards, pushing a new commit from the clone gives the error.
After pulling the missing commit from the original rep, the push works.
Josef
^ permalink raw reply
* Re: Users of git-check-files?
From: Josef Weidendorfer @ 2005-08-03 17:46 UTC (permalink / raw)
To: git
In-Reply-To: <7virymdirb.fsf@assigned-by-dhcp.cox.net>
On Wednesday 03 August 2005 19:37, you wrote:
> Linus Torvalds <torvalds@osdl.org> writes:
> > I started out to make the "-f" flag to send-file work around it, but I
> > never finished that, partly because it really ends up being the same
> > thing as "git-fetch-pack" in reverse, which was against the whole point
> > of git-send-pack. Send-pack is meant to be an "update remote tree" thing,
> > with the assumption that the remote tree is a subset - and exactly that
> > assumption is what makes send-pack much cheaper than fetch-pack.
>
> I think in addition to the existing ref_newer() check, which
> makes sure you are advancing the remote head, not just replacing
> with something unrelated, making sure that we have objects
> referenced by ref->old_sha1 we obtained from the remote on our
> end for all branches involved would be the only thing needed.
> The latter the users should not even be able to override with
> the --force flag, of course, but we would remind them to pull
> from the other end first.
But my example shows that the error happens even with 2 branches totally
unrelated to each other: if branch1 got a new commit, you can not push to
branch2 from another clone.
Why is it not enough to have all the history of a remote branch in the local
clone to be able to push to this branch?
Josef
^ permalink raw reply
* Re: Users of git-check-files?
From: Junio C Hamano @ 2005-08-03 17:37 UTC (permalink / raw)
To: Linus Torvalds; +Cc: git
In-Reply-To: <Pine.LNX.4.58.0508031014070.3258@g5.osdl.org>
Linus Torvalds <torvalds@osdl.org> writes:
> I started out to make the "-f" flag to send-file work around it, but I
> never finished that, partly because it really ends up being the same thing
> as "git-fetch-pack" in reverse, which was against the whole point of
> git-send-pack. Send-pack is meant to be an "update remote tree" thing,
> with the assumption that the remote tree is a subset - and exactly that
> assumption is what makes send-pack much cheaper than fetch-pack.
I think in addition to the existing ref_newer() check, which
makes sure you are advancing the remote head, not just replacing
with something unrelated, making sure that we have objects
referenced by ref->old_sha1 we obtained from the remote on our
end for all branches involved would be the only thing needed.
The latter the users should not even be able to override with
the --force flag, of course, but we would remind them to pull
from the other end first.
^ permalink raw reply
* Re: Users of git-check-files?
From: Junio C Hamano @ 2005-08-03 17:30 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Josef Weidendorfer, git
In-Reply-To: <200508031908.22562.Josef.Weidendorfer@gmx.de>
Josef Weidendorfer <Josef.Weidendorfer@gmx.de> writes:
> ~/tmp/git/clone2> cg-push
> 'refs/heads/branch2': updating from 80e4d426dd4c865b943cc1121b580a946eee921d
> to 8196067677e3415ce404ea5bc35731ac7d56115d
> fatal: bad object f7e944b036fd00af656b262140c1dc93ceffadb1
> Packing 0 objects
> Unpacking 0 objects
Ahhhh.
Yes, we read from the remote and use old->sha1 when doing the
pack generation. If we do not have that object (in Josef's
example because it is not something we have pulled yet), then
rev-list has no way to create the necessary pack.
I have a feeling this explains what I've been seeing as well.
The first thing I do before I push is to fetch (but not
merge-pull) from kernel.org, but this happens against
www.kernel.org (to make sure people are seeing what I want them
to see), not against master. So if I happen to do my push cycle
twice before the things propagate from master to www.kernel.org,
_and_ if I happened to have run git prune in my private
repository just before the second cycle, I may end up not having
the objects referenced by "pu" branch there in my private
repository.
^ permalink raw reply
* Re: Users of git-check-files?
From: Linus Torvalds @ 2005-08-03 17:23 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7voe8fdkd7.fsf@assigned-by-dhcp.cox.net>
On Wed, 3 Aug 2005, Junio C Hamano wrote:
>
> Linus Torvalds <torvalds@osdl.org> writes:
>
> > Are you sure you have a good git version on master? I've never seen
> > anything like that, and I push all the time..
>
> I have been esuspecting that it happens only because I rewind
> and rebase "pu", which you never do. The thing is, even though
> I rewind "pu" all the time, it happens only occasionally.
Oh, that would do it.
You need to prune back the remote tree you send to, so that it is a real
subset of what you are sending from (at least as far as the branch you
send is concerned - other branches may be ahead of you, of course). Unlike
"git-fetch-pack", the send-pack interface does not do any common commit
discovery, so if you have state on the other end that isn't on your local
end, that's setting yourself up for problems: you are basically misusing
the interfaces.
I started out to make the "-f" flag to send-file work around it, but I
never finished that, partly because it really ends up being the same thing
as "git-fetch-pack" in reverse, which was against the whole point of
git-send-pack. Send-pack is meant to be an "update remote tree" thing,
with the assumption that the remote tree is a subset - and exactly that
assumption is what makes send-pack much cheaper than fetch-pack.
(Actually, to me it's not the "cheaper" that matters, but exactly the fact
that send-pack is so safe - if somebody has changed something at the other
end that I don't have in mine, I _want_ errors, because that would be a
serious problem).
Linus
^ permalink raw reply
* Re: [PATCH] GIT_SSH alternate ssh name or helper
From: Junio C Hamano @ 2005-08-03 17:12 UTC (permalink / raw)
To: Martin Sivak; +Cc: git
In-Reply-To: <20050803151542.GA6655@medusa>
Martin Sivak <mars@nomi.cz> writes:
> This patch make possible to use alternate ssh binary or ssh helper
> script. The script can be used to give additional parameters to ssh
> binary (like private key, protocol version, ...).
>
> Example script could look like this:
>
> #!/bin/sh
> ssh -1 -i myprivatekey.key "$@"
>
> The patch itself is realy very simple:
I understand why you would want this if your ssh binary is
called something other than ssh [*1*], but I doubt the example
you gave needs this patch. Could you explain why having
something like this in your .ssh/config file is not enough?
Host foo.bar.xz
Protocol 1
IdentityFile ~/.ssh/privatekey.key
Even if you wish to use different settings between git and
interactive, I presume you could do something like this:
# for interactive
Host foo.bar.xz
Protocol 2
# real repo is foo.bar.xz:/pub/scm/git/git.git/ but pull with
# git-foo.bar.xz:/pub/scm/git/git.git/
Host git-foo.bar.xz
Hostname foo.bar.xz
Protocol 1
IdentityFile ~/.ssh/privatekey.key
[Footnote]
*1* and even in that case you can trivially fix it by having
a small wrapper in $HOME/bin/ssh:
#!/bin/sh
exec ssh-installed-under-nonstandard-name "$@"
^ permalink raw reply
* Re: Users of git-check-files?
From: Josef Weidendorfer @ 2005-08-03 17:08 UTC (permalink / raw)
To: git
In-Reply-To: <Pine.LNX.4.63.0508031849270.24318@wgmdd8.biozentrum.uni-wuerzburg.de>
On Wednesday 03 August 2005 18:50, you wrote:
> Hi,
>
> On Wed, 3 Aug 2005, Linus Torvalds wrote:
> > Are you sure you have a good git version on master? I've never seen
> > anything like that, and I push all the time..
>
> Call him Zaphod: he has two heads (master and pu). You don't. As I said in
> another mail, this could be very well related to Junio's problems.
Yes it is. To reproduce:
Create a repository with 2 branches.
Make 2 clones of the 2 branches via SSH.
Make a commit on one clone and push.
Make another commit on the other clone and push => ERROR
A log of this last push:
=============================================
~/tmp/git/clone2> cg-push
'refs/heads/branch2': updating from 80e4d426dd4c865b943cc1121b580a946eee921d
to 8196067677e3415ce404ea5bc35731ac7d56115d
fatal: bad object f7e944b036fd00af656b262140c1dc93ceffadb1
Packing 0 objects
Unpacking 0 objects
fatal: unpack should have generated 8196067677e3415ce404ea5bc35731ac7d56115d,
but I can't find it!
=============================================
f7e9... is the commit pushed from the first clone.
I had the same problem yesterday.
Josef
^ permalink raw reply
* git-local-pull?
From: barkalow @ 2005-08-03 17:11 UTC (permalink / raw)
To: git
IIRC, git-local-pull still doesn't work for a packed source repository,
because it doesn't include the possibility of copying a pack (or
extracting an object) if the requested object is in a pack.
I can probably fix it if anyone cares, but it's not something I use
personally, so I don't know if it's worthwhile. It should probably be
removed if we don't fix it, since it will fail on any popular repository
at this point.
-Daniel
*This .sig left intentionally blank*
^ permalink raw reply
* Re: Users of git-check-files?
From: Junio C Hamano @ 2005-08-03 17:02 UTC (permalink / raw)
To: Linus Torvalds; +Cc: git
In-Reply-To: <Pine.LNX.4.58.0508030944210.3258@g5.osdl.org>
Linus Torvalds <torvalds@osdl.org> writes:
> Are you sure you have a good git version on master? I've never seen
> anything like that, and I push all the time..
I have been esuspecting that it happens only because I rewind
and rebase "pu", which you never do. The thing is, even though
I rewind "pu" all the time, it happens only occasionally.
^ permalink raw reply
* Re: Users of git-check-files?
From: Johannes Schindelin @ 2005-08-03 16:50 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Junio C Hamano, git
In-Reply-To: <Pine.LNX.4.58.0508030944210.3258@g5.osdl.org>
Hi,
On Wed, 3 Aug 2005, Linus Torvalds wrote:
> Are you sure you have a good git version on master? I've never seen
> anything like that, and I push all the time..
Call him Zaphod: he has two heads (master and pu). You don't. As I said in
another mail, this could be very well related to Junio's problems.
Ciao,
Dscho
^ 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