* Re: Bug: segfault during git-prune
From: Linus Torvalds @ 2007-06-28 22:31 UTC (permalink / raw)
To: Andy Parkins; +Cc: git
In-Reply-To: <200706282321.44244.andyparkins@gmail.com>
On Thu, 28 Jun 2007, Andy Parkins wrote:
>
> I had hoped that git-prune wouldn't be a risk because I have:
>
> * -- * -- * -- * -- * (ffmpeg-svn)
>
> * -- * -- * -- * (libswscale-svn)
Ok. If all subproject branches are also visible in the superproject as
refs, then "git prune" should work fine, and you can apply my patch and it
should just work very naturally: the reachability analysis will find the
subprojects not through the superproject link, but simply through the
direct refs to the subproject.
> > (General rule: never *ever* prune a shared object repository!)
>
> Even when I'm sure that every object of interest is behind a head ref?
So yes, in that case, you're ok.
This is not unlike just having two different repositories sharing the same
object directory: as long as the two different repositories both have the
appropriate refs, pruning is fine. In other words, you can see them as
just independent branches in the same repo.
And in fact, subprojects are obviously very much *designed* to work that
way: a subproject is basically a "different repository". So the basic rule
is that if it would work with totally independent repos, it works with
subprojects.
[ That's all aside from the kind of bug that you found, where some code
that parses the tree structures hadn't been updated for subprojects, of
course ]
Anyway, if that patch works for you, I'd suggest you just pass it on to
Junio (and feel free to add my "Signed-off-by:" on it - but conditional on
you having actually tested it).
Linus
^ permalink raw reply
* [PATCH] Don't fflush(stdout) when it's not helpful
From: Theodore Tso @ 2007-06-28 23:53 UTC (permalink / raw)
To: Jeff King; +Cc: Linus Torvalds, Jim Meyering, git
In-Reply-To: <20070628213451.GB22455@coredump.intra.peff.net>
On Thu, Jun 28, 2007 at 05:34:51PM -0400, Jeff King wrote:
> On top of which, in your patch the type of output trumps the environment
> variable, which seems backwards. In other words, I can't do this:
>
> GIT_FLUSH_EVEN_THOUGH_ITS_A_FILE=1 git-rev-list HEAD >file
> [in another window] tail -f file
>
> I would think an explicit preference from a variable should override any
> guesses.
Good point. Here's a revised patch where GIT_FLUSH=0 and GIT_FLASH=1
trumps any hueristics.
My comments about this making only trivial differences on Linux still
apply (although it does make things slightly more optimal). I suspect
it might make more of a difference on MacOS, but I haven't had time to
benchmark it.
- Ted
---
commit 422becc0f8430d2386ceed92f224a94c9047751e
Author: Theodore Ts'o <tytso@mit.edu>
Date: Thu Jun 28 14:10:58 2007 -0400
Don't fflush(stdout) when it's not helpful
This patch arose from a discussion started by Jim Meyering's patch
whose intention was to provide better diagnostics for failed writes.
Linus proposed a better way to do things, which also had the added
benefit that adding a fflush() to git-log-* operations and incremental
git-blame operations could improve interactive respose time feel, at
the cost of making things a bit slower when we aren't piping the
output to a downstream program.
This patch skips the fflush() calls when stdout is a regular file, or
if the environment variable GIT_FLUSH is set to "0". This latter can
speed up a command such as:
GIT_FLUSH=0 strace -c -f -e write time git-rev-list HEAD | wc -l
a tiny amount.
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
diff --git a/Documentation/git.txt b/Documentation/git.txt
index 20b5b7b..8269148 100644
--- a/Documentation/git.txt
+++ b/Documentation/git.txt
@@ -396,6 +396,16 @@ other
'GIT_PAGER'::
This environment variable overrides `$PAGER`.
+'GIT_FLUSH'::
+ If this environment variable is set to "1", then commands such
+ as git-blame (in incremental mode), git-rev-list, git-log,
+ git-whatchanged, etc., will force a flush of the output stream
+ after each commit-oriented record have been flushed. If this
+ variable is set to "0", the output of these commands will be done
+ using completely buffered I/O. If this environment variable is
+ not set, git will choose buffered or record-oriented flushing
+ based on whether stdout appears to be redirected to a file or not.
+
'GIT_TRACE'::
If this variable is set to "1", "2" or "true" (comparison
is case insensitive), git will print `trace:` messages on
diff --git a/builtin-blame.c b/builtin-blame.c
index f7e2c13..da23a6f 100644
--- a/builtin-blame.c
+++ b/builtin-blame.c
@@ -1459,6 +1459,7 @@ static void found_guilty_entry(struct blame_entry *ent)
printf("boundary\n");
}
write_filename_info(suspect->path);
+ maybe_flush_or_die(stdout, "stdout");
}
}
diff --git a/builtin-rev-list.c b/builtin-rev-list.c
index 813aadf..86db8b0 100644
--- a/builtin-rev-list.c
+++ b/builtin-rev-list.c
@@ -100,7 +100,7 @@ static void show_commit(struct commit *commit)
printf("%s%c", buf, hdr_termination);
free(buf);
}
- fflush(stdout);
+ maybe_flush_or_die(stdout, "stdout");
if (commit->parents) {
free_commit_list(commit->parents);
commit->parents = NULL;
diff --git a/cache.h b/cache.h
index ed83d92..0525c4e 100644
--- a/cache.h
+++ b/cache.h
@@ -532,6 +532,8 @@ extern char git_default_name[MAX_GITNAME];
extern const char *git_commit_encoding;
extern const char *git_log_output_encoding;
+/* IO helper functions */
+extern void maybe_flush_or_die(FILE *, const char *);
extern int copy_fd(int ifd, int ofd);
extern int read_in_full(int fd, void *buf, size_t count);
extern int write_in_full(int fd, const void *buf, size_t count);
diff --git a/log-tree.c b/log-tree.c
index 0cf21bc..ced3f33 100644
--- a/log-tree.c
+++ b/log-tree.c
@@ -408,5 +408,6 @@ int log_tree_commit(struct rev_info *opt, struct commit *commit)
shown = 1;
}
opt->loginfo = NULL;
+ maybe_flush_or_die(stdout, "stdout");
return shown;
}
diff --git a/write_or_die.c b/write_or_die.c
index 5c4bc85..9929a15 100644
--- a/write_or_die.c
+++ b/write_or_die.c
@@ -1,5 +1,47 @@
#include "cache.h"
+/*
+ * Some cases use stdio, but want to flush after the write
+ * to get error handling (and to get better interactive
+ * behaviour - not buffering excessively).
+ *
+ * Of course, if the flush happened within the write itself,
+ * we've already lost the error code, and cannot report it any
+ * more. So we just ignore that case instead (and hope we get
+ * the right error code on the flush).
+ *
+ * If the file handle is stdout, and stdout is a file, then skip the
+ * flush entirely since it's not needed.
+ */
+void maybe_flush_or_die(FILE *f, const char *desc)
+{
+ static int stdout_is_file = -1;
+ struct stat st;
+ char *cp;
+
+ if (f == stdout) {
+ if (stdout_is_file < 0) {
+ cp = getenv("GIT_FLUSH");
+ if (cp)
+ stdout_is_file = (atoi(cp) == 0);
+ else if (getenv("GIT_NEVER_FLUSH_STDOUT") ||
+ ((fstat(fileno(stdout), &st) == 0) &&
+ S_ISREG(st.st_mode)))
+ stdout_is_file = 1;
+ else
+ stdout_is_file = 0;
+ }
+ if (stdout_is_file)
+ return;
+ }
+ if (fflush(f)) {
+ if (errno == EPIPE)
+ exit(0);
+ die("write failure on %s: %s",
+ desc, strerror(errno));
+ }
+}
+
int read_in_full(int fd, void *buf, size_t count)
{
char *p = buf;
^ permalink raw reply related
* Re: [PATCH] git-tag: Fix the main while loop exit condition.
From: Junio C Hamano @ 2007-06-29 0:01 UTC (permalink / raw)
To: Alexandre Vassalotti; +Cc: git
In-Reply-To: <11830498172717-git-send-email-alexandre@peadrop.com>
Thanks.
I think you would need something like this on top if you want to
really fix it, though.
I also suspect that we should error out on:
$ git tag -l foo bar
but that will be left as an exercise to the readers ;-)
diff --git a/git-tag.sh b/git-tag.sh
index bc0d735..48b54a1 100755
--- a/git-tag.sh
+++ b/git-tag.sh
@@ -14,7 +14,8 @@ username=
list=
verify=
LINES=0
-while [ $# -ne 0 ]; do
+while case "$#" in 0) break ;; esac
+do
case "$1" in
-a)
annotate=1
@@ -30,8 +31,9 @@ while [ $# -ne 0 ]; do
shift
;;
-n)
- case $2 in
- -*) LINES=1 # no argument
+ case "$#,$2" in
+ 1,* | *,-*)
+ LINES=1 # no argument
;;
*) shift
LINES=$(expr "$1" : '\([0-9]*\)')
@@ -43,7 +45,14 @@ while [ $# -ne 0 ]; do
-l)
list=1
shift
- PATTERN="$1" # select tags by shell pattern, not re
+ case $# in
+ 0) PATTERN=
+ ;;
+ *)
+ PATTERN="$1" # select tags by shell pattern, not re
+ shift
+ ;;
+ esac
git rev-parse --symbolic --tags | sort |
while read TAG
do
^ permalink raw reply related
* Re: What's cooking in git.git (topics)
From: Junio C Hamano @ 2007-06-29 0:02 UTC (permalink / raw)
To: Matthias Lederhofer; +Cc: git
In-Reply-To: <20070628202321.GA13263@moooo.ath.cx>
Matthias Lederhofer <matled@gmx.net> writes:
> When doing more stuff in receive-pack old hooks might stop working
> break.
>
> For example receive-pack could set up GIT_WORK_TREE with a sane
> default value if a working tree can be found, i.e.
> $ export GIT_WORK_TREE=$(dirname $(pwd))
> if the working tree is in the parent directory
> $ export GIT_WORK_TREE=$(git config core.worktree)
> if core.worktree is set and otherwise GIT_WORK_TREE is not exported.
> This way hooks can just use GIT_WORK_TREE for the working tree if
> they don't need anything special.
Your analysis looks good. Probably we can start without doing
anything to see if anybody screams.
^ permalink raw reply
* Re: [PATCH] git-clone: fetch possibly detached HEAD over dumb http
From: Junio C Hamano @ 2007-06-29 0:02 UTC (permalink / raw)
To: Sven Verdoolaege; +Cc: git, Louis-Noel Pouchet
In-Reply-To: <20070628105208.GA11105@liacs.nl>
Sven Verdoolaege <skimo@liacs.nl> writes:
> git-clone supports cloning from a repo with detached HEAD,
> but if this HEAD is not behind any branch tip then it
> would not have been fetched over dumb http, resulting in a
>
> fatal: Not a valid object name HEAD
>
> Since 928c210a, this would also happen on a http repo
> with a HEAD that is a symbolic link where someone has
> forgotton to run update-server-info.
>
> Signed-off-by: Sven Verdoolaege <skimo@liacs.nl>
Ok. But I think the change regresses when the remote side is
actually on a particular branch, and is using symref to
represent $GIT_DIR/HEAD.
> git-clone.sh | 3 ++-
> 1 files changed, 2 insertions(+), 1 deletions(-)
>
> diff --git a/git-clone.sh b/git-clone.sh
> index bd44ce1..cdbbc20 100755
> --- a/git-clone.sh
> +++ b/git-clone.sh
> @@ -70,7 +70,8 @@ Perhaps git-update-server-info needs to be run there?"
> git-http-fetch $v -a -w "$tname" "$sha1" "$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" &&
> + git-http-fetch $v -a $(cat "$GIT_DIR/REMOTE_HEAD") "$1" ||
> rm -f "$GIT_DIR/REMOTE_HEAD"
> }
At this point, "$GIT_DIR/REMOTE_HEAD" is a copy of HEAD obtained
from the remote site via curl. It can contain:
(1) raw SHA-1 of the tip commit, if the HEAD is detached, or
the repository uses a symlink to represent HEAD, or
(2) "ref: refs/heads/$currentbranch".
You would want to do this extra fetch only in case (1).
I think the additional fetch would fail in case (2), and result
in removal of $GIT_DIR/REMOTE_HEAD.
Hmm?
^ permalink raw reply
* [PATCH] git-mergetool: add support for ediff
From: Sam Vilain @ 2007-06-29 1:00 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, Sam Vilain
There was emerge already but I much prefer this mode.
Signed-off-by: Sam Vilain <sam.vilain@catalyst.net.nz>
---
Documentation/config.txt | 3 ++-
Documentation/git-mergetool.txt | 3 ++-
git-mergetool.sh | 19 ++++++++++++++-----
3 files changed, 18 insertions(+), 7 deletions(-)
diff --git a/Documentation/config.txt b/Documentation/config.txt
index 50503e8..4661e24 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -550,7 +550,8 @@ merge.summary::
merge.tool::
Controls which merge resolution program is used by
gitlink:git-mergetool[l]. Valid values are: "kdiff3", "tkdiff",
- "meld", "xxdiff", "emerge", "vimdiff", "gvimdiff", and "opendiff".
+ "meld", "xxdiff", "emerge", "ediff", "vimdiff", "gvimdiff", and
+ "opendiff".
merge.verbosity::
Controls the amount of output shown by the recursive merge
diff --git a/Documentation/git-mergetool.txt b/Documentation/git-mergetool.txt
index 6c32c6d..1efe6e4 100644
--- a/Documentation/git-mergetool.txt
+++ b/Documentation/git-mergetool.txt
@@ -25,7 +25,8 @@ OPTIONS
-t or --tool=<tool>::
Use the merge resolution program specified by <tool>.
Valid merge tools are:
- kdiff3, tkdiff, meld, xxdiff, emerge, vimdiff, gvimdiff, and opendiff
+ kdiff3, tkdiff, meld, xxdiff, emerge, ediff, vimdiff, gvimdiff,
+ and opendiff
+
If a merge resolution program is not specified, 'git mergetool'
will use the configuration variable merge.tool. If the
diff --git a/git-mergetool.sh b/git-mergetool.sh
index 7b66309..6fda8af 100755
--- a/git-mergetool.sh
+++ b/git-mergetool.sh
@@ -258,6 +258,15 @@ merge_file () {
status=$?
save_backup
;;
+ ediff)
+ if base_present ; then
+ emacs --eval "(ediff-merge-files-with-ancestor \"$LOCAL\" \"$REMOTE\" \"$BASE\" nil \"$path\")"
+ else
+ emacs --eval "(ediff-merge-files \"$LOCAL\" \"$REMOTE\" nil \"$path\")"
+ fi
+ status=$?
+ save_backup
+ ;;
esac
if test "$status" -ne 0; then
echo "merge of $path failed" 1>&2
@@ -299,7 +308,7 @@ done
if test -z "$merge_tool"; then
merge_tool=`git-config merge.tool`
case "$merge_tool" in
- kdiff3 | tkdiff | xxdiff | meld | opendiff | emerge | vimdiff | gvimdiff | "")
+ kdiff3 | tkdiff | xxdiff | meld | opendiff | emerge | ediff | vimdiff | gvimdiff | "")
;; # happy
*)
echo >&2 "git config option merge.tool set to unknown tool: $merge_tool"
@@ -320,15 +329,15 @@ if test -z "$merge_tool" ; then
fi
fi
if echo "${VISUAL:-$EDITOR}" | grep 'emacs' > /dev/null 2>&1; then
- merge_tool_candidates="$merge_tool_candidates emerge"
+ merge_tool_candidates="$merge_tool_candidates emerge ediff"
fi
if echo "${VISUAL:-$EDITOR}" | grep 'vim' > /dev/null 2>&1; then
merge_tool_candidates="$merge_tool_candidates vimdiff"
fi
- merge_tool_candidates="$merge_tool_candidates opendiff emerge vimdiff"
+ merge_tool_candidates="$merge_tool_candidates opendiff ediff emerge vimdiff"
echo "merge tool candidates: $merge_tool_candidates"
for i in $merge_tool_candidates; do
- if test $i = emerge ; then
+ if test $i = emerge || test $i = ediff ; then
cmd=emacs
else
cmd=$i
@@ -351,7 +360,7 @@ case "$merge_tool" in
exit 1
fi
;;
- emerge)
+ emerge|ediff)
if ! type "emacs" > /dev/null 2>&1; then
echo "Emacs is not available"
exit 1
--
1.5.2.1.1131.g3b90
^ permalink raw reply related
* Re: [PATCH] Don't fflush(stdout) when it's not helpful
From: Frank Lichtenheld @ 2007-06-29 1:05 UTC (permalink / raw)
To: Theodore Tso; +Cc: Jeff King, Linus Torvalds, Jim Meyering, git
In-Reply-To: <20070628235319.GD29279@thunk.org>
On Thu, Jun 28, 2007 at 07:53:19PM -0400, Theodore Tso wrote:
> Good point. Here's a revised patch where GIT_FLUSH=0 and GIT_FLASH=1
> trumps any hueristics.
[...]
> + else if (getenv("GIT_NEVER_FLUSH_STDOUT") ||
> + ((fstat(fileno(stdout), &st) == 0) &&
> + S_ISREG(st.st_mode)))
> + stdout_is_file = 1;
> + else
> + stdout_is_file = 0;
> + }
Any particular reason why you still check for GIT_NEVER_FLUSH_STDOUT in
addition to GIT_FLUSH?
Gruesse,
--
Frank Lichtenheld <frank@lichtenheld.de>
www: http://www.djpig.de/
^ permalink raw reply
* Re: [PATCH] git-mergetool: add support for ediff
From: Jason Sewall @ 2007-06-29 1:31 UTC (permalink / raw)
To: Sam Vilain; +Cc: Junio C Hamano, git
In-Reply-To: <11830788163411-git-send-email-sam.vilain@catalyst.net.nz>
On 6/28/07, Sam Vilain <sam.vilain@catalyst.net.nz> wrote:
> There was emerge already but I much prefer this mode.
>
I beat ya to it: http://marc.info/?l=git&m=118301192520295&w=2
But it looks like maybe you did a better job (updated docs, for
example). Other than that, it's almost exactly the same.
Ack.
Jason
P.S.
doing this:
> if echo "${VISUAL:-$EDITOR}" | grep 'emacs' > /dev/null 2>&1; then
> merge_tool_candidates="$merge_tool_candidates emerge ediff"
> fi
and then this
> merge_tool_candidates="$merge_tool_candidates opendiff ediff emerge vimdiff"
makes this
> echo "merge tool candidates: $merge_tool_candidates"
print out emerge and ediff twice, presumably because we're adding it
in for both "visual" emacs and "regular" (i.e. -nw) emacs. I suck at
shell scripts, so I'm probably missing something but what why do we
have all of that testing for emacs + vim if we just add their tools
anyway right afterwards?
^ permalink raw reply
* recursive alternates with git-http-fetch
From: Kumar Gala @ 2007-06-29 2:33 UTC (permalink / raw)
To: git
Is there a reason that git-http-fetch doesn't handle recursive
alternates?
We have the following setup
my powerpc.git has an alternate that looks like:
/pub/scm/linux/kernel/git/paulus/powerpc.git/objects
paulus's has an alternate that looks like:
/pub/scm/linux/kernel/git/torvalds/linux-2.6.git/objects
However git-http-fetch does get the 'torvalds' alternate and ends up
having issues. You get something like the following:
error: Unable to find 060a71d41ad7ccc3214065a182e6f67568420071 under
http://www.kernel.org/pub/scm/linux/kernel/git/galak/powerpc.git/
Cannot obtain needed blob 060a71d41ad7ccc3214065a182e6f67568420071
while processing commit 7b7a57c77dccddd84b6aa02a38deee7ad97c977a.
(Note, I've set my alternates to point to both paulus/powerpc.git and
torvalds/linux-2.6.git to make things work for people).
- k
^ permalink raw reply
* Re: [PATCH] Don't fflush(stdout) when it's not helpful
From: Theodore Tso @ 2007-06-29 3:48 UTC (permalink / raw)
To: Frank Lichtenheld; +Cc: Jeff King, Linus Torvalds, Jim Meyering, git
In-Reply-To: <20070629010507.GL12721@planck.djpig.de>
On Fri, Jun 29, 2007 at 03:05:08AM +0200, Frank Lichtenheld wrote:
> Any particular reason why you still check for GIT_NEVER_FLUSH_STDOUT in
> addition to GIT_FLUSH?
Yup, I forgot to remove it. :-)
- Ted
---
commit 473065f89f27de476d12d774141009cd4f2600c4
Author: Theodore Ts'o <tytso@mit.edu>
Date: Thu Jun 28 14:10:58 2007 -0400
Don't fflush(stdout) when it's not helpful
This patch arose from a discussion started by Jim Meyering's patch
whose intention was to provide better diagnostics for failed writes.
Linus proposed a better way to do things, which also had the added
benefit that adding a fflush() to git-log-* operations and incremental
git-blame operations could improve interactive respose time feel, at
the cost of making things a bit slower when we aren't piping the
output to a downstream program.
This patch skips the fflush() calls when stdout is a regular file, or
if the environment variable GIT_FLUSH is set to "0". This latter can
speed up a command such as:
GIT_FLUSH=0 strace -c -f -e write time git-rev-list HEAD | wc -l
a tiny amount.
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
diff --git a/Documentation/git.txt b/Documentation/git.txt
index 20b5b7b..8269148 100644
--- a/Documentation/git.txt
+++ b/Documentation/git.txt
@@ -396,6 +396,16 @@ other
'GIT_PAGER'::
This environment variable overrides `$PAGER`.
+'GIT_FLUSH'::
+ If this environment variable is set to "1", then commands such
+ as git-blame (in incremental mode), git-rev-list, git-log,
+ git-whatchanged, etc., will force a flush of the output stream
+ after each commit-oriented record have been flushed. If this
+ variable is set to "0", the output of these commands will be done
+ using completely buffered I/O. If this environment variable is
+ not set, git will choose buffered or record-oriented flushing
+ based on whether stdout appears to be redirected to a file or not.
+
'GIT_TRACE'::
If this variable is set to "1", "2" or "true" (comparison
is case insensitive), git will print `trace:` messages on
diff --git a/builtin-blame.c b/builtin-blame.c
index f7e2c13..da23a6f 100644
--- a/builtin-blame.c
+++ b/builtin-blame.c
@@ -1459,6 +1459,7 @@ static void found_guilty_entry(struct blame_entry *ent)
printf("boundary\n");
}
write_filename_info(suspect->path);
+ maybe_flush_or_die(stdout, "stdout");
}
}
diff --git a/builtin-rev-list.c b/builtin-rev-list.c
index 813aadf..86db8b0 100644
--- a/builtin-rev-list.c
+++ b/builtin-rev-list.c
@@ -100,7 +100,7 @@ static void show_commit(struct commit *commit)
printf("%s%c", buf, hdr_termination);
free(buf);
}
- fflush(stdout);
+ maybe_flush_or_die(stdout, "stdout");
if (commit->parents) {
free_commit_list(commit->parents);
commit->parents = NULL;
diff --git a/cache.h b/cache.h
index ed83d92..0525c4e 100644
--- a/cache.h
+++ b/cache.h
@@ -532,6 +532,8 @@ extern char git_default_name[MAX_GITNAME];
extern const char *git_commit_encoding;
extern const char *git_log_output_encoding;
+/* IO helper functions */
+extern void maybe_flush_or_die(FILE *, const char *);
extern int copy_fd(int ifd, int ofd);
extern int read_in_full(int fd, void *buf, size_t count);
extern int write_in_full(int fd, const void *buf, size_t count);
diff --git a/log-tree.c b/log-tree.c
index 0cf21bc..ced3f33 100644
--- a/log-tree.c
+++ b/log-tree.c
@@ -408,5 +408,6 @@ int log_tree_commit(struct rev_info *opt, struct commit *commit)
shown = 1;
}
opt->loginfo = NULL;
+ maybe_flush_or_die(stdout, "stdout");
return shown;
}
diff --git a/write_or_die.c b/write_or_die.c
index 5c4bc85..3fd7c5c 100644
--- a/write_or_die.c
+++ b/write_or_die.c
@@ -1,5 +1,46 @@
#include "cache.h"
+/*
+ * Some cases use stdio, but want to flush after the write
+ * to get error handling (and to get better interactive
+ * behaviour - not buffering excessively).
+ *
+ * Of course, if the flush happened within the write itself,
+ * we've already lost the error code, and cannot report it any
+ * more. So we just ignore that case instead (and hope we get
+ * the right error code on the flush).
+ *
+ * If the file handle is stdout, and stdout is a file, then skip the
+ * flush entirely since it's not needed.
+ */
+void maybe_flush_or_die(FILE *f, const char *desc)
+{
+ static int stdout_is_file = -1;
+ struct stat st;
+ char *cp;
+
+ if (f == stdout) {
+ if (stdout_is_file < 0) {
+ cp = getenv("GIT_FLUSH");
+ if (cp)
+ stdout_is_file = (atoi(cp) == 0);
+ else if ((fstat(fileno(stdout), &st) == 0) &&
+ S_ISREG(st.st_mode))
+ stdout_is_file = 1;
+ else
+ stdout_is_file = 0;
+ }
+ if (stdout_is_file)
+ return;
+ }
+ if (fflush(f)) {
+ if (errno == EPIPE)
+ exit(0);
+ die("write failure on %s: %s",
+ desc, strerror(errno));
+ }
+}
+
int read_in_full(int fd, void *buf, size_t count)
{
char *p = buf;
^ permalink raw reply related
* Re: [PATCH] git-mergetool: add support for ediff
From: Theodore Tso @ 2007-06-29 4:03 UTC (permalink / raw)
To: Jason Sewall; +Cc: Sam Vilain, Junio C Hamano, git
In-Reply-To: <31e9dd080706281831vbe24597i9b6a5f6f6db6fec8@mail.gmail.com>
On Thu, Jun 28, 2007 at 06:31:50PM -0700, Jason Sewall wrote:
> > echo "merge tool candidates: $merge_tool_candidates"
This was a debugging echo that slipped by; I had never intended for it
to be kept.
> print out emerge and ediff twice, presumably because we're adding it
> in for both "visual" emacs and "regular" (i.e. -nw) emacs. I suck at
> shell scripts, so I'm probably missing something but what why do we
> have all of that testing for emacs + vim if we just add their tools
> anyway right afterwards?
Some things get added twice but in a different order because the
search order matters. But in terms of adding emerge and ediff, yes,
there's no point, since they always get added in the same order.
I'll have to look at the two and see why people like one over the
other, and then we'll have to pick which one should be the default.
Although as I've said, past a certain point people should just put
their personal preference in .gitconfig.
- Ted
^ permalink raw reply
* Re: [PATCH] git-cvsimport: force checkout of working tree after initial import
From: Junio C Hamano @ 2007-06-29 4:41 UTC (permalink / raw)
To: Gerrit Pape; +Cc: git
In-Reply-To: <20070628111207.28276.qmail@a0ecab5969a5b1.315fe32.mid.smarden.org>
Thanks.
^ permalink raw reply
* Re: [PATCH] Add test-script for git-tag
From: Junio C Hamano @ 2007-06-29 4:41 UTC (permalink / raw)
To: Carlos Rica; +Cc: git, Johannes.Schindelin, krh
In-Reply-To: <46841568.8070203@gmail.com>
Thanks.
^ permalink raw reply
* Applying patches in a directory that isn't a repository
From: Geoff Russell @ 2007-06-29 6:07 UTC (permalink / raw)
To: git
In-Reply-To: <93c3eada0706280153w1898be80u7785ef2b2b1dd188@mail.gmail.com>
Hi,
I'm trying to use git for software distribution.
The system is a directory of about 450mb comprising binaries,
datafiles and scripts. The
full repository is about 1.1gb. The users don't really need .git
except when we
login to pull upgrades for them. It would be nicer not to have the
.git directory and
just distribute patches which we would apply for our users.
But "git am" needs (AFAIK) a full repository. Is there a way to apply
a patch without
.git being present?
I can see the advantages of our users having the full repository, so maybe
we should just distribute by DVD (currently we use CDs) and forget
about it, but for
download purposes, 450mb is nicer than 1.1gb.
Cheers,
Geoff Russell
^ permalink raw reply
* Re: Applying patches in a directory that isn't a repository
From: Junio C Hamano @ 2007-06-29 6:29 UTC (permalink / raw)
To: geoffrey.russell; +Cc: git
In-Reply-To: <93c3eada0706282307i7a22bd27w6ca10839d36ea4eb@mail.gmail.com>
"Geoff Russell" <geoffrey.russell@gmail.com> writes:
> But "git am" needs (AFAIK) a full repository. Is there a way to apply
> a patch without
> .git being present?
If the recipient does not have a git repository, there is no
point using "git am", as it is about making commits out of
e-mails.
git-apply acts as a plain "patch applicator".
Another possibility is to use "GNU patch", with -p1. That
historically has been how the patches were applied, and the
output from git-diff is designed to be very compatible with it,
unless you choose to use more advanced features that "GNU patch"
does not support yet (notably, renames, mode changes, and binary
diffs).
^ permalink raw reply
* Re: [PATCH] Ignore end-of-line style when computing similarity score for rename detection
From: Junio C Hamano @ 2007-06-29 6:34 UTC (permalink / raw)
To: Shawn O. Pearce; +Cc: Steven Grimm, git
In-Reply-To: <20070628061821.GM32223@spearce.org>
"Shawn O. Pearce" <spearce@spearce.org> writes:
> Actually even better if you can also run the in/out filter things.
> I'm thinking of say an XML file that has had whitespace formatting
> changes, but whose XSD and processors ignore unnecessary whitespace.
> Be nice if the rename detection actually was able to canonicalize
> both files before detecting the rename, assuming both files had a
> canonicalizer input filter defined that does that...
This certainly is tempting, but I suspect that should be left to
later rounds. I suspect that it would introduce a concept of
two different kinds of diffs, one to be mechanically processed
(i.e. use in merge with "git-merge-recursive", and apply with
"git-am"), and another to be inspected by humans to understand.
It often may be useful to munge the input for the latter case,
even though the output from comparing munged input files may not
be readily usable for mechanical application.
Which is not a bad thing per-se, but needs to be done carefully.
A replacement set for Steven to comment on follows.
[PATCH 1/4] diffcore_count_changes: pass diffcore_filespec
[PATCH 2/4] diffcore_filespec: add is_binary
[PATCH 3/4] diffcore-delta.c: update the comment on the algorithm.
[PATCH 4/4] diffcore-delta.c: Ignore CR in CRLF for text files
^ permalink raw reply
* [PATCH 1/4] diffcore_count_changes: pass diffcore_filespec
From: Junio C Hamano @ 2007-06-29 6:35 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano
In-Reply-To: <7v3b0bi88r.fsf@assigned-by-dhcp.pobox.com>
We may want to use richer information on the data we are dealing
with in this function, so instead of passing a buffer address
and length, just pass the diffcore_filespec structure. Existing
callers always call this function with parameters taken from a
filespec anyway, so there is no functionality changes.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
diffcore-break.c | 3 +--
diffcore-delta.c | 8 ++++----
diffcore-rename.c | 3 +--
diffcore.h | 4 ++--
4 files changed, 8 insertions(+), 10 deletions(-)
diff --git a/diffcore-break.c b/diffcore-break.c
index 9c19b8c..ae8a7d0 100644
--- a/diffcore-break.c
+++ b/diffcore-break.c
@@ -66,8 +66,7 @@ static int should_break(struct diff_filespec *src,
if (base_size < MINIMUM_BREAK_SIZE)
return 0; /* we do not break too small filepair */
- if (diffcore_count_changes(src->data, src->size,
- dst->data, dst->size,
+ if (diffcore_count_changes(src, dst,
NULL, NULL,
0,
&src_copied, &literal_added))
diff --git a/diffcore-delta.c b/diffcore-delta.c
index 7338a40..0e1fae7 100644
--- a/diffcore-delta.c
+++ b/diffcore-delta.c
@@ -156,8 +156,8 @@ static struct spanhash_top *hash_chars(unsigned char *buf, unsigned int sz)
return hash;
}
-int diffcore_count_changes(void *src, unsigned long src_size,
- void *dst, unsigned long dst_size,
+int diffcore_count_changes(struct diff_filespec *src,
+ struct diff_filespec *dst,
void **src_count_p,
void **dst_count_p,
unsigned long delta_limit,
@@ -172,14 +172,14 @@ int diffcore_count_changes(void *src, unsigned long src_size,
if (src_count_p)
src_count = *src_count_p;
if (!src_count) {
- src_count = hash_chars(src, src_size);
+ src_count = hash_chars(src->data, src->size);
if (src_count_p)
*src_count_p = src_count;
}
if (dst_count_p)
dst_count = *dst_count_p;
if (!dst_count) {
- dst_count = hash_chars(dst, dst_size);
+ dst_count = hash_chars(dst->data, dst->size);
if (dst_count_p)
*dst_count_p = dst_count;
}
diff --git a/diffcore-rename.c b/diffcore-rename.c
index 79c984c..cb22736 100644
--- a/diffcore-rename.c
+++ b/diffcore-rename.c
@@ -189,8 +189,7 @@ static int estimate_similarity(struct diff_filespec *src,
delta_limit = (unsigned long)
(base_size * (MAX_SCORE-minimum_score) / MAX_SCORE);
- if (diffcore_count_changes(src->data, src->size,
- dst->data, dst->size,
+ if (diffcore_count_changes(src, dst,
&src->cnt_data, &dst->cnt_data,
delta_limit,
&src_copied, &literal_added))
diff --git a/diffcore.h b/diffcore.h
index 7b9294e..990dec5 100644
--- a/diffcore.h
+++ b/diffcore.h
@@ -103,8 +103,8 @@ void diff_debug_queue(const char *, struct diff_queue_struct *);
#define diff_debug_queue(a,b) do {} while(0)
#endif
-extern int diffcore_count_changes(void *src, unsigned long src_size,
- void *dst, unsigned long dst_size,
+extern int diffcore_count_changes(struct diff_filespec *src,
+ struct diff_filespec *dst,
void **src_count_p,
void **dst_count_p,
unsigned long delta_limit,
--
1.5.2.2.1414.g1e7d9
^ permalink raw reply related
* [PATCH 2/4] diffcore_filespec: add is_binary
From: Junio C Hamano @ 2007-06-29 6:35 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano
In-Reply-To: <7v3b0bi88r.fsf@assigned-by-dhcp.pobox.com>
diffcore-break and diffcore-rename would want to behave slightly
differently depending on the binary-ness of the data, so add one
bit to the filespec, as the structure is now passed down to
diffcore_count_changes() function.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
diff.c | 16 ++++++++++++++++
diffcore.h | 1 +
2 files changed, 17 insertions(+), 0 deletions(-)
diff --git a/diff.c b/diff.c
index 9938969..74c1198 100644
--- a/diff.c
+++ b/diff.c
@@ -3005,6 +3005,22 @@ void diffcore_std(struct diff_options *options)
{
if (options->quiet)
return;
+
+ /*
+ * break/rename count similarity differently depending on
+ * the binary-ness.
+ */
+ if ((options->break_opt != -1) || (options->detect_rename)) {
+ struct diff_queue_struct *q = &diff_queued_diff;
+ int i;
+
+ for (i = 0; i < q->nr; i++) {
+ struct diff_filepair *p = q->queue[i];
+ p->one->is_binary = file_is_binary(p->one);
+ p->two->is_binary = file_is_binary(p->two);
+ }
+ }
+
if (options->break_opt != -1)
diffcore_break(options->break_opt);
if (options->detect_rename)
diff --git a/diffcore.h b/diffcore.h
index 990dec5..0c8abb5 100644
--- a/diffcore.h
+++ b/diffcore.h
@@ -37,6 +37,7 @@ struct diff_filespec {
#define DIFF_FILE_VALID(spec) (((spec)->mode) != 0)
unsigned should_free : 1; /* data should be free()'ed */
unsigned should_munmap : 1; /* data should be munmap()'ed */
+ unsigned is_binary : 1; /* data should be considered "binary" */
};
extern struct diff_filespec *alloc_filespec(const char *);
--
1.5.2.2.1414.g1e7d9
^ permalink raw reply related
* [PATCH 3/4] diffcore-delta.c: update the comment on the algorithm.
From: Junio C Hamano @ 2007-06-29 6:36 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano
In-Reply-To: <7v3b0bi88r.fsf@assigned-by-dhcp.pobox.com>
The comment at the top of the file described an old algorithm
that was neutral to text/binary differences (it hashed sliding
window of N-byte sequences and counted overlaps), but long time
ago we switched to a new heuristics that are more suitable for
line oriented (read: text) files that are much faster.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
diffcore-delta.c | 21 +++++++++------------
1 files changed, 9 insertions(+), 12 deletions(-)
diff --git a/diffcore-delta.c b/diffcore-delta.c
index 0e1fae7..7116df0 100644
--- a/diffcore-delta.c
+++ b/diffcore-delta.c
@@ -5,23 +5,20 @@
/*
* Idea here is very simple.
*
- * We have total of (sz-N+1) N-byte overlapping sequences in buf whose
- * size is sz. If the same N-byte sequence appears in both source and
- * destination, we say the byte that starts that sequence is shared
- * between them (i.e. copied from source to destination).
+ * Almost all data we are interested in are text, but sometimes we have
+ * to deal with binary data. So we cut them into chunks delimited by
+ * LF byte, or 64-byte sequence, whichever comes first, and hash them.
*
- * For each possible N-byte sequence, if the source buffer has more
- * instances of it than the destination buffer, that means the
- * difference are the number of bytes not copied from source to
- * destination. If the counts are the same, everything was copied
- * from source to destination. If the destination has more,
- * everything was copied, and destination added more.
+ * For those chunks, if the source buffer has more instances of it
+ * than the destination buffer, that means the difference are the
+ * number of bytes not copied from source to destination. If the
+ * counts are the same, everything was copied from source to
+ * destination. If the destination has more, everything was copied,
+ * and destination added more.
*
* We are doing an approximation so we do not really have to waste
* memory by actually storing the sequence. We just hash them into
* somewhere around 2^16 hashbuckets and count the occurrences.
- *
- * The length of the sequence is arbitrarily set to 8 for now.
*/
/* Wild guess at the initial hash size */
--
1.5.2.2.1414.g1e7d9
^ permalink raw reply related
* [PATCH 4/4] diffcore-delta.c: Ignore CR in CRLF for text files
From: Junio C Hamano @ 2007-06-29 6:36 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano
In-Reply-To: <7v3b0bi88r.fsf@assigned-by-dhcp.pobox.com>
This ignores CR byte in CRLF sequence in text file when
computing similarity of two blobs.
Usually this should not matter as nobody sane would be checking
in a file with CRLF line endings to the repository (they would
use autocrlf so that the repository copy would have LF line
endings).
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
diffcore-delta.c | 14 +++++++++++---
t/t0022-crlf-rename.sh | 33 +++++++++++++++++++++++++++++++++
2 files changed, 44 insertions(+), 3 deletions(-)
create mode 100755 t/t0022-crlf-rename.sh
diff --git a/diffcore-delta.c b/diffcore-delta.c
index 7116df0..a038b16 100644
--- a/diffcore-delta.c
+++ b/diffcore-delta.c
@@ -122,11 +122,14 @@ static struct spanhash_top *add_spanhash(struct spanhash_top *top,
}
}
-static struct spanhash_top *hash_chars(unsigned char *buf, unsigned int sz)
+static struct spanhash_top *hash_chars(struct diff_filespec *one)
{
int i, n;
unsigned int accum1, accum2, hashval;
struct spanhash_top *hash;
+ unsigned char *buf = one->data;
+ unsigned int sz = one->size;
+ int is_text = !one->is_binary;
i = INITIAL_HASH_SIZE;
hash = xmalloc(sizeof(*hash) + sizeof(struct spanhash) * (1<<i));
@@ -140,6 +143,11 @@ static struct spanhash_top *hash_chars(unsigned char *buf, unsigned int sz)
unsigned int c = *buf++;
unsigned int old_1 = accum1;
sz--;
+
+ /* Ignore CR in CRLF sequence if text */
+ if (is_text && c == '\r' && sz && *buf == '\n')
+ continue;
+
accum1 = (accum1 << 7) ^ (accum2 >> 25);
accum2 = (accum2 << 7) ^ (old_1 >> 25);
accum1 += c;
@@ -169,14 +177,14 @@ int diffcore_count_changes(struct diff_filespec *src,
if (src_count_p)
src_count = *src_count_p;
if (!src_count) {
- src_count = hash_chars(src->data, src->size);
+ src_count = hash_chars(src);
if (src_count_p)
*src_count_p = src_count;
}
if (dst_count_p)
dst_count = *dst_count_p;
if (!dst_count) {
- dst_count = hash_chars(dst->data, dst->size);
+ dst_count = hash_chars(dst);
if (dst_count_p)
*dst_count_p = dst_count;
}
diff --git a/t/t0022-crlf-rename.sh b/t/t0022-crlf-rename.sh
new file mode 100755
index 0000000..430a1d1
--- /dev/null
+++ b/t/t0022-crlf-rename.sh
@@ -0,0 +1,33 @@
+#!/bin/sh
+
+test_description='ignore CR in CRLF sequence while computing similiarity'
+
+. ./test-lib.sh
+
+test_expect_success setup '
+
+ cat ../t0022-crlf-rename.sh >sample &&
+ git add sample &&
+
+ test_tick &&
+ git commit -m Initial &&
+
+ sed -e "s/\$/
/" ../t0022-crlf-rename.sh >elpmas &&
+ git add elpmas &&
+ rm -f sample &&
+
+ test_tick &&
+ git commit -a -m Second
+
+'
+
+test_expect_success 'diff -M' '
+
+ git diff-tree -M -r --name-status HEAD^ HEAD |
+ sed -e "s/R[0-9]*/RNUM/" >actual &&
+ echo "RNUM sample elpmas" >expect &&
+ diff -u expect actual
+
+'
+
+test_done
--
1.5.2.2.1414.g1e7d9
^ permalink raw reply related
* Re: [PATCH] Don't fflush(stdout) when it's not helpful
From: Jeff King @ 2007-06-29 6:38 UTC (permalink / raw)
To: Theodore Tso; +Cc: Frank Lichtenheld, Linus Torvalds, Jim Meyering, git
In-Reply-To: <20070629034838.GF29279@thunk.org>
On Thu, Jun 28, 2007 at 11:48:38PM -0400, Theodore Tso wrote:
> +void maybe_flush_or_die(FILE *f, const char *desc)
> +{
> + static int stdout_is_file = -1;
> + struct stat st;
> + char *cp;
> +
> + if (f == stdout) {
> + if (stdout_is_file < 0) {
> + cp = getenv("GIT_FLUSH");
> + if (cp)
> + stdout_is_file = (atoi(cp) == 0);
> + else if ((fstat(fileno(stdout), &st) == 0) &&
> + S_ISREG(st.st_mode))
> + stdout_is_file = 1;
> + else
> + stdout_is_file = 0;
> + }
> + if (stdout_is_file)
> + return;
> + }
Looks much better to me, but I have one minor nit: stdout_is_file is a
poor name, since it can mean either that stdout is a file, or that
flushing was explicitly turned off. Naming it something like
stdout_wants_flush would make much more sense. Though it's not a huge
deal since the function is fairly short, I think it makes things a
little easier to read (I had to double-check the negation on atoi(cp) ==
0 before I convinced myself the code was correct).
-Peff
^ permalink raw reply
* Re: [PATCH] git add: respect core.filemode even with unmerged entriesin the index
From: Johannes Sixt @ 2007-06-29 6:57 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: git
In-Reply-To: <Pine.LNX.4.64.0706281653260.4438@racer.site>
Johannes Schindelin wrote:
>
> When a merge left unmerged entries, git add failed to pick up the
> file mode from the index, when core.filemode == 0.
>
> Noticed by Johannes Sixt.
>
> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
> ---
>
> On Thu, 28 Jun 2007, Johannes Sixt wrote:
>
> > Johannes Sixt wrote:
> >
> > The deficiency is not in merge-recursive, but in 'git add'. The
> > problem is that after a conflicted merge of an executable file
> > 'git add' loses the +x bit even if core.filemode=false.
>
> How's that?
That's fine, thanks.
It covers the most common case that all three stages are in the index.
However, if only two stages are present, the file mode is still taken
from the file instead of from the index. As that easy to solve (at least
for the unambiguous case)?
-- Hannes
^ permalink raw reply
* Re: [PATCH] Don't fflush(stdout) when it's not helpful
From: Junio C Hamano @ 2007-06-29 7:07 UTC (permalink / raw)
To: Jeff King
Cc: Theodore Tso, Frank Lichtenheld, Linus Torvalds, Jim Meyering,
git
In-Reply-To: <20070629063819.GA23138@coredump.intra.peff.net>
Jeff King <peff@peff.net> writes:
> On Thu, Jun 28, 2007 at 11:48:38PM -0400, Theodore Tso wrote:
>
>> +void maybe_flush_or_die(FILE *f, const char *desc)
>> +{
>> + static int stdout_is_file = -1;
>> + struct stat st;
>> + char *cp;
>> +
>> + if (f == stdout) {
>> + if (stdout_is_file < 0) {
>> + cp = getenv("GIT_FLUSH");
>> + if (cp)
>> + stdout_is_file = (atoi(cp) == 0);
>> + else if ((fstat(fileno(stdout), &st) == 0) &&
>> + S_ISREG(st.st_mode))
>> + stdout_is_file = 1;
>> ...
>
> Looks much better to me, but I have one minor nit: stdout_is_file is a
> poor name,...
Thanks for bringing it up, as I had the same "Huh?" moment.
I would probably call that simply "do_not_flush". Or name the
variable "flush_stdout" and swap all the logic.
if (f == stdout) {
if (flush_stdout < 0) {
cp = getenv("GIT_FLUSH_STDOUT");
if (cp)
flush_stdout = !!atoi(cp);
else if ((fstat(fileno(stdout), &st) == 0) &&
!S_ISREG(st.st_mode))
flush_stdout = 0;
else
flush_stdout = 1;
}
if (!flush_stdout)
return;
}
^ permalink raw reply
* Re: Darcs
From: Bu Bacoo @ 2007-06-29 7:13 UTC (permalink / raw)
To: Josh Triplett; +Cc: git
In-Reply-To: <46830E60.2090806@freedesktop.org>
On 6/28/07, Josh Triplett <josh@freedesktop.org> wrote:
> Linus Torvalds wrote:
> > On Sun, 24 Jun 2007, Bu Bacoo wrote:
> >> What do you think about darcs?
> >>
> >> There was a lot written/spoken about morons and stupidos around
> >> thinking in cvs / svn, etc... (what would be the words for dudes
> >> around vss ....).
> >
> > Ahh, a chance to flame! I will never back down from such a challenge!
> >
> > Darcs is .. umm .. ehh..
>
> Wow. You completely skipped the opportunity to flame Visual Source Safe (vss)
> users. :) Too easy?
>
> - Josh Triplett
>
>
>
>
We've been talking about version control systems, not version killers.... ;)
^ permalink raw reply
* Alternative git logo and favicon
From: Henrik Nyh @ 2007-06-29 7:54 UTC (permalink / raw)
To: git
I came up with an alternative logo/favicon to use with my gitweb:
http://henrik.nyh.se/2007/06/alternative-git-logo-and-favicon.
Thought I'd sent it to the list in case someone else likes them.
^ 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