* Re: Solaris cloning woes partly diagnosed
From: Linus Torvalds @ 2006-04-02 19:22 UTC (permalink / raw)
To: Jason Riedy; +Cc: git
In-Reply-To: <29336.1144005022@lotus.CS.Berkeley.EDU>
On Sun, 2 Apr 2006, Jason Riedy wrote:
> And Linus Torvalds writes:
> -
> - I'd be willing to bet that it's the fact that we take signals.
>
> Unfortunately, I'm too busy to check into this, but I've
> run into similar problems in the past. Just takes a busy
> file server.
>
> - We do, for example, expect that regular file writing not do that. At least
> - "write_sha1_from_fd()" will just do a "write()" without testing the error
> - return, [...]
>
> There is an xwrite in git-compat-util.h...
Well, git itself is actually fairly good about these things. Right now I'm
seriously suspecting Solaris stdio as being just horribly impolite.
git tends to not just use xwrite() in most places, but check the return
value for partial sizes etc. I tried to grep for places where we were
lazy, and there really seems to be just a very small handful, and they
shouldn't impact this case at all (you have to have a seriously broken
setup for them to matter, but we should fix them nonetheless.
Linus
^ permalink raw reply
* Re: parsecvs tool now creates git repositories
From: Jan-Benedict Glaw @ 2006-04-02 19:31 UTC (permalink / raw)
To: Keith Packard; +Cc: Git Mailing List
In-Reply-To: <20060402093906.GH1259@lug-owl.de>
[-- Attachment #1: Type: text/plain, Size: 2751 bytes --]
On Sun, 2006-04-02 11:39:06 +0200, Jan-Benedict Glaw <jbglaw@lug-owl.de> wrote:
> On Sat, 2006-04-01 21:36:28 -0800, Keith Packard <keithp@keithp.com> wrote:
> > The UI is a total disaster, sufficient for testing. You must create an
> > Authors file in the current directory which looks like the git-cvsimport
> > authors file. You must also have a edit-change-log program in your path
> > which edits the commit message in place. /bin/true will work if you
> > don't need to edit the messages.
>
> Well, at least this sounds quite promising. I'll give it a run once
> I've arrived back home on the Binutils repository.
Doesn't build for me:
jbglaw@bixie:~/vax/gittish/parsecvs$ make clean
rm -f gram.o lex.o parsecvs.o cvsutil.o revlist.o atom.o revcvs.o git.o y.tab.h gram.c parsecvs
jbglaw@bixie:~/vax/gittish/parsecvs$ make
yacc -d gram.y
mv -f y.tab.c gram.c
cc -O0 -g -Wall -Wpointer-arith -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wnested-externs -fno-strict-aliasing -c -o gram.o gram.c
cc -O0 -g -Wall -Wpointer-arith -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wnested-externs -fno-strict-aliasing -c -o lex.o lex.c
lex.l: In function ‘yylex’:
lex.l:69: warning: implicit declaration of function ‘yyget_lineno’
lex.l:69: warning: nested extern declaration of ‘yyget_lineno’
<stdout>: At top level:
<stdout>:1747: warning: no previous prototype for ‘yyget_lineno’
<stdout>:1756: warning: no previous prototype for ‘yyget_in’
<stdout>:1764: warning: no previous prototype for ‘yyget_out’
<stdout>:1772: warning: no previous prototype for ‘yyget_leng’
<stdout>:1781: warning: no previous prototype for ‘yyget_text’
<stdout>:1790: warning: no previous prototype for ‘yyset_lineno’
<stdout>:1802: warning: no previous prototype for ‘yyset_in’
<stdout>:1807: warning: no previous prototype for ‘yyset_out’
<stdout>:1812: warning: no previous prototype for ‘yyget_debug’
<stdout>:1817: warning: no previous prototype for ‘yyset_debug’
<stdout>:1823: warning: no previous prototype for ‘yylex_destroy’
lex.l: In function ‘parse_data’:
lex.l:90: error: ‘yytext_ptr’ undeclared (first use in this function)
lex.l:90: error: (Each undeclared identifier is reported only once
lex.l:90: error: for each function it appears in.)
make: *** [lex.o] Error 1
MfG, JBG
--
Jan-Benedict Glaw jbglaw@lug-owl.de . +49-172-7608481 _ O _
"Eine Freie Meinung in einem Freien Kopf | Gegen Zensur | Gegen Krieg _ _ O
für einen Freien Staat voll Freier Bürger" | im Internet! | im Irak! O O O
ret = do_actions((curr | FREE_SPEECH) & ~(NEW_COPYRIGHT_LAW | DRM | TCPA));
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* Re: Solaris cloning woes partly diagnosed
From: Jason Riedy @ 2006-04-02 19:52 UTC (permalink / raw)
To: git
In-Reply-To: <Pine.LNX.4.64.0604021159110.3050@g5.osdl.org>
And Linus Torvalds writes:
-
- so it really really looks like fgets() would have problems with a SIGALRM
- coming in and doesn't just re-try on EINTR. Can Solaris stdio _really_ be
- that broken? (Yeah, yeah, it may be "conforming". It's also so incredibly
- programmer-unfriendly that it's not even funny)
Yes, it is that broken. I haven't encountered the problem
consistently in git myself, so I can't tell you if the patch
works. Google finds similar reports and patches for BOINC, ruby,
and a few other projects.
Solaris folks will say you should be using sigaction with
SA_RESTART. IIRC, SA_RESTART isn't guaranteed to be there
or work, but all the systems I deal with right now have it.
So an alternate patch for this one use is appended... Other
uses of signal could be changed to sigaction, too. And
progress_update "should" be sig_atomic_t.
Passes the pack-objects tests, but I can't make the problem
happen on demand. (I have seen it occur before, but never
during make test, and I'd not tracked it down...)
Jason
----
diff --git a/pack-objects.c b/pack-objects.c
index ccfaa5f..1faa0bb 100644
--- a/pack-objects.c
+++ b/pack-objects.c
@@ -877,10 +877,21 @@ static int try_delta(struct unpacked *cu
return 0;
}
-static void progress_interval(int signum)
+static void progress_interval(int);
+
+static void setup_progress_signal(void)
+{
+ struct sigaction sa;
+ sa.sa_handler = progress_interval;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = SA_RESTART;
+ sigaction(SIGALRM, &sa, NULL);
+}
+
+void progress_interval(int signum)
{
- signal(SIGALRM, progress_interval);
progress_update = 1;
+ setup_progress_signal();
}
static void find_deltas(struct object_entry **list, int window, int depth)
@@ -1094,7 +1105,7 @@ int main(int argc, char **argv)
v.it_interval.tv_sec = 1;
v.it_interval.tv_usec = 0;
v.it_value = v.it_interval;
- signal(SIGALRM, progress_interval);
+ setup_progress_signal();
setitimer(ITIMER_REAL, &v, NULL);
fprintf(stderr, "Generating pack...\n");
}
^ permalink raw reply related
* Re: Solaris cloning woes partly diagnosed
From: Linus Torvalds @ 2006-04-02 20:28 UTC (permalink / raw)
To: Jason Riedy; +Cc: git
In-Reply-To: <824.1144007555@lotus.CS.Berkeley.EDU>
On Sun, 2 Apr 2006, Jason Riedy wrote:
>
> Solaris folks will say you should be using sigaction with
> SA_RESTART. IIRC, SA_RESTART isn't guaranteed to be there
> or work, but all the systems I deal with right now have it.
I think we might as well do that _too_.
However, once you use "sigaction()", you don't need to re-arm the signal
handler any more, so I'd suggest a simpler patch like this instead..
Junio, I think this confirms/explains the Solaris breakage.
I'll re-send the "anal stdio semantics" version of the patch on top of
this in the next email.
Linus
----
Subject: Fix Solaris stdio signal handling stupidities
This uses sigaction() to install the SIGALRM handler with SA_RESTART, so
that Solaris stdio doesn't break completely when a signal interrupts a
read.
Thanks to Jason Riedy for confirming the silly Solaris signal behaviour.
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
----
diff --git a/pack-objects.c b/pack-objects.c
index ccfaa5f..1817b58 100644
--- a/pack-objects.c
+++ b/pack-objects.c
@@ -58,7 +58,7 @@ static int nr_objects = 0, nr_alloc = 0,
static const char *base_name;
static unsigned char pack_file_sha1[20];
static int progress = 1;
-static volatile int progress_update = 0;
+static volatile sig_atomic_t progress_update = 0;
/*
* The object names in objects array are hashed with this hashtable,
@@ -879,7 +879,6 @@ static int try_delta(struct unpacked *cu
static void progress_interval(int signum)
{
- signal(SIGALRM, progress_interval);
progress_update = 1;
}
@@ -1025,6 +1024,23 @@ static int reuse_cached_pack(unsigned ch
return 1;
}
+static void setup_progress_signal(void)
+{
+ struct sigaction sa;
+ struct itimerval v;
+
+ memset(&sa, 0, sizeof(sa));
+ sa.sa_handler = progress_interval;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = SA_RESTART;
+ sigaction(SIGALRM, &sa, NULL);
+
+ v.it_interval.tv_sec = 1;
+ v.it_interval.tv_usec = 0;
+ v.it_value = v.it_interval;
+ setitimer(ITIMER_REAL, &v, NULL);
+}
+
int main(int argc, char **argv)
{
SHA_CTX ctx;
@@ -1090,13 +1106,8 @@ int main(int argc, char **argv)
prepare_packed_git();
if (progress) {
- struct itimerval v;
- v.it_interval.tv_sec = 1;
- v.it_interval.tv_usec = 0;
- v.it_value = v.it_interval;
- signal(SIGALRM, progress_interval);
- setitimer(ITIMER_REAL, &v, NULL);
fprintf(stderr, "Generating pack...\n");
+ setup_progress_signal();
}
while (fgets(line, sizeof(line), stdin) != NULL) {
^ permalink raw reply related
* [PATCH 2/2] pack-objects: be incredibly anal about stdio semantics
From: Linus Torvalds @ 2006-04-02 20:31 UTC (permalink / raw)
To: Jason Riedy, Junio C Hamano; +Cc: Git Mailing List
In-Reply-To: <Pine.LNX.4.64.0604021312510.3050@g5.osdl.org>
This is the "letter of the law" version of using fgets() properly in the
face of incredibly broken stdio implementations. We can work around the
Solaris breakage with SA_RESTART, but in case anybody else is ever that
stupid, here's the "safe" (read: "insanely anal") way to use fgets.
It probably goes without saying that I'm not terribly impressed by
Solaris libc.
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
---
This is the same one that I already sent out, but re-diffed, and with a
proper commit message.
Not tested on Solaris.
Junio - I think that I forgot to Cc: you on the 1/2 patch, but you'll see
it on the git list.
diff --git a/pack-objects.c b/pack-objects.c
index 1817b58..0ea16ad 100644
--- a/pack-objects.c
+++ b/pack-objects.c
@@ -1110,8 +1110,18 @@ int main(int argc, char **argv)
setup_progress_signal();
}
- while (fgets(line, sizeof(line), stdin) != NULL) {
+ for (;;) {
unsigned char sha1[20];
+
+ if (!fgets(line, sizeof(line), stdin)) {
+ if (feof(stdin))
+ break;
+ if (!ferror(stdin))
+ die("fgets returned NULL, not EOF, not error!");
+ if (errno == EINTR)
+ continue;
+ die("fgets: %s", strerror(errno));
+ }
if (line[0] == '-') {
if (get_sha1_hex(line+1, sha1))
^ permalink raw reply related
* Re: [RFH] xdiff shows trivially redundant diff.
From: Junio C Hamano @ 2006-04-02 21:02 UTC (permalink / raw)
To: Davide Libenzi; +Cc: git, Linus Torvalds
In-Reply-To: <Pine.LNX.4.64.0604021035130.30097@alien.or.mcafeemobile.com>
[-- Attachment #1: Type: text/plain, Size: 979 bytes --]
Davide Libenzi <davidel@xmailserver.org> writes:
> On Sun, 2 Apr 2006, Junio C Hamano wrote:
>
>> $ git diff-tree -p 52e8a6^2 52d8a6 -- git-fetch.sh
>>
>> shows a change that trivially is redundant, like this:
>>
>> diff --git a/git-fetch.sh b/git-fetch.sh
>> index b4325d9..de4f011 100755
>> --- a/git-fetch.sh
>> +++ b/git-fetch.sh
>> @@ -320,7 +320,7 @@ fetch_main () {
>>..
>> Notice the first '-' and '+' lines of second hunk are identical?
>>
>> There is another interesting thing. This is running diff
>> between 52e8a6^2 and 52d8a6 blobs, but if I change them slightly
>> so that the first hunk is not different, then this anomaly
>> disappears.
>
> Could you send me the two files that creates the above diff?
I should have tried your pristine xdiff code myself before
bothering you, but I haven't (sorry).
The problem is from the "stripped down" version we use in git,
so you may or may not see the problem in your version. Attached
are the files.
[-- Attachment #2: diff test preimage --]
[-- Type: text/plain, Size: 9364 bytes --]
#!/bin/sh
#
USAGE='<fetch-options> <repository> <refspec>...'
. git-sh-setup
. git-parse-remote
_x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'
_x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40"
LF='
'
IFS="$LF"
no_tags=
tags=
append=
force=
verbose=
update_head_ok=
exec=
upload_pack=
while case "$#" in 0) break ;; esac
do
case "$1" in
-a|--a|--ap|--app|--appe|--appen|--append)
append=t
;;
--upl|--uplo|--uploa|--upload|--upload-|--upload-p|\
--upload-pa|--upload-pac|--upload-pack)
shift
exec="--exec=$1"
upload_pack="-u $1"
;;
-f|--f|--fo|--for|--forc|--force)
force=t
;;
-t|--t|--ta|--tag|--tags)
tags=t
;;
-n|--n|--no|--no-|--no-t|--no-ta|--no-tag|--no-tags)
no_tags=t
;;
-u|--u|--up|--upd|--upda|--updat|--update|--update-|--update-h|\
--update-he|--update-hea|--update-head|--update-head-|\
--update-head-o|--update-head-ok)
update_head_ok=t
;;
-v|--verbose)
verbose=Yes
;;
-k|--k|--ke|--kee|--keep)
keep=--keep
;;
-*)
usage
;;
*)
break
;;
esac
shift
done
case "$#" in
0)
test -f "$GIT_DIR/branches/origin" ||
test -f "$GIT_DIR/remotes/origin" ||
die "Where do you want to fetch from today?"
set origin ;;
esac
remote_nick="$1"
remote=$(get_remote_url "$@")
refs=
rref=
rsync_slurped_objects=
if test "" = "$append"
then
: >"$GIT_DIR/FETCH_HEAD"
fi
append_fetch_head () {
head_="$1"
remote_="$2"
remote_name_="$3"
remote_nick_="$4"
local_name_="$5"
case "$6" in
t) not_for_merge_='not-for-merge' ;;
'') not_for_merge_= ;;
esac
# remote-nick is the URL given on the command line (or a shorthand)
# remote-name is the $GIT_DIR relative refs/ path we computed
# for this refspec.
case "$remote_name_" in
HEAD)
note_= ;;
refs/heads/*)
note_="$(expr "$remote_name_" : 'refs/heads/\(.*\)')"
note_="branch '$note_' of " ;;
refs/tags/*)
note_="$(expr "$remote_name_" : 'refs/tags/\(.*\)')"
note_="tag '$note_' of " ;;
*)
note_="$remote_name of " ;;
esac
remote_1_=$(expr "$remote_" : '\(.*\)\.git/*$') &&
remote_="$remote_1_"
note_="$note_$remote_"
# 2.6.11-tree tag would not be happy to be fed to resolve.
if git-cat-file commit "$head_" >/dev/null 2>&1
then
headc_=$(git-rev-parse --verify "$head_^0") || exit
echo "$headc_ $not_for_merge_ $note_" >>"$GIT_DIR/FETCH_HEAD"
[ "$verbose" ] && echo >&2 "* committish: $head_"
[ "$verbose" ] && echo >&2 " $note_"
else
echo "$head_ not-for-merge $note_" >>"$GIT_DIR/FETCH_HEAD"
[ "$verbose" ] && echo >&2 "* non-commit: $head_"
[ "$verbose" ] && echo >&2 " $note_"
fi
if test "$local_name_" != ""
then
# We are storing the head locally. Make sure that it is
# a fast forward (aka "reverse push").
fast_forward_local "$local_name_" "$head_" "$note_"
fi
}
fast_forward_local () {
mkdir -p "$(dirname "$GIT_DIR/$1")"
case "$1" in
refs/tags/*)
# Tags need not be pointing at commits so there
# is no way to guarantee "fast-forward" anyway.
if test -f "$GIT_DIR/$1"
then
if now_=$(cat "$GIT_DIR/$1") && test "$now_" = "$2"
then
[ "$verbose" ] && echo >&2 "* $1: same as $3"
else
echo >&2 "* $1: updating with $3"
fi
else
echo >&2 "* $1: storing $3"
fi
git-update-ref "$1" "$2"
;;
refs/heads/*)
# $1 is the ref being updated.
# $2 is the new value for the ref.
local=$(git-rev-parse --verify "$1^0" 2>/dev/null)
if test "$local"
then
# Require fast-forward.
mb=$(git-merge-base "$local" "$2") &&
case "$2,$mb" in
$local,*)
echo >&2 "* $1: same as $3"
;;
*,$local)
echo >&2 "* $1: fast forward to $3"
git-update-ref "$1" "$2" "$local"
;;
*)
false
;;
esac || {
echo >&2 "* $1: does not fast forward to $3;"
case ",$force,$single_force," in
*,t,*)
echo >&2 " forcing update."
git-update-ref "$1" "$2" "$local"
;;
*)
echo >&2 " not updating."
;;
esac
}
else
echo >&2 "* $1: storing $3"
git-update-ref "$1" "$2"
fi
;;
esac
}
case "$update_head_ok" in
'')
orig_head=$(git-rev-parse --verify HEAD 2>/dev/null)
;;
esac
# If --tags (and later --heads or --all) is specified, then we are
# not talking about defaults stored in Pull: line of remotes or
# branches file, and just fetch those and refspecs explicitly given.
# Otherwise we do what we always did.
reflist=$(get_remote_refs_for_fetch "$@")
if test "$tags"
then
taglist=$(IFS=" " &&
git-ls-remote $upload_pack --tags "$remote" |
while read sha1 name
do
case "$name" in
(*^*) continue ;;
esac
if git-check-ref-format "$name"
then
echo ".${name}:${name}"
else
echo >&2 "warning: tag ${name} ignored"
fi
done)
if test "$#" -gt 1
then
# remote URL plus explicit refspecs; we need to merge them.
reflist="$reflist$LF$taglist"
else
# No explicit refspecs; fetch tags only.
reflist=$taglist
fi
fi
fetch_main () {
reflist="$1"
refs=
for ref in $reflist
do
refs="$refs$LF$ref"
# These are relative path from $GIT_DIR, typically starting at refs/
# but may be HEAD
if expr "$ref" : '\.' >/dev/null
then
not_for_merge=t
ref=$(expr "$ref" : '\.\(.*\)')
else
not_for_merge=
fi
if expr "$ref" : '\+' >/dev/null
then
single_force=t
ref=$(expr "$ref" : '\+\(.*\)')
else
single_force=
fi
remote_name=$(expr "$ref" : '\([^:]*\):')
local_name=$(expr "$ref" : '[^:]*:\(.*\)')
rref="$rref$LF$remote_name"
# There are transports that can fetch only one head at a time...
case "$remote" in
http://* | https://*)
if [ -n "$GIT_SSL_NO_VERIFY" ]; then
curl_extra_args="-k"
fi
remote_name_quoted=$(perl -e '
my $u = $ARGV[0];
$u =~ s{([^-a-zA-Z0-9/.])}{sprintf"%%%02x",ord($1)}eg;
print "$u";
' "$remote_name")
head=$(curl -nsfL $curl_extra_args "$remote/$remote_name_quoted") &&
expr "$head" : "$_x40\$" >/dev/null ||
die "Failed to fetch $remote_name from $remote"
echo >&2 Fetching "$remote_name from $remote" using http
git-http-fetch -v -a "$head" "$remote/" || exit
;;
rsync://*)
TMP_HEAD="$GIT_DIR/TMP_HEAD"
rsync -L -q "$remote/$remote_name" "$TMP_HEAD" || exit 1
head=$(git-rev-parse --verify TMP_HEAD)
rm -f "$TMP_HEAD"
test "$rsync_slurped_objects" || {
rsync -av --ignore-existing --exclude info \
"$remote/objects/" "$GIT_OBJECT_DIRECTORY/" || exit
# Look at objects/info/alternates for rsync -- http will
# support it natively and git native ones will do it on
# the remote end. Not having that file is not a crime.
rsync -q "$remote/objects/info/alternates" \
"$GIT_DIR/TMP_ALT" 2>/dev/null ||
rm -f "$GIT_DIR/TMP_ALT"
if test -f "$GIT_DIR/TMP_ALT"
then
resolve_alternates "$remote" <"$GIT_DIR/TMP_ALT" |
while read alt
do
case "$alt" in 'bad alternate: '*) die "$alt";; esac
echo >&2 "Getting alternate: $alt"
rsync -av --ignore-existing --exclude info \
"$alt" "$GIT_OBJECT_DIRECTORY/" || exit
done
rm -f "$GIT_DIR/TMP_ALT"
fi
rsync_slurped_objects=t
}
;;
*)
# We will do git native transport with just one call later.
continue ;;
esac
append_fetch_head "$head" "$remote" \
"$remote_name" "$remote_nick" "$local_name" "$not_for_merge"
done
case "$remote" in
http://* | https://* | rsync://* )
;; # we are already done.
*)
( : subshell because we muck with IFS
IFS=" $LF"
(
git-fetch-pack $exec $keep "$remote" $rref || echo failed "$remote"
) |
while read sha1 remote_name
do
case "$sha1" in
failed)
echo >&2 "Fetch failure: $remote"
exit 1 ;;
esac
found=
single_force=
for ref in $refs
do
case "$ref" in
+$remote_name:*)
single_force=t
not_for_merge=
found="$ref"
break ;;
.+$remote_name:*)
single_force=t
not_for_merge=t
found="$ref"
break ;;
.$remote_name:*)
not_for_merge=t
found="$ref"
break ;;
$remote_name:*)
not_for_merge=
found="$ref"
break ;;
esac
done
local_name=$(expr "$found" : '[^:]*:\(.*\)')
append_fetch_head "$sha1" "$remote" \
"$remote_name" "$remote_nick" "$local_name" "$not_for_merge"
done
) || exit ;;
esac
}
fetch_main "$reflist"
# automated tag following
case "$no_tags$tags" in
'')
taglist=$(IFS=" " &&
git-ls-remote $upload_pack --tags "$remote" |
sed -ne 's|^\([0-9a-f]*\)[ ]\(refs/tags/.*\)^{}$|\1 \2|p' |
while read sha1 name
do
test -f "$GIT_DIR/$name" && continue
git-check-ref-format "$name" || {
echo >&2 "warning: tag ${name} ignored"
continue
}
git-cat-file -t "$sha1" >/dev/null 2>&1 || continue
echo >&2 "Auto-following $name"
echo ".${name}:${name}"
done)
case "$taglist" in
'') ;;
?*)
fetch_main "$taglist" ;;
esac
esac
# If the original head was empty (i.e. no "master" yet), or
# if we were told not to worry, we do not have to check.
case ",$update_head_ok,$orig_head," in
*,, | t,* )
;;
*)
curr_head=$(git-rev-parse --verify HEAD 2>/dev/null)
if test "$curr_head" != "$orig_head"
then
git-update-ref HEAD "$orig_head"
die "Cannot fetch into the current branch."
fi
;;
esac
[-- Attachment #3: diff test postimage --]
[-- Type: text/plain, Size: 9508 bytes --]
#!/bin/sh
#
USAGE='<fetch-options> <repository> <refspec>...'
. git-sh-setup
. git-parse-remote
_x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'
_x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40"
LF='
'
IFS="$LF"
no_tags=
tags=
append=
force=
verbose=
update_head_ok=
exec=
upload_pack=
while case "$#" in 0) break ;; esac
do
case "$1" in
-a|--a|--ap|--app|--appe|--appen|--append)
append=t
;;
--upl|--uplo|--uploa|--upload|--upload-|--upload-p|\
--upload-pa|--upload-pac|--upload-pack)
shift
exec="--exec=$1"
upload_pack="-u $1"
;;
-f|--f|--fo|--for|--forc|--force)
force=t
;;
-t|--t|--ta|--tag|--tags)
tags=t
;;
-n|--n|--no|--no-|--no-t|--no-ta|--no-tag|--no-tags)
no_tags=t
;;
-u|--u|--up|--upd|--upda|--updat|--update|--update-|--update-h|\
--update-he|--update-hea|--update-head|--update-head-|\
--update-head-o|--update-head-ok)
update_head_ok=t
;;
-v|--verbose)
verbose=Yes
;;
-k|--k|--ke|--kee|--keep)
keep=--keep
;;
-*)
usage
;;
*)
break
;;
esac
shift
done
case "$#" in
0)
test -f "$GIT_DIR/branches/origin" ||
test -f "$GIT_DIR/remotes/origin" ||
die "Where do you want to fetch from today?"
set origin ;;
esac
remote_nick="$1"
remote=$(get_remote_url "$@")
refs=
rref=
rsync_slurped_objects=
if test "" = "$append"
then
: >"$GIT_DIR/FETCH_HEAD"
fi
append_fetch_head () {
head_="$1"
remote_="$2"
remote_name_="$3"
remote_nick_="$4"
local_name_="$5"
case "$6" in
t) not_for_merge_='not-for-merge' ;;
'') not_for_merge_= ;;
esac
# remote-nick is the URL given on the command line (or a shorthand)
# remote-name is the $GIT_DIR relative refs/ path we computed
# for this refspec.
case "$remote_name_" in
HEAD)
note_= ;;
refs/heads/*)
note_="$(expr "$remote_name_" : 'refs/heads/\(.*\)')"
note_="branch '$note_' of " ;;
refs/tags/*)
note_="$(expr "$remote_name_" : 'refs/tags/\(.*\)')"
note_="tag '$note_' of " ;;
*)
note_="$remote_name of " ;;
esac
remote_1_=$(expr "$remote_" : '\(.*\)\.git/*$') &&
remote_="$remote_1_"
note_="$note_$remote_"
# 2.6.11-tree tag would not be happy to be fed to resolve.
if git-cat-file commit "$head_" >/dev/null 2>&1
then
headc_=$(git-rev-parse --verify "$head_^0") || exit
echo "$headc_ $not_for_merge_ $note_" >>"$GIT_DIR/FETCH_HEAD"
[ "$verbose" ] && echo >&2 "* committish: $head_"
[ "$verbose" ] && echo >&2 " $note_"
else
echo "$head_ not-for-merge $note_" >>"$GIT_DIR/FETCH_HEAD"
[ "$verbose" ] && echo >&2 "* non-commit: $head_"
[ "$verbose" ] && echo >&2 " $note_"
fi
if test "$local_name_" != ""
then
# We are storing the head locally. Make sure that it is
# a fast forward (aka "reverse push").
fast_forward_local "$local_name_" "$head_" "$note_"
fi
}
fast_forward_local () {
mkdir -p "$(dirname "$GIT_DIR/$1")"
case "$1" in
refs/tags/*)
# Tags need not be pointing at commits so there
# is no way to guarantee "fast-forward" anyway.
if test -f "$GIT_DIR/$1"
then
if now_=$(cat "$GIT_DIR/$1") && test "$now_" = "$2"
then
[ "$verbose" ] && echo >&2 "* $1: same as $3"
else
echo >&2 "* $1: updating with $3"
fi
else
echo >&2 "* $1: storing $3"
fi
git-update-ref "$1" "$2"
;;
refs/heads/*)
# $1 is the ref being updated.
# $2 is the new value for the ref.
local=$(git-rev-parse --verify "$1^0" 2>/dev/null)
if test "$local"
then
# Require fast-forward.
mb=$(git-merge-base "$local" "$2") &&
case "$2,$mb" in
$local,*)
echo >&2 "* $1: same as $3"
;;
*,$local)
echo >&2 "* $1: fast forward to $3"
git-update-ref "$1" "$2" "$local"
;;
*)
false
;;
esac || {
echo >&2 "* $1: does not fast forward to $3;"
case ",$force,$single_force," in
*,t,*)
echo >&2 " forcing update."
git-update-ref "$1" "$2" "$local"
;;
*)
echo >&2 " not updating."
;;
esac
}
else
echo >&2 "* $1: storing $3"
git-update-ref "$1" "$2"
fi
;;
esac
}
case "$update_head_ok" in
'')
orig_head=$(git-rev-parse --verify HEAD 2>/dev/null)
;;
esac
# If --tags (and later --heads or --all) is specified, then we are
# not talking about defaults stored in Pull: line of remotes or
# branches file, and just fetch those and refspecs explicitly given.
# Otherwise we do what we always did.
reflist=$(get_remote_refs_for_fetch "$@")
if test "$tags"
then
taglist=$(IFS=" " &&
git-ls-remote $upload_pack --tags "$remote" |
while read sha1 name
do
case "$name" in
(*^*) continue ;;
esac
if git-check-ref-format "$name"
then
echo ".${name}:${name}"
else
echo >&2 "warning: tag ${name} ignored"
fi
done)
if test "$#" -gt 1
then
# remote URL plus explicit refspecs; we need to merge them.
reflist="$reflist$LF$taglist"
else
# No explicit refspecs; fetch tags only.
reflist=$taglist
fi
fi
fetch_main () {
reflist="$1"
refs=
for ref in $reflist
do
refs="$refs$LF$ref"
# These are relative path from $GIT_DIR, typically starting at refs/
# but may be HEAD
if expr "$ref" : '\.' >/dev/null
then
not_for_merge=t
ref=$(expr "$ref" : '\.\(.*\)')
else
not_for_merge=
fi
if expr "$ref" : '\+' >/dev/null
then
single_force=t
ref=$(expr "$ref" : '\+\(.*\)')
else
single_force=
fi
remote_name=$(expr "$ref" : '\([^:]*\):')
local_name=$(expr "$ref" : '[^:]*:\(.*\)')
rref="$rref$LF$remote_name"
# There are transports that can fetch only one head at a time...
case "$remote" in
http://* | https://*)
if [ -n "$GIT_SSL_NO_VERIFY" ]; then
curl_extra_args="-k"
fi
remote_name_quoted=$(perl -e '
my $u = $ARGV[0];
$u =~ s{([^-a-zA-Z0-9/.])}{sprintf"%%%02x",ord($1)}eg;
print "$u";
' "$remote_name")
head=$(curl -nsfL $curl_extra_args "$remote/$remote_name_quoted") &&
expr "$head" : "$_x40\$" >/dev/null ||
die "Failed to fetch $remote_name from $remote"
echo >&2 Fetching "$remote_name from $remote" using http
git-http-fetch -v -a "$head" "$remote/" || exit
;;
rsync://*)
TMP_HEAD="$GIT_DIR/TMP_HEAD"
rsync -L -q "$remote/$remote_name" "$TMP_HEAD" || exit 1
head=$(git-rev-parse --verify TMP_HEAD)
rm -f "$TMP_HEAD"
test "$rsync_slurped_objects" || {
rsync -av --ignore-existing --exclude info \
"$remote/objects/" "$GIT_OBJECT_DIRECTORY/" || exit
# Look at objects/info/alternates for rsync -- http will
# support it natively and git native ones will do it on
# the remote end. Not having that file is not a crime.
rsync -q "$remote/objects/info/alternates" \
"$GIT_DIR/TMP_ALT" 2>/dev/null ||
rm -f "$GIT_DIR/TMP_ALT"
if test -f "$GIT_DIR/TMP_ALT"
then
resolve_alternates "$remote" <"$GIT_DIR/TMP_ALT" |
while read alt
do
case "$alt" in 'bad alternate: '*) die "$alt";; esac
echo >&2 "Getting alternate: $alt"
rsync -av --ignore-existing --exclude info \
"$alt" "$GIT_OBJECT_DIRECTORY/" || exit
done
rm -f "$GIT_DIR/TMP_ALT"
fi
rsync_slurped_objects=t
}
;;
*)
# We will do git native transport with just one call later.
continue ;;
esac
append_fetch_head "$head" "$remote" \
"$remote_name" "$remote_nick" "$local_name" "$not_for_merge"
done
case "$remote" in
http://* | https://* | rsync://* )
;; # we are already done.
*)
( : subshell because we muck with IFS
IFS=" $LF"
(
git-fetch-pack $exec $keep --thin "$remote" $rref || echo failed "$remote"
) |
while read sha1 remote_name
do
case "$sha1" in
failed)
echo >&2 "Fetch failure: $remote"
exit 1 ;;
esac
found=
single_force=
for ref in $refs
do
case "$ref" in
+$remote_name:*)
single_force=t
not_for_merge=
found="$ref"
break ;;
.+$remote_name:*)
single_force=t
not_for_merge=t
found="$ref"
break ;;
.$remote_name:*)
not_for_merge=t
found="$ref"
break ;;
$remote_name:*)
not_for_merge=
found="$ref"
break ;;
esac
done
local_name=$(expr "$found" : '[^:]*:\(.*\)')
append_fetch_head "$sha1" "$remote" \
"$remote_name" "$remote_nick" "$local_name" "$not_for_merge"
done
) || exit ;;
esac
}
fetch_main "$reflist"
# automated tag following
case "$no_tags$tags" in
'')
case "$reflist" in
*:refs/*)
# effective only when we are following remote branch
# using local tracking branch.
taglist=$(IFS=" " &&
git-ls-remote $upload_pack --tags "$remote" |
sed -ne 's|^\([0-9a-f]*\)[ ]\(refs/tags/.*\)^{}$|\1 \2|p' |
while read sha1 name
do
test -f "$GIT_DIR/$name" && continue
git-check-ref-format "$name" || {
echo >&2 "warning: tag ${name} ignored"
continue
}
git-cat-file -t "$sha1" >/dev/null 2>&1 || continue
echo >&2 "Auto-following $name"
echo ".${name}:${name}"
done)
esac
case "$taglist" in
'') ;;
?*)
fetch_main "$taglist" ;;
esac
esac
# If the original head was empty (i.e. no "master" yet), or
# if we were told not to worry, we do not have to check.
case ",$update_head_ok,$orig_head," in
*,, | t,* )
;;
*)
curr_head=$(git-rev-parse --verify HEAD 2>/dev/null)
if test "$curr_head" != "$orig_head"
then
git-update-ref HEAD "$orig_head"
die "Cannot fetch into the current branch."
fi
;;
esac
^ permalink raw reply
* Re: [PATCH 2/2] pack-objects: be incredibly anal about stdio semantics
From: Junio C Hamano @ 2006-04-02 21:09 UTC (permalink / raw)
To: Linus Torvalds; +Cc: git
In-Reply-To: <Pine.LNX.4.64.0604021328380.3050@g5.osdl.org>
Linus Torvalds <torvalds@osdl.org> writes:
> This is the "letter of the law" version of using fgets() properly in the
> face of incredibly broken stdio implementations. We can work around the
> Solaris breakage with SA_RESTART, but in case anybody else is ever that
> stupid, here's the "safe" (read: "insanely anal") way to use fgets.
Thanks.
It's good that I can say "Oh, I think this is the part that is
broken, but I am going to bed" to find the problem solved by
capable others when I wake up the next day. Global distributed
development process at the finest, although I suspect Jason,
Linus and myself are all in the same timezone ;-)
Did you mean this as a real change or a demonstration? The
sigaction change is a real fix, but somehow I find this one
similar to the "(void*) NULL" thing you objected earlier (which
was not merged because I agreed with your argument)...
^ permalink raw reply
* Re: [RFH] xdiff shows trivially redundant diff.
From: Linus Torvalds @ 2006-04-02 21:16 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Davide Libenzi, git
In-Reply-To: <7vzmj3k7x9.fsf@assigned-by-dhcp.cox.net>
On Sun, 2 Apr 2006, Junio C Hamano wrote:
>
> I should have tried your pristine xdiff code myself before
> bothering you, but I haven't (sorry).
It definitely happens with plain libxdiff-0.17 too.
In general, unless it's related to the "\ No newline" or the extra stuff
on the "@@"-line, I'd be very surprised if we have any differences in the
diff output wrt libxdiff-0.17. I was really pretty careful, and didn't
change the code at all, just removed unnecessary files and functions.
Linus
^ permalink raw reply
* Re: [PATCH 2/2] pack-objects: be incredibly anal about stdio semantics
From: Linus Torvalds @ 2006-04-02 21:21 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7vmzf3k7m9.fsf@assigned-by-dhcp.cox.net>
On Sun, 2 Apr 2006, Junio C Hamano wrote:
> Linus Torvalds <torvalds@osdl.org> writes:
>
> > This is the "letter of the law" version of using fgets() properly in the
> > face of incredibly broken stdio implementations. We can work around the
> > Solaris breakage with SA_RESTART, but in case anybody else is ever that
> > stupid, here's the "safe" (read: "insanely anal") way to use fgets.
>
> Did you mean this as a real change or a demonstration? The
> sigaction change is a real fix, but somehow I find this one
> similar to the "(void*) NULL" thing you objected earlier (which
> was not merged because I agreed with your argument)...
I don't have any really strong opinions on it. I think that any libc that
needs the "ferror()" test + EINTR loopback is totally broken. I would
happily say that people should just not use a development platform that is
that horrible.
But the fact that Solaris actually had that as a real problem (never mind
that we could work around it another way) just makes me go "Hmm..".
So I _think_ we're safe with just the "sigaction()" diff. Neither of the
patches _should_ make any difference at all on a sane platform.
Linus
^ permalink raw reply
* Re: Default remote branch for local branch
From: Junio C Hamano @ 2006-04-02 21:40 UTC (permalink / raw)
To: Josef Weidendorfer; +Cc: git
In-Reply-To: <200604021817.30222.Josef.Weidendorfer@gmx.de>
Josef Weidendorfer <Josef.Weidendorfer@gmx.de> writes:
> On Saturday 01 April 2006 06:18, Pavel Roskin wrote:
>> On Fri, 2006-03-31 at 19:05 -0800, Junio C Hamano wrote:
>> > Maybe you would want something like this.
>> >
>> > In $GIT_DIR/config:
>> >
>> > [pull]
>> > origin = linus for master
>> > origin = irq-pio of libata for ata-irq-pio
>> > origin = pata-drivers of libata for ata-pata
>
> Let me try to understand this: the general idea is that
>
> pull.origin = [<refspec> of] <remote> for <branch>
>
> specifies the default action of git-pull if we are on <branch>, ie.
> a "git pull" then runs "git pull <remote> [<refspec>]".
Not quite.
It will be (if this were a serious proposal -- I am not
absolutely convinced this is a good idea) more like "git fetch
<remote>" followed by "git-merge HEAD the-refspec-named-there".
The implementation of the above would involve changes to
git-fetch, because it needs to give ".not-for-merge" mark to
different line in FETCH_HEAD depending on [<refspec> of] part.
> So the example above, if .git/remotes/linus would contain two
> refspecs, and you are on the branch of the 2nd refspec, it would
> do the wrong thing: merge the 1st refspec with current branch.
Sorry I fail to visualize this part.
>> Secondly, I think the relationship should be between a local development
>> branch and a local tracking branch.
>
> Agree.
> It is also useful to specify this relation if the upstream is purely a
> local branch, e.g. when branching off a local branch, and you want to
> pull in changes from the local upstream.
>
> This works automatically if git-pull only does upstream fetching if
> there is a remote branch associated. The default action of git-fetch
> similar could be "fetch the upstream branch, if that tracks a remote
> branch", using the same configuration.
Interesting.
You would need sanity checker for $GIT_DIR/remotes/* files if
you do this to make sure no local tracking branch is by mistake
configured to track two remote branches, which is a good change,
but then:
git-pull, without parameter, would:
(1) check if this branch has any local branch it usually
merges from; if not, do whatever we traditionally
did (or barf).
(2) if there is a local branch it merges from, check if
it is a tracking branch for a remote, by looking at
remotes/* files. It would be nice if we could
detect tracking branches fed from external svn/cvs
repositories via svn/cvs-import this way at this
time. If not, skip the next step and go directly to
(4).
(3) run git-fetch (or svn/cvs-import) to update the
tracking branch;
(4) merge from that other local branch.
> Junio's proposal has the advantage that you do not have to search in all
> files in .git/remotes (and even .git/branches) for the remote branch that
> maps to a given local branch.
> But that is not the big issue.
A bigger thing is that I am trying to avoid _requiring_ tracking
branches. If you are not micromanaging your subsystem
maintainers, you should not have to care where they were the
last time you pulled from them. You should be able to just
pull, examine what the merge brings in, and decide it is worth
merging. If it isn't, do a "reset", tell them "not good, please
rework and let me know when you are ready," and forget about it.
If we are going require tracking branches, we could do a bit
more with them, like remembering where the tip was when we
fetched the last time (or the time before that...) and diff with
that, but the tracking branch heads are not set up to do things
like that right now -- they are single pointers.
>> Perhaps you are missing a remotes editor command?
Perhaps. Also perhaps a remotes/ sanity checker.
Something like this:
$ git branch --describe ata-pata
Typically merges from pata-drivers branch of
git://.../jgarzik/libata-dev.git
which is tracked with local refs/remotes/libata/pata-drivers.
$ git branch --decribe refs/remotes/libata/pata-drivers
Tracking branch for pata-drivers branch of
git://.../jgarzik/libata-dev.git
$ git checkout origin
warning: you are checking out a tracking branch for "master" branch of
warning: git://.../torvalds/linux-2.6.git
warning: commit/pull/merge commands are disabled.
hint: you can still create a new branch from here.
^ permalink raw reply
* [PATCH] Documentation: revise top of git man page
From: J. Bruce Fields @ 2006-04-02 21:54 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
I'm afraid I'll be accused of trying to suck all the jokes and the
personality out of the git documentation. I'm not! Really!
That said, "man git" is one of the first things a new user is likely try,
and it seems a little cruel to start off with a somewhat obscure joke
about the architecture of git.
So instead I'm trying for a relatively straightforward description of what
git does, and what features distinguish it from other systems, together
with immediate links to introductory documentation.
I also did some minor reorganization in an attempt to clarify the
classification of commands. And revised a bit for conciseness (as is
obvious from the diffstat--hopefully I didn't cut anything important).
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
---
Documentation/git.txt | 103 +++++++++++++++++++++++--------------------------
1 files changed, 48 insertions(+), 55 deletions(-)
9fc3b77b82004356a6e5fa19e5e31a2b19f088d3
diff --git a/Documentation/git.txt b/Documentation/git.txt
index fe34f50..06b2e53 100644
--- a/Documentation/git.txt
+++ b/Documentation/git.txt
@@ -12,10 +12,14 @@ SYNOPSIS
DESCRIPTION
-----------
-'git' is both a program and a directory content tracker system.
-The program 'git' is just a wrapper to reach the core git programs
-(or a potty if you like, as it's not exactly porcelain but still
-brings your stuff to the plumbing).
+Git is a fast, scalable, distributed revision control system with an
+unusually rich command set that provides both high-level operations
+and full access to internals.
+
+See this link:tutorial.html[tutorial] to get started, then see
+link:everyday.html[Everyday Git] for a useful minimum set of commands, and
+"man git-commandname" for documentation of each command. CVS users may
+also want to read link:cvs-migration.html[CVS migration].
OPTIONS
-------
@@ -35,55 +39,38 @@ OPTIONS
the current setting and then exit.
-NOT LEARNING CORE GIT COMMANDS
-------------------------------
+FURTHER DOCUMENTATION
+---------------------
+
+See the references above to get started using git. The following is
+probably more detail than necessary for a first-time user.
+
+The <<Discussion,Discussion>> section below and the
+link:core-tutorial.html[Core tutorial] both provide introductions to the
+underlying git architecture.
+
+See also the link:howto-index.html[howto] documents for some useful
+examples.
+
+GIT COMMANDS
+------------
-This manual is intended to give complete background information
-and internal workings of git, which may be too much for most
-people. The <<Discussion>> section below contains much useful
-definition and clarification - read that first.
-
-If you are interested in using git to manage (version control)
-projects, use link:tutorial.html[The Tutorial] to get you started,
-and then link:everyday.html[Everyday GIT] as a guide to the
-minimum set of commands you need to know for day-to-day work.
-Most likely, that will get you started, and you can go a long
-way without knowing the low level details too much.
-
-The link:core-tutorial.html[Core tutorial] document covers how things
-internally work.
-
-If you are migrating from CVS, link:cvs-migration.html[cvs
-migration] document may be helpful after you finish the
-tutorial.
-
-After you get the general feel from the tutorial and this
-overview page, you may want to take a look at the
-link:howto-index.html[howto] documents.
-
-
-CORE GIT COMMANDS
------------------
-
-If you are writing your own Porcelain, you need to be familiar
-with most of the low level commands --- I suggest starting from
-gitlink:git-update-index[1] and gitlink:git-read-tree[1].
-
-
-Commands Overview
------------------
-The git commands can helpfully be split into those that manipulate
-the repository, the index and the files in the working tree, those that
-interrogate and compare them, and those that moves objects and
-references between repositories.
-
-In addition, git itself comes with a spartan set of porcelain
-commands. They are usable but are not meant to compete with real
-Porcelains.
-
-There are also some ancillary programs that can be viewed as useful
-aids for using the core commands but which are unlikely to be used by
-SCMs layered over git.
+We divide git into high level ("porcelain") commands and low level
+("plumbing") commands.
+
+Low-level commands (plumbing)
+-----------------------------
+
+Although git includes its
+own porcelain layer, its low-level commands are sufficient to support
+development of alternative porcelains. Developers of such porcelains
+might start by reading about gitlink:git-update-index[1] and
+gitlink:git-read-tree[1].
+
+We divide the low-level commands into commands that manipulate objects (in
+the repository, index, and working tree), commands that interrogate and
+compare objects, and commands that move objects and references between
+repositories.
Manipulation commands
~~~~~~~~~~~~~~~~~~~~~
@@ -248,8 +235,14 @@ gitlink:git-upload-pack[1]::
what are asked for.
-Porcelain-ish Commands
-----------------------
+High-level commands (porcelain)
+-------------------------------
+
+We separate the porcelain commands into the main commands and some
+ancillary user utilities.
+
+Main porcelain commands
+~~~~~~~~~~~~~~~~~~~~~~~
gitlink:git-add[1]::
Add paths to the index.
@@ -346,7 +339,7 @@ gitlink:git-whatchanged[1]::
Ancillary Commands
-------------------
+~~~~~~~~~~~~~~~~~~
Manipulators:
gitlink:git-applypatch[1]::
--
1.2.4.g0382
^ permalink raw reply related
* Re: [PATCH 2/2] pack-objects: be incredibly anal about stdio semantics
From: Jason Riedy @ 2006-04-02 22:12 UTC (permalink / raw)
To: git
In-Reply-To: <Pine.LNX.4.64.0604021417301.23419@g5.osdl.org>
And Linus Torvalds writes:
-
- I don't have any really strong opinions on it. I think that any libc that
- needs the "ferror()" test + EINTR loopback is totally broken. I would
- happily say that people should just not use a development platform that is
- that horrible.
If you consider stdio to be a low-level wrapper over syscalls
that only adds buffering and simple parsing, then passing EINTR
back to the application is a sensible choice. I wouldn't be
too surprised if L4, VxWorks, etc. do something similar.
- So I _think_ we're safe with just the "sigaction()" diff. Neither of the
- patches _should_ make any difference at all on a sane platform.
Anyone with an older HP/UX care to try these patches? HP/UX
may not be sane, but I think it may lack SA_RESTART. I don't
know if stdio calls need restarted, though.
Jason
^ permalink raw reply
* Re: [RFH] xdiff shows trivially redundant diff.
From: Davide Libenzi @ 2006-04-02 22:14 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, Linus Torvalds
In-Reply-To: <7vzmj3k7x9.fsf@assigned-by-dhcp.cox.net>
On Sun, 2 Apr 2006, Junio C Hamano wrote:
> I should have tried your pristine xdiff code myself before
> bothering you, but I haven't (sorry).
>
> The problem is from the "stripped down" version we use in git,
> so you may or may not see the problem in your version. Attached
> are the files.
Yes, it does even vanilla libxdiff ;) It's not a problem though, since it
is created in xdl_cleanup_records() that tries to do a fast pass over the
records to try to simplify the real diff operation. In trying to be fast,
only hashes are compared, and it happens that the hash for "'')" collides
with another one (try to replace one of the "'')" chars with another one).
Why is this not a problem? Because what this lead to is only lines to be
marked as changed, with a probability of about N/2^(8 * sizeof(long) - 1),
even though they are not. And this happens only during sequential groups
of lines changed, that is when the hash-colliding line is either at the
begin or the end of the run.
- Davide
^ permalink raw reply
* Re: [RFH] xdiff shows trivially redundant diff.
From: Davide Libenzi @ 2006-04-02 22:18 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Junio C Hamano, git
In-Reply-To: <Pine.LNX.4.64.0604021411300.23419@g5.osdl.org>
On Sun, 2 Apr 2006, Linus Torvalds wrote:
> On Sun, 2 Apr 2006, Junio C Hamano wrote:
>>
>> I should have tried your pristine xdiff code myself before
>> bothering you, but I haven't (sorry).
>
> It definitely happens with plain libxdiff-0.17 too.
>
> In general, unless it's related to the "\ No newline" or the extra stuff
> on the "@@"-line, I'd be very surprised if we have any differences in the
> diff output wrt libxdiff-0.17. I was really pretty careful, and didn't
> change the code at all, just removed unnecessary files and functions.
So it does 0.18, that contains the "\ No newline" handling for text diff
and patch. See my reply to Junio also.
- Davide
^ permalink raw reply
* Re: git-svn and svn sw --relocate
From: Eric Wong @ 2006-04-02 22:21 UTC (permalink / raw)
To: Nicolas Vilz 'niv'; +Cc: git
In-Reply-To: <4430123E.5090605@iaglans.de>
Nicolas Vilz 'niv' <niv@iaglans.de> wrote:
> ok, guys... next question:
>
> i have now my repository locally and i want to get it remotely on a
> server, in order to have a few collaborators...
>
> the steps on the svn-side are clear. But what do i have todo on the
> git-svn-side of this life?
>
> does a simple "svn sw --relocate" do the job in the git-svn meta-dir?
Yes, you'll need to do that in .git/git-svn/tree and also update
.git/git-svn/info/url by hand.
--
Eric Wong
^ permalink raw reply
* [PATCH] Use sigaction and SA_RESTART in read-tree.c; add option in Makefile.
From: Jason Riedy @ 2006-04-02 22:29 UTC (permalink / raw)
To: Linus Torvalds, Junio C Hamano; +Cc: git
In-Reply-To: <Pine.LNX.4.64.0604021312510.3050@g5.osdl.org>
Might as well ape the sigaction change in read-tree.c to avoid
the same potential problems. The fprintf status output will
be overwritten in a second, so don't bother guarding it. Do
move the fputc after disabling SIGALRM to ensure we go to the
next line, though.
Also add a NO_SA_RESTART option in the Makefile in case someone
doesn't have SA_RESTART but does restart (maybe older HP/UX?).
We want the builder to chose this specifically in case the
system both lacks SA_RESTART and does not restart stdio calls;
a compat #define in git-compat-utils.h would silently allow
broken systems.
Signed-off-by: Jason Riedy <ejr@cs.berkeley.edu>
---
Makefile | 7 +++++++
read-tree.c | 28 +++++++++++++++++++---------
2 files changed, 26 insertions(+), 9 deletions(-)
521dc260ea90a23d58a4e920203af5035ca1a673
diff --git a/Makefile b/Makefile
index c79d646..f3b1d49 100644
--- a/Makefile
+++ b/Makefile
@@ -63,6 +63,9 @@
# Define COLLISION_CHECK below if you believe that SHA1's
# 1461501637330902918203684832716283019655932542976 hashes do not give you
# sufficient guarantee that no collisions between objects will ever happen.
+#
+# Define NO_SA_RESTART if your platform does not have SA_RESTART, _AND_ if
+# it automatically restarts interrupted stdio calls.
# Define USE_NSEC below if you want git to care about sub-second file mtimes
# and ctimes. Note that you need recent glibc (at least 2.2.4) for this, and
@@ -425,6 +428,10 @@
endif
ifdef NO_ACCURATE_DIFF
ALL_CFLAGS += -DNO_ACCURATE_DIFF
+endif
+
+ifdef NO_SA_RESTART
+ ALL_CFLAGS += -DSA_RESTART=0
endif
# Shell quote (do not use $(call) to accomodate ancient setups);
diff --git a/read-tree.c b/read-tree.c
index eaff444..4422dbf 100644
--- a/read-tree.c
+++ b/read-tree.c
@@ -273,10 +273,26 @@
static void progress_interval(int signum)
{
- signal(SIGALRM, progress_interval);
progress_update = 1;
}
+static void setup_progress_signal(void)
+{
+ struct sigaction sa;
+ struct itimerval v;
+
+ memset(&sa, 0, sizeof(sa));
+ sa.sa_handler = progress_interval;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = SA_RESTART;
+ sigaction(SIGALRM, &sa, NULL);
+
+ v.it_interval.tv_sec = 1;
+ v.it_interval.tv_usec = 0;
+ v.it_value = v.it_interval;
+ setitimer(ITIMER_REAL, &v, NULL);
+}
+
static void check_updates(struct cache_entry **src, int nr)
{
static struct checkout state = {
@@ -289,8 +305,6 @@
unsigned last_percent = 200, cnt = 0, total = 0;
if (update && verbose_update) {
- struct itimerval v;
-
for (total = cnt = 0; cnt < nr; cnt++) {
struct cache_entry *ce = src[cnt];
if (!ce->ce_mode || ce->ce_flags & mask)
@@ -302,12 +316,8 @@
total = 0;
if (total) {
- v.it_interval.tv_sec = 1;
- v.it_interval.tv_usec = 0;
- v.it_value = v.it_interval;
- signal(SIGALRM, progress_interval);
- setitimer(ITIMER_REAL, &v, NULL);
fprintf(stderr, "Checking files out...\n");
+ setup_progress_signal();
progress_update = 1;
}
cnt = 0;
@@ -341,8 +351,8 @@
}
}
if (total) {
- fputc('\n', stderr);
signal(SIGALRM, SIG_IGN);
+ fputc('\n', stderr);
}
}
--
1.3.0.rc1
^ permalink raw reply related
* Re: [PATCH 2/2] pack-objects: be incredibly anal about stdio semantics
From: Linus Torvalds @ 2006-04-02 22:58 UTC (permalink / raw)
To: Jason Riedy; +Cc: git
In-Reply-To: <15051.1144015974@lotus.CS.Berkeley.EDU>
On Sun, 2 Apr 2006, Jason Riedy wrote:
>
> If you consider stdio to be a low-level wrapper over syscalls
> that only adds buffering and simple parsing, then passing EINTR
> back to the application is a sensible choice. I wouldn't be
> too surprised if L4, VxWorks, etc. do something similar.
No, returning EINTR is insane, because stdio has to do re-starting of
system calls by hand _anyway_ for the "short read" case.
EINTR really _is_ 100% equivalent to "short read of zero bytes" (that
literally is what it means for a read/write system call - anybody who
tells you otherwise is just crazy).
So any library that handles short reads, but doesn't handle EINTR is by
definition doing something totally idiotic and broken.
Now, I agree that somebody else might be broken too. I would not agree
that it's "acceptable". It's craptastically bad library code.
> Anyone with an older HP/UX care to try these patches? HP/UX
> may not be sane, but I think it may lack SA_RESTART. I don't
> know if stdio calls need restarted, though.
I'd assume that older HPUX is so BSD-based that all signals end up
restarting. That was the BSD signal() semantics, after all.
Linus
^ permalink raw reply
* Re: Multi-headed branches (hydra? :)) for basic patch calculus
From: Sam Vilain @ 2006-04-02 23:15 UTC (permalink / raw)
To: Jakub Narebski; +Cc: git
In-Reply-To: <e0ns59$uq2$1@sea.gmane.org>
Jakub Narebski wrote:
>>However, if there was support for "hydra", or heads that are multiple
>>commit IDs (and necessarily, no blobs in corresponding paths in their
>>trees that are not identical), then you would not need to destroy and
>>recreate this dummy merge head commit to model your patch history in
>>this manner.
>>
>>
>[...]
>
>I'm not sure if "hydras", i.e. multi-commit 'heads' are what would make
>GIT able to use some of Darcs patches calculus ideas. If I understand
>correctly in GIT 'head' (and 'tag') not only identifies commit (commits
>in hydra[1]) but also tree (in hydra it is result of trivial (?) merge).
>
>
Whether it is stored as a procession of trees or as a sequence of
patches does not actually make a difference to a mathematician.
This might not sound right at first, but think that it does not matter
whether you have the number "4" which came after "3" that you store it
as "4 (3 was prior)" or "1+1+1+1". ℕ (the set of natural numbers) is
itself defined by induction, yet this is not important for functions
that deal with natural number elements.
>Wouldn't it be better to somehow represent rather partial ordering between
>commits in history, to have something from Darcs in GIT? Although I'm not
>sure about efficiency, and if we should do detect commits dependency -- or
>in other words partial ordering of commits/patches -- at commit or at
>merge.
>
That is more or less what I proposed, except that the ordering is built
at commit time to pick a best head rather than when you try to pull the
patch, which seems a trivial difference at best.
I think git-commit --hydra is called for.
First we define a "hydra leash", I can think of two definitions:
- a hydra leash is a specially marked commit
- a hydra leash is a commit that has multiple parents, and is
the result of just an index merge of its parents
We must also define the concept of a commit being "against" the head(s)
of a hydra.
With that term in mind, we can make "--hydra" do as follows:
a) find the head(s) of the hydra that the commit is against;
b) apply the commit, and set its parents to those head(s)
c) put the hydra leash back on.
Ideally the leash should not have the previous leash as one of its
parents; that leash was always transient and keeping its history is
perhaps not required, and would break the latter leash detection method
described above.
Instead, git-pull et al should know what to do.
> And if we should remember (or cache) partial ordering/dependency
>info...
>
>[1] I've detected some confusion in this terminology. "Hydra" is
>multi-headed moster, yet in your ptoposal it is one head that has multiple
>bodies... and "octopus" is taken. I guess the terminology should be
>switched (octopus <-> hydra).
>
>
A head is a head because there is only one of it, and it's at the top.
If the leash is transient then it doesn't really exist, and therefore
can't be called a head. So, you look instead at the heads remaining,
and where you expected to see an entity with a single head you see many
heads.
Sam.
^ permalink raw reply
* Re: Default remote branch for local branch
From: Josef Weidendorfer @ 2006-04-02 23:28 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7v7j67k65b.fsf@assigned-by-dhcp.cox.net>
On Sunday 02 April 2006 23:40, you wrote:
> > Let me try to understand this: the general idea is that
> >
> > pull.origin = [<refspec> of] <remote> for <branch>
> >
> > specifies the default action of git-pull if we are on <branch>, ie.
> > a "git pull" then runs "git pull <remote> [<refspec>]".
>
> Not quite.
>
> It will be (if this were a serious proposal -- I am not
> absolutely convinced this is a good idea) more like "git fetch
> <remote>" followed by "git-merge HEAD the-refspec-named-there".
So it is not really a <refspec>, but a <localbranch> which has to
appear in the .git/remotes file on the right side of a refspec on
a Pull line.
Then, I think it is redundant to specify the <remote>, as
this can be detected by looking at the .git/remotes files and
searching for <localbranch>.
> > So the example above, if .git/remotes/linus would contain two
> > refspecs, and you are on the branch of the 2nd refspec, it would
> > do the wrong thing: merge the 1st refspec with current branch.
>
> Sorry I fail to visualize this part.
All I wanted to remark is, that, with
URL: <remote-URL>
Pull: refs/head/master:refs/head/remote1
Pull: refs/head/other:refs/head/remote2
the config
pull.origin = <remote> for refs/head/my-devel-for-remote2
which does not use the [<refspec> of] part, always is bogus:
We get remote1 merged into my-devel-for-remote2 on a git-pull,
which is not what we want.
> > It is also useful to specify this relation if the upstream is purely a
> > local branch, e.g. when branching off a local branch, and you want to
> > pull in changes from the local upstream.
>
> Interesting.
>
> You would need sanity checker for $GIT_DIR/remotes/* files if
> you do this to make sure no local tracking branch is by mistake
> configured to track two remote branches,
Why should this always be a mistake? If you have two developers
doing topic branches for you, you could use this type of config
to make "git-pull" fetching both remotes, and creating an
octopus merge.
And for your "next", you could use this to make "git-pull" merge
both from the stable branch and all topics.
> which is a good change,
The sanity checker probably should be put into a branch attribute
editor which allows to add the config discussed here. And it
should only print a warning when you are trying to add multiple
upstreams.
> but then:
>
> git-pull, without parameter, would:
>
> (1) check if this branch has any local branch it usually
> merges from; if not, do whatever we traditionally
> did (or barf).
Yes. This is simply looking up the config.
We could automatically add such a config when branching off to
specify the upstream of a branch.
And git-clone should set this, too, and: We get rid of the current
"origin" hardcoded special handling.
Optionally, branching <new> off from <old> could add <new> as
topic branch of <old>: Thus, if you are on <old> and do git-pull,
you get <new> merged in.
> (2) if there is a local branch it merges from, check if
> it is a tracking branch for a remote, by looking at
> remotes/* files. It would be nice if we could
> detect tracking branches fed from external svn/cvs
> repositories via svn/cvs-import this way at this
> time.
Good idea. I suppose this needs an entry in .git/remotes like
URL: ...
Type: SVN
> If not, skip the next step and go directly to
> (4).
>
> (3) run git-fetch (or svn/cvs-import) to update the
> tracking branch;
If (1) found multiple branches, do (2)/(3) for every branch.
> (4) merge from that other local branch.
Or for multiple, do an octopus.
> A bigger thing is that I am trying to avoid _requiring_ tracking
> branches.
I don't think you force anything when you add functionality to git-pull
for the config discussed here. Nobody *has* to use this config - it's
a porcelain thingie.
Cogito could use this, too. AFAIK, it has the same origin/master hardcoded
tracking behavior.
> If you are not micromanaging your subsystem
> maintainers, you should not have to care where they were the
> last time you pulled from them. You should be able to just
> pull, examine what the merge brings in, and decide it is worth
> merging. If it isn't, do a "reset", tell them "not good, please
> rework and let me know when you are ready," and forget about it.
>
> If we are going require tracking branches,
I do not understand. Why should we require this?
> we could do a bit
> more with them, like remembering where the tip was when we
> fetched the last time (or the time before that...) and diff with
> that, but the tracking branch heads are not set up to do things
> like that right now -- they are single pointers.
>
> >> Perhaps you are missing a remotes editor command?
>
> Perhaps. Also perhaps a remotes/ sanity checker.
> Something like this:
> ...
Doing this as part of git-branch sounds good.
Josef
^ permalink raw reply
* [PATCH] git-clone: fix handling of upsteram whose HEAD does not point at master.
From: Junio C Hamano @ 2006-04-02 23:29 UTC (permalink / raw)
To: git
Here is a proposed fix to a problem discussed on #git yesterday.
The change also contains an independent fix to deal with new
style symref HEAD copied over HTTP (we incorrectly kept the code
that assumes downloading $GIT_DIR/HEAD using curl/wget would
give us the SHA1, which is not the case anymore), which was what
started me, but it turns out the other transports share the
problem the rest of the patch addresses.
-- >8 --
When cloning from a remote repository that has master, main, and
origin branches _and_ with the HEAD pointing at main branch, we
did quite confused things during clone. So this cleans things
up. The behaviour is a bit different between separate remotes/
layout and the mixed branches layout.
The newer layout with $GIT_DIR/refs/remotes/$origin/, things are
simpler and more transparent:
- remote branches are copied to refs/remotes/$origin/.
- HEAD points at refs/heads/master, which starts at where the
remote HEAD points at.
- $GIT_DIR/remotes/$origin file is set up to fetch all remote
branches, and merge the branch HEAD pointed at at the time of
the cloning.
Everything-in-refs/heads layout was the more confused one, but
cleaned up like this:
- remote branches are copied to refs/heads, but the branch
"$origin" is not copied, instead a copy of the branch the
remote HEAD points at is created there.
- HEAD points at the branch with the same name as the remote
HEAD points at.
- $GIT_DIR/remotes/$origin file is set up to fetch all remote
branches except "$origin", and merge the branch HEAD pointed
at at the time of the cloning.
With this, the remote has master, main and origin, and its HEAD
points at main, you could:
git clone $URL --origin upstream
to use refs/heads/upstream as the tracking branch for remote
"main", and your primary working branch will also be "main".
"master" and "origin" are used to track the corresponding remote
branches and with this setup they do not have any special meaning.
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
git-clone.sh | 51 ++++++++++++++++++++++++++++++++-------------------
1 files changed, 32 insertions(+), 19 deletions(-)
1fa378f885d2d3e391b2924a01f42dc38f87cc21
diff --git a/git-clone.sh b/git-clone.sh
index 823c74b..9cc374e 100755
--- a/git-clone.sh
+++ b/git-clone.sh
@@ -52,7 +52,8 @@ Perhaps git-update-server-info needs to
git-http-fetch -v -a -w "$tname" "$name" "$1/" || exit 1
done <"$clone_tmp/refs"
rm -fr "$clone_tmp"
- http_fetch "$1/HEAD" "$GIT_DIR/REMOTE_HEAD"
+ http_fetch "$1/HEAD" "$GIT_DIR/REMOTE_HEAD" ||
+ rm -f "$GIT_DIR/REMOTE_HEAD"
}
# Read git-fetch-pack -k output and store the remote branches.
@@ -324,7 +325,7 @@ test -d "$GIT_DIR/refs/reference-tmp" &&
if test -f "$GIT_DIR/CLONE_HEAD"
then
- # Figure out where the remote HEAD points at.
+ # Read git-fetch-pack -k output and store the remote branches.
perl -e "$copy_refs" "$GIT_DIR" "$use_separate_remote" "$origin"
fi
@@ -332,22 +333,25 @@ cd "$D" || exit
if test -z "$bare" && test -f "$GIT_DIR/REMOTE_HEAD"
then
- head_sha1=`cat "$GIT_DIR/REMOTE_HEAD"`
# Figure out which remote branch HEAD points at.
case "$use_separate_remote" in
'') remote_top=refs/heads ;;
*) remote_top="refs/remotes/$origin" ;;
esac
- # What to use to track the remote primary branch
- if test -n "$use_separate_remote"
- then
- origin_tracking="remotes/$origin/master"
- else
- origin_tracking="heads/$origin"
- fi
+ head_sha1=`cat "$GIT_DIR/REMOTE_HEAD"`
+ case "$head_sha1" in
+ 'ref: refs/'*)
+ # Uh-oh, the remote told us (http transport done against
+ # new style repository with a symref HEAD).
+ # Ideally we should skip the guesswork but for now
+ # opt for minimum change.
+ head_sha1=`expr "$head_sha1" : 'ref: refs/heads/\(.*\)'`
+ head_sha1=`cat "$GIT_DIR/$remote_top/$head_sha1"`
+ ;;
+ esac
- # The name under $remote_top the remote HEAD seems to point at
+ # The name under $remote_top the remote HEAD seems to point at.
head_points_at=$(
(
echo "master"
@@ -368,23 +372,32 @@ then
)
)
- # Write out remotes/$origin file.
+ # Write out remotes/$origin file, and update our "$head_points_at".
case "$head_points_at" in
?*)
mkdir -p "$GIT_DIR/remotes" &&
+ case "$use_separate_remote" in
+ # With separete-remote, our primary branch is always
+ # at 'master'
+ t) origin_track="$remote_top/$head_points_at"
+ git-update-ref HEAD "$head_sha1" ;;
+ # Otherwise our primary branch is the same as the remote;
+ # we track upstream with $origin.
+ *) origin_track="$remote_top/$origin"
+ git-symbolic-ref HEAD "refs/heads/$head_points_at"
+ git-update-ref "refs/heads/$origin" "$head_sha1" ;;
+ esac &&
echo >"$GIT_DIR/remotes/$origin" \
"URL: $repo
-Pull: refs/heads/$head_points_at:refs/$origin_tracking" &&
- case "$use_separate_remote" in
- t) git-update-ref HEAD "$head_sha1" ;;
- *) git-update-ref "refs/heads/$origin" $(git-rev-parse HEAD) ;;
- esac &&
+Pull: refs/heads/$head_points_at:$origin_track" &&
(cd "$GIT_DIR/$remote_top" && find . -type f -print) |
while read dotslref
do
name=`expr "$dotslref" : './\(.*\)'` &&
- test "$head_points_at" = "$name" ||
- test "$origin" = "$name" ||
+ test "$use_separate_remote" = '' && {
+ test "$head_points_at" = "$name" ||
+ test "$origin" = "$name"
+ } ||
echo "Pull: refs/heads/${name}:$remote_top/${name}"
done >>"$GIT_DIR/remotes/$origin" &&
case "$use_separate_remote" in
--
1.3.0.rc1.gf0c97
^ permalink raw reply related
* Re: [RFH] xdiff shows trivially redundant diff.
From: Linus Torvalds @ 2006-04-03 0:52 UTC (permalink / raw)
To: Davide Libenzi; +Cc: Junio C Hamano, git
In-Reply-To: <Pine.LNX.4.64.0604021454560.30205@alien.or.mcafeemobile.com>
On Sun, 2 Apr 2006, Davide Libenzi wrote:
>
> Yes, it does even vanilla libxdiff ;) It's not a problem though, since it is
> created in xdl_cleanup_records() that tries to do a fast pass over the records
> to try to simplify the real diff operation. In trying to be fast, only hashes
> are compared, and it happens that the hash for "'')" collides with another one
> (try to replace one of the "'')" chars with another one). Why is this not a
> problem? Because what this lead to is only lines to be marked as changed, with
> a probability of about N/2^(8 * sizeof(long) - 1), even though they are not.
> And this happens only during sequential groups of lines changed, that is when
> the hash-colliding line is either at the begin or the end of the run.
Hmm. It's still ugly, though. No possibility to have a "clean up identical
initial and final lines" stage to get rid of extraneous bogus diffs?
I look at diffs a lot, and while this may be rare, if I were to end up
having to wonder what the difference is and it turns out that it's just
due to a libxdelta thing, I'd be a bit irritated and wish it gave me a
proper diff..
Linus
^ permalink raw reply
* Re: [PATCH] Use sigaction and SA_RESTART in read-tree.c; add option in Makefile.
From: Linus Torvalds @ 2006-04-03 1:02 UTC (permalink / raw)
To: Jason Riedy; +Cc: Junio C Hamano, git
In-Reply-To: <17063.1144016974@lotus.CS.Berkeley.EDU>
On Sun, 2 Apr 2006, Jason Riedy wrote:
>
> Might as well ape the sigaction change in read-tree.c to avoid
> the same potential problems.
Looks good. I didn't realize we had the exact same code duplicated. I
guess it's small enough that there isn't a huge win in moving it to some
common file..
Does somebody have access to Solaris to verify that this all actually does
fix it? I obviously believe it will, since this just explains the symptoms
to a tee, but it would still be good to have an actual confirmation by
somebody who has access to a Solaris environment.
> Also add a NO_SA_RESTART option in the Makefile in case someone
> doesn't have SA_RESTART but does restart (maybe older HP/UX?).
> We want the builder to chose this specifically in case the
> system both lacks SA_RESTART and does not restart stdio calls;
> a compat #define in git-compat-utils.h would silently allow
> broken systems.
I do believe that we already require POSIX.2 functionality (regex,
fnmatch, C90 compiler), which implies that git probably wouldn't compile
anyway on things that are _really_ ancient.
I think SA_RESTART was part of the original POSIX.1 specs, so anybody that
doesn't have it is likely to not have a lot of other things we rely on
too. There are other SA_* flags that aren't as standard, but I'd expect
SA_RESTART to be everywhere (or it likely doesn't have sigaction() at
all..).
But hey, I certainly don't have really old HP-UX to test either.
Linus
^ permalink raw reply
* Re: Multi-headed branches (hydra? :)) for basic patch calculus
From: Martin Langhoff @ 2006-04-03 1:15 UTC (permalink / raw)
To: Sam Vilain; +Cc: git
In-Reply-To: <1143950852.21233.23.camel@localhost.localdomain>
On 4/2/06, Sam Vilain <sam@vilain.net> wrote:
> If the plumbing or a porcelain could be smart enough to automatically
> create hydra when patches are not dependent, then many of the benefits
> of patch calculus might come for free, without having to create these
> complicated sounding entities manually.
I'm not too excited about the benefits of patch calculus -- it seems
to break many general usage scenarios(*) and I haven't seen many
examples of those benefits that aren't a bit contrived.
* - For instance: the common practice of having a patch series where
you create a new function and later add calls to it breaks quite
seriously under patch calculus.
Are there common usage scenarios where patch calculus helps more than
it hurts? Preferrably without involving manual recording of
dependencies or full language parsers that guess them.
cheers,
m
^ permalink raw reply
* Re: Multi-headed branches (hydra? :)) for basic patch calculus
From: Sam Vilain @ 2006-04-03 2:09 UTC (permalink / raw)
To: Martin Langhoff; +Cc: git
In-Reply-To: <46a038f90604021815g453c57c9pf95a0f70a62f2fbc@mail.gmail.com>
Martin Langhoff wrote:
>On 4/2/06, Sam Vilain <sam@vilain.net> wrote:
>
>
>>If the plumbing or a porcelain could be smart enough to automatically
>>create hydra when patches are not dependent, then many of the benefits
>>of patch calculus might come for free, without having to create these
>>complicated sounding entities manually.
>>
>>
>
>I'm not too excited about the benefits of patch calculus -- it seems
>to break many general usage scenarios(*) and I haven't seen many
>examples of those benefits that aren't a bit contrived.
>
>* - For instance: the common practice of having a patch series where
>you create a new function and later add calls to it breaks quite
>seriously under patch calculus.
>
>
Perhaps. But forget the darcs implementation for a moment.
When you make a commit, you're labelling it with the previous dependent
commit for this commit to apply.
So, git-commit-hydra would do this calculation based on the files
changed. git-commit would assume the prior commit. You still have both
options available.
>Are there common usage scenarios where patch calculus helps more than
>it hurts? Preferrably without involving manual recording of
>dependencies or full language parsers that guess them.
>
>
I am in the process of converting a live repository as if it had been
committed to in this manner. I'll post results shortly.
Sam.
^ permalink raw reply
* Re: Solaris cloning woes partly diagnosed
From: Linus Torvalds @ 2006-04-03 3:06 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <Pine.LNX.4.64.0604021159110.3050@g5.osdl.org>
On Sun, 2 Apr 2006, Linus Torvalds wrote:
>
> - while (fgets(line, sizeof(line), stdin) != NULL) {
> + for (;;) {
> unsigned char sha1[20];
> +
> + if (!fgets(line, sizeof(line), stdin)) {
> + if (feof(stdin))
> + break;
> + if (!ferror(stdin))
> + die("fgets returned NULL, not EOF, not error!");
> + if (errno == EINTR)
> + continue;
> + die("fgets: %s", strerror(errno));
While it shouldn't actually matter, I just realized that this incredibly
anal sequence isn't actually quite anal enough, sinceit really should have
a "clearerr(stdin)" for the continue case when we ignore the EINTR thing.
Otherwise, some stdio implementation might just decide to continue to
return NULL from fgets(), since the error indicator is technically sticky.
I don't know if they do so, but it's entirely possible.
So I'd almost suggest something like
char *safe_fgets(char *s, int size, FILE *stream)
{
for (;;) {
if (fgets(s, size, stream))
return s;
if (feof(stream))
return NULL;
if (!ferror(stream))
die("fgets returned NULL, not EOF, not error!");
if (errno != EINTR)
die("fgets: %s", strerror(errno));
clearerr(stream);
}
}
which sbould then hopefully work as a sane fgets()-replacement for broken
environments.
(And then we can just do
while (safe_fgets(..))
like normal people again, and not be afraid of strange stdio
implementations).
Linus
^ 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