* Re: [PATCH] Supplant the "while case ... break ;; esac" idiom
From: Junio C Hamano @ 2007-09-25 6:29 UTC (permalink / raw)
To: David Kastrup; +Cc: git
In-Reply-To: <85hcljgtlr.fsf@lola.goethe.zz>
David Kastrup <dak@gnu.org> writes:
> As a completely irrelevant side note: the autoconf documentation
> mentions that "false" is more portable than "true" since calling it
> returns a non-zero exit status even when it is not installed or
> built-in.
Ah, I like that ;-) It is obvious when you think about it, and
it is so true but in a very twisted way...
^ permalink raw reply
* Re: [PATCH] Add ability to specify SMTP server port when using git-send-email.
From: Junio C Hamano @ 2007-09-25 6:24 UTC (permalink / raw)
To: Glenn Rempe; +Cc: git
In-Reply-To: <1190666058-10969-1-git-send-email-glenn@rempe.us>
Glenn Rempe <glenn@rempe.us> writes:
> git-send-email.perl | 48 +++++++++++++++++++++++++++++++++++++-----------
> 1 files changed, 37 insertions(+), 11 deletions(-)
>
> diff --git a/git-send-email.perl b/git-send-email.perl
> index 4031e86..7c9c302 100755
> --- a/git-send-email.perl
> +++ b/git-send-email.perl
> @@ -79,6 +79,10 @@ Options:
> --smtp-server If set, specifies the outgoing SMTP server to use.
> Defaults to localhost.
>
> + --smtp-server-port If set, specifies the port on the outgoing SMTP
> + server to use. Defaults to port 25 unless --smtp-ssl is set in
> + which case it will default to port 465.
> +
This paragraph look inconsistent with different indentation
for second and subsequent lines.
> @@ -375,6 +381,14 @@ if (!defined $smtp_server) {
> $smtp_server ||= 'localhost'; # could be 127.0.0.1, too... *shrug*
> }
>
> +if (!defined $smtp_server_port) {
> + if ($smtp_ssl) {
> + $smtp_server_port = 465 # SSL port
> + } else {
> + $smtp_server_port = 25 # Non-SSL port
> + }
> +}
> +
> if ($compose) {
> # Note that this does not need to be secure, but we will make a small
> # effort to have it be unique
> @@ -604,20 +618,32 @@ X-Mailer: git-send-email $gitversion
> } else {
> if ($smtp_ssl) {
> require Net::SMTP::SSL;
> - $smtp ||= Net::SMTP::SSL->new( $smtp_server, Port => 465 );
> + $smtp ||= Net::SMTP::SSL->new( $smtp_server, Port => $smtp_server_port );
> }
> else {
> require Net::SMTP;
> - $smtp ||= Net::SMTP->new( $smtp_server );
> + $smtp ||= Net::SMTP->new( $smtp_server . ":" . $smtp_server_port );
> }
This change suggests that, although undocumented, existing users
could have already been using
--smtp-server=smtp.myisp.com:26
to specify a nonstandard port, and this patch, while bringing in
the support for a nonstandard port as an official feature, would
break such a setup. I wonder how real the issue is, and if we
can work it around easily. For example,
(1) drop the "default to 25 for smtp if undefined" part we saw
earlier;
(2) redo this part as
if ($smtp_ssl) {
... as you have it ...
} else {
require Net::SMTP;
$smtp ||= Net::SMTP->new((defined $smtp_server_port) ?
"$smtp_server:$smtp_server_port" :
$smtp_server);
}
> - $smtp->auth( $smtp_authuser, $smtp_authpass )
> - or die $smtp->message if (defined $smtp_authuser);
> ...
> +
> + # we'll get an ugly error if $smtp was undefined above.
> + # If so we'll catch it and present something friendlier.
> + if ($smtp) {
> +
> + if ((defined $smtp_authuser) && (defined $smtp_authpass)) {
> + $smtp->auth( $smtp_authuser, $smtp_authpass ) or die $smtp->message;
> + }
> + ...
> + } else {
> + die "Unable to initialize SMTP properly. Is there something wrong with your config?";
> + }
I'd prefer the check done the opposite order, like
if (!$smtp) {
die ...
}
without an else clause.
^ permalink raw reply
* Re: [PATCH] Supplant the "while case ... break ;; esac" idiom
From: David Kastrup @ 2007-09-25 6:13 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7vodfr8wts.fsf@gitster.siamese.dyndns.org>
Junio C Hamano <gitster@pobox.com> writes:
> David Kastrup <dak@gnu.org> writes:
>
>> I am somewhat taken aback that a commit message considered offensive
>> (though I still have a problem understanding why and certainly did not
>> intend this) has been committed into master without giving me a chance
>> to amend it.
>
> Heh, that's simple. I changed my mind ;-)
>
> When A and B test for preconditions, and C, D, and E are
> operations with error reports as their side effects, we can
> write our loop in these forms:
>
> (1) while A && B && C && D && E || false; do :; done
> (2) while A && B && C && D && E || break; do :; done
> (3) while A && B; do C && D && E || break; do :; done
> (4) while :; do A && B && C && D && E || break; done
>
> and all of them are equivalent.
>
> But obviously the only sane version is (3).
Uh, it is the only version with a syntax error.
> If your complaint were against things like (1) and (2), I would have
> completely agreed with you. If you want "effects", you do so
> between do and done. Although you can use break between do and done
> if you need to conditionally break out of the loop after causing
> some effect there, between while and do is where you are only
> supposed to decide if you want to break out of the loop without
> causing "effects".
>
> But what you were complaining about was different.
Basically
while A && B || break; do C && D && E || break; done
> If we were to ignore broken shells that do not return success
> from a case statement with no matching pattern, the following
> two are equivalent:
>
> while case "$sth" in foo) break ;; esac; do ...; done
> while case "$sth" in foo) false ;; esac; do ...; done
>
> Their "case" are used to decide if you want to break out of the
> loop; the former is (1) being a bit more explicit, and (2) used
> to be a bit more efficient when false was not built-in.
As a completely irrelevant side note: the autoconf documentation
mentions that "false" is more portable than "true" since calling it
returns a non-zero exit status even when it is not installed or
built-in.
> Now the latter reason is mostly historical and it is not a valid
> reason to choose the former over the latter anymore. But that does
> not make it any more confusing than the latter to a person who knows
> what "break" means in a loop. An explicit 'break' is still more,
> eh,... explicit ;-)
>
> But the "break" never was the issue. Return value of "case" was.
I guess this has been a misunderstanding: for me, personally, the
break was the issue: I don't like breaking out of a condition, since
breaking for me is an action. I just used the fact that the BSD
shells happen not to grok the constructs (and actually through a
somewhat similar confusion between condition and action) to leverage
my dislike of this construct and propose a patch.
> The reason I took your patch and proposed commit log message
> (almost) as-is was because you rewrote "case" to "test".
Uhm, ok. It was a case of realizing "hm, this does not really look
much nicer" before I chose to switch to "test". In fact, there is one
case statement remaining which I rewrote in the previously discussed
manner, and it did not strike me as being much prettier. So maybe I
somewhat misjudged the core of my offended sense of aesthetics, but
the impetus of the discussion still carried into the commit message.
Alea iacta est ("The SHA-1 has been established").
--
David Kastrup, Kriemhildstr. 15, 44793 Bochum
^ permalink raw reply
* Re: [PATCH] rebase -i: commit when continuing after "edit"
From: Junio C Hamano @ 2007-09-25 5:37 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: Dmitry Potapov, git
In-Reply-To: <Pine.LNX.4.64.0709240121080.28395@racer.site>
> When doing an "edit" on a commit, editing and git-adding some files,
> "git rebase -i" complained about a missing "author-script". The idea was
> that the user would call "git commit --amend" herself.
>
> But we can be nice and do that for the user.
>
> To do this, rebase -i stores the author script and message whenever
> writing out a patch, and it remembers to do an "amend" by creating the
> file "amend" in "$DOTEST".
>
> Noticed by Dmitry Potapov.
>
> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
> Signed-off-by: Junio C Hamano <gitster@pobox.com>
>
> diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
> index 2fa53fd..5982967 100755
> --- a/git-rebase--interactive.sh
> +++ b/git-rebase--interactive.sh
> @@ -1,484 +1,488 @@
> #!/bin/sh
> ...
> output () {
> case "$VERBOSE" in
> '')
> "$@" > "$DOTEST"/output 2>&1
> status=$?
> test $status != 0 &&
> cat "$DOTEST"/output
> return $status
> ;;
One more level of indent, please.
> *)
> "$@"
> esac
I find it is usually less error prone to help the longer term
maintainability if you do not omit double-semicolon before esac.
> }
>
> require_clean_work_tree () {
> # test if working tree is dirty
> git rev-parse --verify HEAD > /dev/null &&
> git update-index --refresh &&
> git diff-files --quiet &&
> git diff-index --cached --quiet HEAD ||
> die "Working tree is dirty"
> }
> ...
> mark_action_done () {
> sed -e 1q < "$TODO" >> "$DONE"
> sed -e 1d < "$TODO" >> "$TODO".new
> mv -f "$TODO".new "$TODO"
> count=$(($(wc -l < "$DONE")))
> total=$(($count+$(wc -l < "$TODO")))
> printf "Rebasing (%d/%d)\r" $count $total
> test -z "$VERBOSE" || echo
> }
>
> make_patch () {
> parent_sha1=$(git rev-parse --verify "$1"^ 2> /dev/null)
> git diff "$parent_sha1".."$1" > "$DOTEST"/patch
What's the point of using --verify when you do not error out
upon error? I find this quite inconsistent; your
require_clean_work_tree above is so nicely written.
Is there anything (other than user's common sense, which we
cannot always count on these days) that prevents the caller to
feed a root commit to this function, I wonder?
> -}
> -
> -die_with_patch () {
> test -f "$DOTEST"/message ||
> git cat-file commit $sha1 | sed "1,/^$/d" > "$DOTEST"/message
> test -f "$DOTEST"/author-script ||
> get_author_ident_from_commit $sha1 > "$DOTEST"/author-script
> +}
Are these "$sha1" still valid, or do you need "$1" given to the
make_patch function?
> pick_one () {
> no_ff=
> case "$1" in -n) sha1=$2; no_ff=t ;; *) sha1=$1 ;; esac
> output git rev-parse --verify $sha1 || die "Invalid commit name: $sha1"
> test -d "$REWRITTEN" &&
> pick_one_preserving_merges "$@" && return
> parent_sha1=$(git rev-parse --verify $sha1^ 2>/dev/null)
> current_sha1=$(git rev-parse --verify HEAD)
Again --verify without verifying.
> if test $no_ff$current_sha1 = $parent_sha1; then
> output git reset --hard $sha1
> test "a$1" = a-n && output git reset --soft $current_sha1
> sha1=$(git rev-parse --short $sha1)
> output warn Fast forward to $sha1
> else
> output git cherry-pick $STRATEGY "$@"
> fi
> }
>
> pick_one_preserving_merges () {
> case "$1" in -n) sha1=$2 ;; *) sha1=$1 ;; esac
> sha1=$(git rev-parse $sha1)
>
> if test -f "$DOTEST"/current-commit
> then
> current_commit=$(cat "$DOTEST"/current-commit) &&
> git rev-parse HEAD > "$REWRITTEN"/$current_commit &&
> rm "$DOTEST"/current-commit ||
> die "Cannot write current commit's replacement sha1"
> fi
>
> # rewrite parents; if none were rewritten, we can fast-forward.
> fast_forward=t
> preserve=t
> new_parents=
> for p in $(git rev-list --parents -1 $sha1 | cut -d\ -f2-)
Just a style nit. A string literal for a SP is easier to read
if written as a SP inside sq pair (i.e. ' ') not backslash
followed by a SP (i.e. \ ).
> do
> if test -f "$REWRITTEN"/$p
> then
> preserve=f
> new_p=$(cat "$REWRITTEN"/$p)
> test $p != $new_p && fast_forward=f
> case "$new_parents" in
> *$new_p*)
> ;; # do nothing; that parent is already there
> *)
> new_parents="$new_parents $new_p"
> esac
> fi
> done
> case $fast_forward in
> t)
> output warn "Fast forward to $sha1"
> test $preserve=f && echo $sha1 > "$REWRITTEN"/$sha1
Testing if concatenation of $preserve and "=f" is not an empty
string, which would almost always yield true?
> ;;
> f)
> test "a$1" = a-n && die "Refusing to squash a merge: $sha1"
>
> first_parent=$(expr "$new_parents" : " \([^ ]*\)")
Style; typically regexp form of expr and sed expression are
easier to read with quoted with sq, not dq.
> # detach HEAD to current parent
> output git checkout $first_parent 2> /dev/null ||
> die "Cannot move HEAD to $first_parent"
>
> echo $sha1 > "$DOTEST"/current-commit
> case "$new_parents" in
> \ *\ *)
Likewise here: ' '*' '*
> # redo merge
> author_script=$(get_author_ident_from_commit $sha1)
> eval "$author_script"
> msg="$(git cat-file commit $sha1 | \
> sed -e '1,/^$/d' -e "s/[\"\\]/\\\\&/g")"
What's this backquoting about? Your "output" does not eval (and
it shouldn't), so that's not it. Working around incompatible
echo that does auto magic used to write MERGE_MSG? Can we lose
the backquoting by using printf "%s\n" there?
> ...
> nth_string () {
> case "$1" in
> *1[0-9]|*[04-9]) echo "$1"th;;
> *1) echo "$1"st;;
> *2) echo "$1"nd;;
> *3) echo "$1"rd;;
> esac
> }
Cute.
> ...
> do_next () {
> test -f "$DOTEST"/message && rm "$DOTEST"/message
> test -f "$DOTEST"/author-script && rm "$DOTEST"/author-script
> + test -f "$DOTEST"/amend && rm "$DOTEST"/amend
As you do not check the error from "rm", how are these different
from rm -f "$DOTEST/frotz"?
> read command sha1 rest < "$TODO"
> case "$command" in
> \#|'')
> mark_action_done
> ;;
Perhaps '#'*?
> ...
> edit)
> comment_for_reflog edit
>
> mark_action_done
> pick_one $sha1 ||
> die_with_patch $sha1 "Could not apply $sha1... $rest"
> make_patch $sha1
> + : > "$DOTEST"/amend
Good catch, but ':' is redundant ;-)
> warn
> warn "You can amend the commit now, with"
> warn
> warn " git commit --amend"
> warn
> exit 0
> ;;
> squash)
> comment_for_reflog squash
>
> test -z "$(grep -ve '^$' -e '^#' < $DONE)" &&
> die "Cannot 'squash' without a previous commit"
Why "test -z"? Wouldn't this be equivalent?
grep -v -q -e '^$' -e '^#' "$DONE" || die ...
>
> mark_action_done
> make_squash_message $sha1 > "$MSG"
> case "$(peek_next_command)" in
> squash)
> EDIT_COMMIT=
> USE_OUTPUT=output
> cp "$MSG" "$SQUASH_MSG"
> ;;
One more level of indent, please.
> *)
> EDIT_COMMIT=-e
> USE_OUTPUT=
> test -f "$SQUASH_MSG" && rm "$SQUASH_MSG"
Again, "test -f && rm"?
> ...
> pick_one -n $sha1 || failed=t
> author_script=$(get_author_ident_from_commit $sha1)
> echo "$author_script" > "$DOTEST"/author-script
> case $failed in
> f)
> # This is like --amend, but with a different message
> eval "$author_script"
> export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_AUTHOR_DATE
> $USE_OUTPUT git commit -F "$MSG" $EDIT_COMMIT
> ;;
The "export" here makes me somewhat nervous -- no chance these
leak into the next round?
> ...
> HEAD=$(git rev-parse --verify HEAD) || die "No HEAD?"
> UPSTREAM=$(git rev-parse --verify "$1") || die "Invalid base"
>
> test -z "$ONTO" && ONTO=$UPSTREAM
>
> : > "$DOTEST"/interactive || die "Could not mark as interactive"
> git symbolic-ref HEAD > "$DOTEST"/head-name ||
> die "Could not get HEAD"
It was somewhat annoying that you cannot "rebase -i" the
detached HEAD state.
> ...
> cat > "$TODO" << EOF
> # Rebasing $SHORTUPSTREAM..$SHORTHEAD onto $SHORTONTO
> #
> # Commands:
> # pick = use commit
> # edit = use commit, but stop for amending
> # squash = use commit, but meld into previous commit
> #
> # If you remove a line here THAT COMMIT WILL BE LOST.
> #
> EOF
> git rev-list $MERGES_OPTION --pretty=oneline --abbrev-commit \
> --abbrev=7 --reverse --left-right --cherry-pick \
> $UPSTREAM...$HEAD | \
> sed -n "s/^>/pick /p" >> "$TODO"
>
> test -z "$(grep -ve '^$' -e '^#' < $TODO)" &&
> die_abort "Nothing to do"
Same comment here as before, and there is another one a few
lines below. Perhaps a trivial shell function is in order?
^ permalink raw reply
* Re: [PATCH] post-checkout hook, and related docs and tests
From: Andreas Ericsson @ 2007-09-25 4:42 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Josh England, git
In-Reply-To: <7vfy138vql.fsf@gitster.siamese.dyndns.org>
Junio C Hamano wrote:
> "Josh England" <jjengla@sandia.gov> writes:
>
> But I am obviously not the one who is interested in tracking
> extended attributes attached to git contents, and I do not feel
> too strongly about one way or the other. I am Ok with it if you
> think "checkout is magical" is easier to teach [*1*].
>
> [Footnote]
>
> *1* I actually suspect this might be the case.
I think so too, if nothing else than for the simple reason than that
the hook is called 'post-checkout', so the explanation is likely to
go something like 'the checkout program activates it after having
updated the worktree'.
> I consider that
> per-path checkout from a commit is just a fancy and handy way to
> edit individual files but that probably comes from knowing how
> git works too much and I lost my git virginity too long ago. A
> pure "user" who types "git checkout commit path" may actively
> expect "checkout" command to do something more magical than
> simply updating the index and the work tree files to a random
> state that happens to match the state recorded in one commit.
Like, run the post-checkout hook? I should think it wouldn't be
too hard to believe it will.
I imagine the people using this feature will be either git-fanatics
that use it for everything and only in their own environment, or
sysadmins that get a handy tool for managing config in a corporate
environment. I wouldn't be surprised if those sysadmins weren't
all too keen on learning the 1001 ways there is to create a file
from a special revision in git (and personally I only knew about 2
of the 4 you listed), so for them there'll most likely *only* be
git-checkout to edit the work-tree.
--
Andreas Ericsson andreas.ericsson@op5.se
OP5 AB www.op5.se
Tel: +46 8-230225 Fax: +46 8-230231
^ permalink raw reply
* [PATCH 3/3] Prevent send-pack from segfaulting when a branch doesn't match
From: Shawn O. Pearce @ 2007-09-25 4:13 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
If `git push url foo` can't find a local branch named foo we can't
match it to any remote branch as the local branch is NULL and its
name is probably at position 0x34 in memory. On most systems that
isn't a valid address for git-send-pack's virtual address space
and we segfault.
If we can't find a source match and we have no destination we
need to abort the match function early before we try to match the
destination against the remote.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
remote.c | 5 ++++-
1 files changed, 4 insertions(+), 1 deletions(-)
diff --git a/remote.c b/remote.c
index 2166a2b..e7d735b 100644
--- a/remote.c
+++ b/remote.c
@@ -610,8 +610,11 @@ static int match_explicit(struct ref *src, struct ref *dst,
if (!matched_src)
errs = 1;
- if (!dst_value)
+ if (!dst_value) {
+ if (!matched_src)
+ return errs;
dst_value = matched_src->name;
+ }
switch (count_refspec_match(dst_value, dst, &matched_dst)) {
case 1:
--
1.5.3.2.124.g2456-dirty
^ permalink raw reply related
* [PATCH 2/3] Cleanup unnecessary break in remote.c
From: Shawn O. Pearce @ 2007-09-25 4:13 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
This simple change makes the body of "case 0" easier to read; no
matter what the value of matched_src is we want to break out of
the switch and not fall through. We only want to display an error
if matched_src is NULL, as this indicates there is no local branch
matching the input.
Also modified the default case's error message so it uses one less
line of text. Even at 8 column per tab indentation we still don't
break 80 columns with this new formatting.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
remote.c | 9 +++------
1 files changed, 3 insertions(+), 6 deletions(-)
diff --git a/remote.c b/remote.c
index ac354f3..2166a2b 100644
--- a/remote.c
+++ b/remote.c
@@ -598,15 +598,12 @@ static int match_explicit(struct ref *src, struct ref *dst,
* way to delete 'other' ref at the remote end.
*/
matched_src = try_explicit_object_name(rs->src);
- if (matched_src)
- break;
- error("src refspec %s does not match any.",
- rs->src);
+ if (!matched_src)
+ error("src refspec %s does not match any.", rs->src);
break;
default:
matched_src = NULL;
- error("src refspec %s matches more than one.",
- rs->src);
+ error("src refspec %s matches more than one.", rs->src);
break;
}
--
1.5.3.2.124.g2456-dirty
^ permalink raw reply related
* [PATCH 1/3] Cleanup style nit of 'x == NULL' in remote.c
From: Shawn O. Pearce @ 2007-09-25 4:13 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
Git style tends to prefer "!x" over "x == NULL". Make it so in
these handful of locations that were not following along.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
remote.c | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/remote.c b/remote.c
index e3c3df5..ac354f3 100644
--- a/remote.c
+++ b/remote.c
@@ -416,7 +416,7 @@ int remote_find_tracking(struct remote *remote, struct refspec *refspec)
int i;
if (find_src) {
- if (refspec->dst == NULL)
+ if (!refspec->dst)
return error("find_tracking: need either src or dst");
needle = refspec->dst;
result = &refspec->src;
@@ -613,7 +613,7 @@ static int match_explicit(struct ref *src, struct ref *dst,
if (!matched_src)
errs = 1;
- if (dst_value == NULL)
+ if (!dst_value)
dst_value = matched_src->name;
switch (count_refspec_match(dst_value, dst, &matched_dst)) {
@@ -633,7 +633,7 @@ static int match_explicit(struct ref *src, struct ref *dst,
dst_value);
break;
}
- if (errs || matched_dst == NULL)
+ if (errs || !matched_dst)
return 1;
if (matched_dst->peer_ref) {
errs = 1;
--
1.5.3.2.124.g2456-dirty
^ permalink raw reply related
* [PATCH] Move convert-objects to contrib.
From: Matt Kraai @ 2007-09-25 3:14 UTC (permalink / raw)
To: git; +Cc: Matt Kraai
Signed-off-by: Matt Kraai <kraai@ftbfs.org>
---
.gitignore | 1 -
Documentation/cmd-list.perl | 1 -
Documentation/git-convert-objects.txt | 28 --
Makefile | 2 +-
contrib/completion/git-completion.bash | 1 -
contrib/convert-objects/convert-objects.c | 329 +++++++++++++++++++++++
contrib/convert-objects/git-convert-objects.txt | 28 ++
convert-objects.c | 329 -----------------------
8 files changed, 358 insertions(+), 361 deletions(-)
delete mode 100644 Documentation/git-convert-objects.txt
create mode 100644 contrib/convert-objects/convert-objects.c
create mode 100644 contrib/convert-objects/git-convert-objects.txt
delete mode 100644 convert-objects.c
diff --git a/.gitignore b/.gitignore
index 63c918c..e0b91be 100644
--- a/.gitignore
+++ b/.gitignore
@@ -25,7 +25,6 @@ git-clone
git-commit
git-commit-tree
git-config
-git-convert-objects
git-count-objects
git-cvsexportcommit
git-cvsimport
diff --git a/Documentation/cmd-list.perl b/Documentation/cmd-list.perl
index 4ee76ea..1061fd8 100755
--- a/Documentation/cmd-list.perl
+++ b/Documentation/cmd-list.perl
@@ -94,7 +94,6 @@ git-clone mainporcelain
git-commit mainporcelain
git-commit-tree plumbingmanipulators
git-config ancillarymanipulators
-git-convert-objects ancillarymanipulators
git-count-objects ancillaryinterrogators
git-cvsexportcommit foreignscminterface
git-cvsimport foreignscminterface
diff --git a/Documentation/git-convert-objects.txt b/Documentation/git-convert-objects.txt
deleted file mode 100644
index 9718abf..0000000
--- a/Documentation/git-convert-objects.txt
+++ /dev/null
@@ -1,28 +0,0 @@
-git-convert-objects(1)
-======================
-
-NAME
-----
-git-convert-objects - Converts old-style git repository
-
-
-SYNOPSIS
---------
-'git-convert-objects'
-
-DESCRIPTION
------------
-Converts old-style git repository to the latest format
-
-
-Author
-------
-Written by Linus Torvalds <torvalds@osdl.org>
-
-Documentation
---------------
-Documentation by David Greaves, Junio C Hamano and the git-list <git@vger.kernel.org>.
-
-GIT
----
-Part of the gitlink:git[7] suite
diff --git a/Makefile b/Makefile
index 0055eef..94b16d0 100644
--- a/Makefile
+++ b/Makefile
@@ -233,7 +233,7 @@ SCRIPTS = $(patsubst %.sh,%,$(SCRIPT_SH)) \
# ... and all the rest that could be moved out of bindir to gitexecdir
PROGRAMS = \
- git-convert-objects$X git-fetch-pack$X \
+ git-fetch-pack$X \
git-hash-object$X git-index-pack$X git-local-fetch$X \
git-fast-import$X \
git-daemon$X \
diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index cad842a..e760930 100755
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -299,7 +299,6 @@ __git_commands ()
check-attr) : plumbing;;
check-ref-format) : plumbing;;
commit-tree) : plumbing;;
- convert-objects) : plumbing;;
cvsexportcommit) : export;;
cvsimport) : import;;
cvsserver) : daemon;;
diff --git a/contrib/convert-objects/convert-objects.c b/contrib/convert-objects/convert-objects.c
new file mode 100644
index 0000000..90e7900
--- /dev/null
+++ b/contrib/convert-objects/convert-objects.c
@@ -0,0 +1,329 @@
+#include "cache.h"
+#include "blob.h"
+#include "commit.h"
+#include "tree.h"
+
+struct entry {
+ unsigned char old_sha1[20];
+ unsigned char new_sha1[20];
+ int converted;
+};
+
+#define MAXOBJECTS (1000000)
+
+static struct entry *convert[MAXOBJECTS];
+static int nr_convert;
+
+static struct entry * convert_entry(unsigned char *sha1);
+
+static struct entry *insert_new(unsigned char *sha1, int pos)
+{
+ struct entry *new = xcalloc(1, sizeof(struct entry));
+ hashcpy(new->old_sha1, sha1);
+ memmove(convert + pos + 1, convert + pos, (nr_convert - pos) * sizeof(struct entry *));
+ convert[pos] = new;
+ nr_convert++;
+ if (nr_convert == MAXOBJECTS)
+ die("you're kidding me - hit maximum object limit");
+ return new;
+}
+
+static struct entry *lookup_entry(unsigned char *sha1)
+{
+ int low = 0, high = nr_convert;
+
+ while (low < high) {
+ int next = (low + high) / 2;
+ struct entry *n = convert[next];
+ int cmp = hashcmp(sha1, n->old_sha1);
+ if (!cmp)
+ return n;
+ if (cmp < 0) {
+ high = next;
+ continue;
+ }
+ low = next+1;
+ }
+ return insert_new(sha1, low);
+}
+
+static void convert_binary_sha1(void *buffer)
+{
+ struct entry *entry = convert_entry(buffer);
+ hashcpy(buffer, entry->new_sha1);
+}
+
+static void convert_ascii_sha1(void *buffer)
+{
+ unsigned char sha1[20];
+ struct entry *entry;
+
+ if (get_sha1_hex(buffer, sha1))
+ die("expected sha1, got '%s'", (char*) buffer);
+ entry = convert_entry(sha1);
+ memcpy(buffer, sha1_to_hex(entry->new_sha1), 40);
+}
+
+static unsigned int convert_mode(unsigned int mode)
+{
+ unsigned int newmode;
+
+ newmode = mode & S_IFMT;
+ if (S_ISREG(mode))
+ newmode |= (mode & 0100) ? 0755 : 0644;
+ return newmode;
+}
+
+static int write_subdirectory(void *buffer, unsigned long size, const char *base, int baselen, unsigned char *result_sha1)
+{
+ char *new = xmalloc(size);
+ unsigned long newlen = 0;
+ unsigned long used;
+
+ used = 0;
+ while (size) {
+ int len = 21 + strlen(buffer);
+ char *path = strchr(buffer, ' ');
+ unsigned char *sha1;
+ unsigned int mode;
+ char *slash, *origpath;
+
+ if (!path || strtoul_ui(buffer, 8, &mode))
+ die("bad tree conversion");
+ mode = convert_mode(mode);
+ path++;
+ if (memcmp(path, base, baselen))
+ break;
+ origpath = path;
+ path += baselen;
+ slash = strchr(path, '/');
+ if (!slash) {
+ newlen += sprintf(new + newlen, "%o %s", mode, path);
+ new[newlen++] = '\0';
+ hashcpy((unsigned char*)new + newlen, (unsigned char *) buffer + len - 20);
+ newlen += 20;
+
+ used += len;
+ size -= len;
+ buffer = (char *) buffer + len;
+ continue;
+ }
+
+ newlen += sprintf(new + newlen, "%o %.*s", S_IFDIR, (int)(slash - path), path);
+ new[newlen++] = 0;
+ sha1 = (unsigned char *)(new + newlen);
+ newlen += 20;
+
+ len = write_subdirectory(buffer, size, origpath, slash-origpath+1, sha1);
+
+ used += len;
+ size -= len;
+ buffer = (char *) buffer + len;
+ }
+
+ write_sha1_file(new, newlen, tree_type, result_sha1);
+ free(new);
+ return used;
+}
+
+static void convert_tree(void *buffer, unsigned long size, unsigned char *result_sha1)
+{
+ void *orig_buffer = buffer;
+ unsigned long orig_size = size;
+
+ while (size) {
+ size_t len = 1+strlen(buffer);
+
+ convert_binary_sha1((char *) buffer + len);
+
+ len += 20;
+ if (len > size)
+ die("corrupt tree object");
+ size -= len;
+ buffer = (char *) buffer + len;
+ }
+
+ write_subdirectory(orig_buffer, orig_size, "", 0, result_sha1);
+}
+
+static unsigned long parse_oldstyle_date(const char *buf)
+{
+ char c, *p;
+ char buffer[100];
+ struct tm tm;
+ const char *formats[] = {
+ "%c",
+ "%a %b %d %T",
+ "%Z",
+ "%Y",
+ " %Y",
+ NULL
+ };
+ /* We only ever did two timezones in the bad old format .. */
+ const char *timezones[] = {
+ "PDT", "PST", "CEST", NULL
+ };
+ const char **fmt = formats;
+
+ p = buffer;
+ while (isspace(c = *buf))
+ buf++;
+ while ((c = *buf++) != '\n')
+ *p++ = c;
+ *p++ = 0;
+ buf = buffer;
+ memset(&tm, 0, sizeof(tm));
+ do {
+ const char *next = strptime(buf, *fmt, &tm);
+ if (next) {
+ if (!*next)
+ return mktime(&tm);
+ buf = next;
+ } else {
+ const char **p = timezones;
+ while (isspace(*buf))
+ buf++;
+ while (*p) {
+ if (!memcmp(buf, *p, strlen(*p))) {
+ buf += strlen(*p);
+ break;
+ }
+ p++;
+ }
+ }
+ fmt++;
+ } while (*buf && *fmt);
+ printf("left: %s\n", buf);
+ return mktime(&tm);
+}
+
+static int convert_date_line(char *dst, void **buf, unsigned long *sp)
+{
+ unsigned long size = *sp;
+ char *line = *buf;
+ char *next = strchr(line, '\n');
+ char *date = strchr(line, '>');
+ int len;
+
+ if (!next || !date)
+ die("missing or bad author/committer line %s", line);
+ next++; date += 2;
+
+ *buf = next;
+ *sp = size - (next - line);
+
+ len = date - line;
+ memcpy(dst, line, len);
+ dst += len;
+
+ /* Is it already in new format? */
+ if (isdigit(*date)) {
+ int datelen = next - date;
+ memcpy(dst, date, datelen);
+ return len + datelen;
+ }
+
+ /*
+ * Hacky hacky: one of the sparse old-style commits does not have
+ * any date at all, but we can fake it by using the committer date.
+ */
+ if (*date == '\n' && strchr(next, '>'))
+ date = strchr(next, '>')+2;
+
+ return len + sprintf(dst, "%lu -0700\n", parse_oldstyle_date(date));
+}
+
+static void convert_date(void *buffer, unsigned long size, unsigned char *result_sha1)
+{
+ char *new = xmalloc(size + 100);
+ unsigned long newlen = 0;
+
+ /* "tree <sha1>\n" */
+ memcpy(new + newlen, buffer, 46);
+ newlen += 46;
+ buffer = (char *) buffer + 46;
+ size -= 46;
+
+ /* "parent <sha1>\n" */
+ while (!memcmp(buffer, "parent ", 7)) {
+ memcpy(new + newlen, buffer, 48);
+ newlen += 48;
+ buffer = (char *) buffer + 48;
+ size -= 48;
+ }
+
+ /* "author xyz <xyz> date" */
+ newlen += convert_date_line(new + newlen, &buffer, &size);
+ /* "committer xyz <xyz> date" */
+ newlen += convert_date_line(new + newlen, &buffer, &size);
+
+ /* Rest */
+ memcpy(new + newlen, buffer, size);
+ newlen += size;
+
+ write_sha1_file(new, newlen, commit_type, result_sha1);
+ free(new);
+}
+
+static void convert_commit(void *buffer, unsigned long size, unsigned char *result_sha1)
+{
+ void *orig_buffer = buffer;
+ unsigned long orig_size = size;
+
+ if (memcmp(buffer, "tree ", 5))
+ die("Bad commit '%s'", (char*) buffer);
+ convert_ascii_sha1((char *) buffer + 5);
+ buffer = (char *) buffer + 46; /* "tree " + "hex sha1" + "\n" */
+ while (!memcmp(buffer, "parent ", 7)) {
+ convert_ascii_sha1((char *) buffer + 7);
+ buffer = (char *) buffer + 48;
+ }
+ convert_date(orig_buffer, orig_size, result_sha1);
+}
+
+static struct entry * convert_entry(unsigned char *sha1)
+{
+ struct entry *entry = lookup_entry(sha1);
+ enum object_type type;
+ void *buffer, *data;
+ unsigned long size;
+
+ if (entry->converted)
+ return entry;
+ data = read_sha1_file(sha1, &type, &size);
+ if (!data)
+ die("unable to read object %s", sha1_to_hex(sha1));
+
+ buffer = xmalloc(size);
+ memcpy(buffer, data, size);
+
+ if (type == OBJ_BLOB) {
+ write_sha1_file(buffer, size, blob_type, entry->new_sha1);
+ } else if (type == OBJ_TREE)
+ convert_tree(buffer, size, entry->new_sha1);
+ else if (type == OBJ_COMMIT)
+ convert_commit(buffer, size, entry->new_sha1);
+ else
+ die("unknown object type %d in %s", type, sha1_to_hex(sha1));
+ entry->converted = 1;
+ free(buffer);
+ free(data);
+ return entry;
+}
+
+int main(int argc, char **argv)
+{
+ unsigned char sha1[20];
+ struct entry *entry;
+
+ setup_git_directory();
+
+ if (argc != 2)
+ usage("git-convert-objects <sha1>");
+ if (get_sha1(argv[1], sha1))
+ die("Not a valid object name %s", argv[1]);
+
+ entry = convert_entry(sha1);
+ printf("new sha1: %s\n", sha1_to_hex(entry->new_sha1));
+ return 0;
+}
diff --git a/contrib/convert-objects/git-convert-objects.txt b/contrib/convert-objects/git-convert-objects.txt
new file mode 100644
index 0000000..9718abf
--- /dev/null
+++ b/contrib/convert-objects/git-convert-objects.txt
@@ -0,0 +1,28 @@
+git-convert-objects(1)
+======================
+
+NAME
+----
+git-convert-objects - Converts old-style git repository
+
+
+SYNOPSIS
+--------
+'git-convert-objects'
+
+DESCRIPTION
+-----------
+Converts old-style git repository to the latest format
+
+
+Author
+------
+Written by Linus Torvalds <torvalds@osdl.org>
+
+Documentation
+--------------
+Documentation by David Greaves, Junio C Hamano and the git-list <git@vger.kernel.org>.
+
+GIT
+---
+Part of the gitlink:git[7] suite
diff --git a/convert-objects.c b/convert-objects.c
deleted file mode 100644
index 90e7900..0000000
--- a/convert-objects.c
+++ /dev/null
@@ -1,329 +0,0 @@
-#include "cache.h"
-#include "blob.h"
-#include "commit.h"
-#include "tree.h"
-
-struct entry {
- unsigned char old_sha1[20];
- unsigned char new_sha1[20];
- int converted;
-};
-
-#define MAXOBJECTS (1000000)
-
-static struct entry *convert[MAXOBJECTS];
-static int nr_convert;
-
-static struct entry * convert_entry(unsigned char *sha1);
-
-static struct entry *insert_new(unsigned char *sha1, int pos)
-{
- struct entry *new = xcalloc(1, sizeof(struct entry));
- hashcpy(new->old_sha1, sha1);
- memmove(convert + pos + 1, convert + pos, (nr_convert - pos) * sizeof(struct entry *));
- convert[pos] = new;
- nr_convert++;
- if (nr_convert == MAXOBJECTS)
- die("you're kidding me - hit maximum object limit");
- return new;
-}
-
-static struct entry *lookup_entry(unsigned char *sha1)
-{
- int low = 0, high = nr_convert;
-
- while (low < high) {
- int next = (low + high) / 2;
- struct entry *n = convert[next];
- int cmp = hashcmp(sha1, n->old_sha1);
- if (!cmp)
- return n;
- if (cmp < 0) {
- high = next;
- continue;
- }
- low = next+1;
- }
- return insert_new(sha1, low);
-}
-
-static void convert_binary_sha1(void *buffer)
-{
- struct entry *entry = convert_entry(buffer);
- hashcpy(buffer, entry->new_sha1);
-}
-
-static void convert_ascii_sha1(void *buffer)
-{
- unsigned char sha1[20];
- struct entry *entry;
-
- if (get_sha1_hex(buffer, sha1))
- die("expected sha1, got '%s'", (char*) buffer);
- entry = convert_entry(sha1);
- memcpy(buffer, sha1_to_hex(entry->new_sha1), 40);
-}
-
-static unsigned int convert_mode(unsigned int mode)
-{
- unsigned int newmode;
-
- newmode = mode & S_IFMT;
- if (S_ISREG(mode))
- newmode |= (mode & 0100) ? 0755 : 0644;
- return newmode;
-}
-
-static int write_subdirectory(void *buffer, unsigned long size, const char *base, int baselen, unsigned char *result_sha1)
-{
- char *new = xmalloc(size);
- unsigned long newlen = 0;
- unsigned long used;
-
- used = 0;
- while (size) {
- int len = 21 + strlen(buffer);
- char *path = strchr(buffer, ' ');
- unsigned char *sha1;
- unsigned int mode;
- char *slash, *origpath;
-
- if (!path || strtoul_ui(buffer, 8, &mode))
- die("bad tree conversion");
- mode = convert_mode(mode);
- path++;
- if (memcmp(path, base, baselen))
- break;
- origpath = path;
- path += baselen;
- slash = strchr(path, '/');
- if (!slash) {
- newlen += sprintf(new + newlen, "%o %s", mode, path);
- new[newlen++] = '\0';
- hashcpy((unsigned char*)new + newlen, (unsigned char *) buffer + len - 20);
- newlen += 20;
-
- used += len;
- size -= len;
- buffer = (char *) buffer + len;
- continue;
- }
-
- newlen += sprintf(new + newlen, "%o %.*s", S_IFDIR, (int)(slash - path), path);
- new[newlen++] = 0;
- sha1 = (unsigned char *)(new + newlen);
- newlen += 20;
-
- len = write_subdirectory(buffer, size, origpath, slash-origpath+1, sha1);
-
- used += len;
- size -= len;
- buffer = (char *) buffer + len;
- }
-
- write_sha1_file(new, newlen, tree_type, result_sha1);
- free(new);
- return used;
-}
-
-static void convert_tree(void *buffer, unsigned long size, unsigned char *result_sha1)
-{
- void *orig_buffer = buffer;
- unsigned long orig_size = size;
-
- while (size) {
- size_t len = 1+strlen(buffer);
-
- convert_binary_sha1((char *) buffer + len);
-
- len += 20;
- if (len > size)
- die("corrupt tree object");
- size -= len;
- buffer = (char *) buffer + len;
- }
-
- write_subdirectory(orig_buffer, orig_size, "", 0, result_sha1);
-}
-
-static unsigned long parse_oldstyle_date(const char *buf)
-{
- char c, *p;
- char buffer[100];
- struct tm tm;
- const char *formats[] = {
- "%c",
- "%a %b %d %T",
- "%Z",
- "%Y",
- " %Y",
- NULL
- };
- /* We only ever did two timezones in the bad old format .. */
- const char *timezones[] = {
- "PDT", "PST", "CEST", NULL
- };
- const char **fmt = formats;
-
- p = buffer;
- while (isspace(c = *buf))
- buf++;
- while ((c = *buf++) != '\n')
- *p++ = c;
- *p++ = 0;
- buf = buffer;
- memset(&tm, 0, sizeof(tm));
- do {
- const char *next = strptime(buf, *fmt, &tm);
- if (next) {
- if (!*next)
- return mktime(&tm);
- buf = next;
- } else {
- const char **p = timezones;
- while (isspace(*buf))
- buf++;
- while (*p) {
- if (!memcmp(buf, *p, strlen(*p))) {
- buf += strlen(*p);
- break;
- }
- p++;
- }
- }
- fmt++;
- } while (*buf && *fmt);
- printf("left: %s\n", buf);
- return mktime(&tm);
-}
-
-static int convert_date_line(char *dst, void **buf, unsigned long *sp)
-{
- unsigned long size = *sp;
- char *line = *buf;
- char *next = strchr(line, '\n');
- char *date = strchr(line, '>');
- int len;
-
- if (!next || !date)
- die("missing or bad author/committer line %s", line);
- next++; date += 2;
-
- *buf = next;
- *sp = size - (next - line);
-
- len = date - line;
- memcpy(dst, line, len);
- dst += len;
-
- /* Is it already in new format? */
- if (isdigit(*date)) {
- int datelen = next - date;
- memcpy(dst, date, datelen);
- return len + datelen;
- }
-
- /*
- * Hacky hacky: one of the sparse old-style commits does not have
- * any date at all, but we can fake it by using the committer date.
- */
- if (*date == '\n' && strchr(next, '>'))
- date = strchr(next, '>')+2;
-
- return len + sprintf(dst, "%lu -0700\n", parse_oldstyle_date(date));
-}
-
-static void convert_date(void *buffer, unsigned long size, unsigned char *result_sha1)
-{
- char *new = xmalloc(size + 100);
- unsigned long newlen = 0;
-
- /* "tree <sha1>\n" */
- memcpy(new + newlen, buffer, 46);
- newlen += 46;
- buffer = (char *) buffer + 46;
- size -= 46;
-
- /* "parent <sha1>\n" */
- while (!memcmp(buffer, "parent ", 7)) {
- memcpy(new + newlen, buffer, 48);
- newlen += 48;
- buffer = (char *) buffer + 48;
- size -= 48;
- }
-
- /* "author xyz <xyz> date" */
- newlen += convert_date_line(new + newlen, &buffer, &size);
- /* "committer xyz <xyz> date" */
- newlen += convert_date_line(new + newlen, &buffer, &size);
-
- /* Rest */
- memcpy(new + newlen, buffer, size);
- newlen += size;
-
- write_sha1_file(new, newlen, commit_type, result_sha1);
- free(new);
-}
-
-static void convert_commit(void *buffer, unsigned long size, unsigned char *result_sha1)
-{
- void *orig_buffer = buffer;
- unsigned long orig_size = size;
-
- if (memcmp(buffer, "tree ", 5))
- die("Bad commit '%s'", (char*) buffer);
- convert_ascii_sha1((char *) buffer + 5);
- buffer = (char *) buffer + 46; /* "tree " + "hex sha1" + "\n" */
- while (!memcmp(buffer, "parent ", 7)) {
- convert_ascii_sha1((char *) buffer + 7);
- buffer = (char *) buffer + 48;
- }
- convert_date(orig_buffer, orig_size, result_sha1);
-}
-
-static struct entry * convert_entry(unsigned char *sha1)
-{
- struct entry *entry = lookup_entry(sha1);
- enum object_type type;
- void *buffer, *data;
- unsigned long size;
-
- if (entry->converted)
- return entry;
- data = read_sha1_file(sha1, &type, &size);
- if (!data)
- die("unable to read object %s", sha1_to_hex(sha1));
-
- buffer = xmalloc(size);
- memcpy(buffer, data, size);
-
- if (type == OBJ_BLOB) {
- write_sha1_file(buffer, size, blob_type, entry->new_sha1);
- } else if (type == OBJ_TREE)
- convert_tree(buffer, size, entry->new_sha1);
- else if (type == OBJ_COMMIT)
- convert_commit(buffer, size, entry->new_sha1);
- else
- die("unknown object type %d in %s", type, sha1_to_hex(sha1));
- entry->converted = 1;
- free(buffer);
- free(data);
- return entry;
-}
-
-int main(int argc, char **argv)
-{
- unsigned char sha1[20];
- struct entry *entry;
-
- setup_git_directory();
-
- if (argc != 2)
- usage("git-convert-objects <sha1>");
- if (get_sha1(argv[1], sha1))
- die("Not a valid object name %s", argv[1]);
-
- entry = convert_entry(sha1);
- printf("new sha1: %s\n", sha1_to_hex(entry->new_sha1));
- return 0;
-}
--
1.5.3.2
^ permalink raw reply related
* Re: My stash wants to delete all my files
From: Junio C Hamano @ 2007-09-25 1:26 UTC (permalink / raw)
To: Jonathan del Strother; +Cc: Git Mailing List
In-Reply-To: <5A9D6E3B-7B0E-4414-9AFB-C1C8B2EE6A9D@steelskies.com>
Jonathan del Strother <maillist@steelskies.com> writes:
> $ git stash list
> stash@{0}: On master: --apply
> stash@{1}: WIP on master: 09e3c30... Better handling of cell sizes in
> the grid
>
> $ git stash show stash@{1}
> ...
> 19 files changed, 0 insertions(+), 3805 deletions(-)
>
> Hmm. Looks like it's trying to delete all of my versioned files.
> "git stash apply stash@{1}" confirms this. Obviously that's not what
> I tried to stash - my WIP when I stashed was a few additions, a couple
> of new unversioned files, and moving a few lines of code from one file
> to another.
>
> Any ideas what happened there? I can't seem to reproduce the problem
> in a test repository.
There are two possibilities that I can think of offhand, neither
of them is about git-stash but about the state you ran stash
from.
Whenever anybody wonders where inadvertent reverting changes
come from, two most likely reasons are incorrect push into the
current branch's tip initiated from elsewhere, or incorrect
fetch into the current branch's tip initiated from the
repository.
If your work repository is foo, and if you are working on
'master' branch, you could
$ cd ../bar ; git push ../foo master:master
to push from elsewhere to update the tip of the checked out
branch. This makes the index and the work tree that was based
on the old commit in foo repository totally out of sync with
respect to the HEAD (which you are replacing), and committing
that state would revert the change the above push made.
You can do the same by doing something equally silly and
destructive by:
$ git fetch --update-head-ok ../bar master:master
After these operations that could make your index and work
tree state to include reverts, if you "stash", the stash will
record that the reverting was what you wanted to do.
I am not saying this is the only possible explanation though.
You can try:
git ls-tree stash@{1}
git rev-parse stash@{1}^1
git diff stash@{1}^1 stash@{1}^2
The stash entry itself is the state of the work tree, its first
parent (i.e. ^1) is the commit your stash was originally based
on, and its second parent (i.e. ^2) is what was recorded in the
index. Is the output from the first one empty? Does the second
command show you that you were on the commit you thought you were
on? Does the third command show you what you thought you have
told "git add" to put in the index just before you made the
stash?
^ permalink raw reply
* Re: [EGIT PATCH] Change to simplified icon.
From: Shawn O. Pearce @ 2007-09-25 1:16 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: git
In-Reply-To: <Pine.LNX.4.64.0709241124500.28395@racer.site>
Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:
> On Mon, 24 Sep 2007, Shawn O. Pearce wrote:
> >
> > [...] Maybe I'll take a stab at creating
> > a git-gui icon [...]
>
> You might want to look at http://git.or.cz/gitwiki/GitRelatedLogos (I
> especially like Henrik Nyh's, we use it in git-gui). Might be a good
> starting point.
What do you mean you "use it in git-gui" ? Have you patched git-gui
to set the window icon to Henrik's? And not tried to contribute
the patch upstream? Come on, show the GPL love... :-)
--
Shawn.
^ permalink raw reply
* Re: Missing strptime
From: Johannes Schindelin @ 2007-09-25 1:03 UTC (permalink / raw)
To: Linus Torvalds; +Cc: mkraai, git
In-Reply-To: <alpine.LFD.0.999.0709241750510.3579@woody.linux-foundation.org>
Hi,
On Mon, 24 Sep 2007, Linus Torvalds wrote:
> On Tue, 25 Sep 2007, Johannes Schindelin wrote:
> >
> > The only user for strptime is convert-objects, a program that should
> > probably move to contrib/ anyway. It was used once, a long time ago,
> > to convert from the old format, which hashed the compressed contents,
> > to the current format, which hashes the contents _before_ compression.
>
> Actually, it also changes the date format, I think.
Yes, right, that was actually why strptime() was needed.
Ciao,
Dscho
^ permalink raw reply
* Re: Missing strptime
From: Linus Torvalds @ 2007-09-25 0:52 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: mkraai, git
In-Reply-To: <Pine.LNX.4.64.0709250127170.28395@racer.site>
On Tue, 25 Sep 2007, Johannes Schindelin wrote:
>
> The only user for strptime is convert-objects, a program that should
> probably move to contrib/ anyway. It was used once, a long time ago, to
> convert from the old format, which hashed the compressed contents, to the
> current format, which hashes the contents _before_ compression.
Actually, it also changes the date format, I think.
> AFAIAC if a similar need should arise, the better alternative would be to
> write git-fast-export, a tool which dumps the contents of a repository
> suitable to pipe into git-fast-import.
Agreed. It probably might as well just be moved to contrib and let it
bitrot.
Linus
^ permalink raw reply
* Re: Missing strptime
From: Johannes Schindelin @ 2007-09-25 0:30 UTC (permalink / raw)
To: mkraai; +Cc: git
In-Reply-To: <OF8EBEA0A7.5425E9EA-ON88257360.00812AEA-88257360.00819919@beckman.com>
Hi,
On Mon, 24 Sep 2007, mkraai@beckman.com wrote:
> I'm porting Git to QNX.
That's nice!
> Its C library doesn't provide strptime, so I'd was planning to use the
> Gnulib implementation. Is that OK? If so, should I try to leave it as
> close to upstream's version as possible or should I remove all of the
> unneeded cruft? If not, is there an alternative implementation I should
> use?
The only user for strptime is convert-objects, a program that should
probably move to contrib/ anyway. It was used once, a long time ago, to
convert from the old format, which hashed the compressed contents, to the
current format, which hashes the contents _before_ compression.
AFAIAC if a similar need should arise, the better alternative would be to
write git-fast-export, a tool which dumps the contents of a repository
suitable to pipe into git-fast-import.
FWIW in mingw.git, we disabled convert-objects already a long time ago.
Ciao,
Dscho
^ permalink raw reply
* Missing strptime
From: mkraai @ 2007-09-24 23:35 UTC (permalink / raw)
To: git
Howdy,
I'm porting Git to QNX. Its C library doesn't provide strptime, so I'd
was planning to use the Gnulib implementation. Is that OK? If so, should
I try to leave it as close to upstream's version as possible or should I
remove all of the unneeded cruft? If not, is there an alternative
implementation I should use?
Matt
P.S. Sorry for the footer.
The server made the following annotations
---------------------------------------------------------------------------------
This message contains information that may be privileged or confidential and is the property of Beckman Coulter, Inc. It is intended only for the person to whom it is addressed. If you are not the intended recipient, you are not authorized to read, print, retain, copy, disseminate, distribute or use this message or any part thereof. If you receive this message in error, please notify the sender immediately and delete all copies of this message.
---------------------------------------------------------------------------------
^ permalink raw reply
* Re: [PATCH] post-checkout hook, and related docs and tests
From: Junio C Hamano @ 2007-09-24 23:54 UTC (permalink / raw)
To: Josh England; +Cc: Junio C Hamano, git
In-Reply-To: <1190671558.6078.87.camel@beauty>
"Josh England" <jjengla@sandia.gov> writes:
> On Mon, 2007-09-24 at 14:07 -0700, Junio C Hamano wrote:
> ...
>> If you want to spacial case
>>
>> $ git checkout otherbranch path.c
>>
>> it raises another issue. Which commit should supply the
>> "extended attribute description" for path.c? Should it be taken
>> from the current commit (aka HEAD), otherbranch, or the index?
>
> This already is a special case and your question is valid but not one
> that git should necessary care about. Since extended attributes are not
> built into git the only way to handle them is through hooks. A such, it
> is up to the hook to worry about these kinds of issues.
The fear I have is that that kind of thinking would necessitate
your hook to be called after the user edits paths.c in any other
way not to confuse users.
What I am questioning is where we should stop, in order to keep
things simpler to explain, and I happen to think that it is far
easier if we can teach that "git checkout other path.c" is
equivalent to "git cat-file blob other:path.c >path.c" followed
by "git add path.c", than saying "checkout is magical and if you
have external hook it can do far more than editing the file
yourself to arrive at the same contents".
But I am obviously not the one who is interested in tracking
extended attributes attached to git contents, and I do not feel
too strongly about one way or the other. I am Ok with it if you
think "checkout is magical" is easier to teach [*1*].
I just wanted to make sure we know what semantics this is
bringing in, and get it clearly documented. That's all.
[Footnote]
*1* I actually suspect this might be the case. I consider that
per-path checkout from a commit is just a fancy and handy way to
edit individual files but that probably comes from knowing how
git works too much and I lost my git virginity too long ago. A
pure "user" who types "git checkout commit path" may actively
expect "checkout" command to do something more magical than
simply updating the index and the work tree files to a random
state that happens to match the state recorded in one commit.
^ permalink raw reply
* Re: [PATCH] Supplant the "while case ... break ;; esac" idiom
From: Junio C Hamano @ 2007-09-24 23:31 UTC (permalink / raw)
To: David Kastrup; +Cc: git
In-Reply-To: <86bqbsta3g.fsf@lola.quinscape.zz>
David Kastrup <dak@gnu.org> writes:
> I am somewhat taken aback that a commit message considered offensive
> (though I still have a problem understanding why and certainly did not
> intend this) has been committed into master without giving me a chance
> to amend it.
Heh, that's simple. I changed my mind ;-)
When A and B test for preconditions, and C, D, and E are
operations with error reports as their side effects, we can
write our loop in these forms:
(1) while A && B && C && D && E || false; do :; done
(2) while A && B && C && D && E || break; do :; done
(3) while A && B; do C && D && E || break; do :; done
(4) while :; do A && B && C && D && E || break; done
and all of them are equivalent.
But obviously the only sane version is (3).
If your complaint were against things like (1) and (2), I would
have completely agreed with you. If you want "effects", you do
so between do and done. Although you can use break between do
and done if you need to conditionally break out of the loop
after causing some effect there, between while and do is where
you are only supposed to decide if you want to break out of the
loop without causing "effects".
But what you were complaining about was different.
If we were to ignore broken shells that do not return success
from a case statement with no matching pattern, the following
two are equivalent:
while case "$sth" in foo) break ;; esac; do ...; done
while case "$sth" in foo) false ;; esac; do ...; done
Their "case" are used to decide if you want to break out of the
loop; the former is (1) being a bit more explicit, and (2) used
to be a bit more efficient when false was not built-in.
Now the latter reason is mostly historical and it is not a valid
reason to choose the former over the latter anymore. But that
does not make it any more confusing than the latter to a person
who knows what "break" means in a loop. An explicit 'break' is
still more, eh,... explicit ;-)
But the "break" never was the issue. Return value of "case"
was.
The reason I took your patch and proposed commit log message
(almost) as-is was because you rewrote "case" to "test". That
IS an improvement, especially in the presense of a shell in the
field that does not implement case statement correctly, and you
talk about that in the later part of the commit log message.
The only "offending" part was "I consider...ugly", which is your
opinion but I think you as the patch author deserve to express
that. I do not think it would not have helped the FreeBSD shell
a bit if you removed that "ugliness" by merely replacing "break"
with "false", so I think the comment was not just offending but
irrelevant, though.
All the rest of your commit message is correct. The spec of
"case" might not be obvious to everybody that it ought to return
success when no pattern matched. And I found your wording to
fold the bug decription of some BSD shells there amusing ;-)
^ permalink raw reply
* Re: [PATCH] post-checkout hook, and related docs and tests
From: Josh England @ 2007-09-24 22:05 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7vejgnai1z.fsf@gitster.siamese.dyndns.org>
On Mon, 2007-09-24 at 14:07 -0700, Junio C Hamano wrote:
> "Josh England" <jjengla@sandia.gov> writes:
>
> > ... Granted, the
> > branch (and HEAD) does not change for this operation, but that shouldn't
> > matter. It is somewhat in line with the principle of 'least-surprise':
> > if the hook runs for 'git checkout otherbranch', but not 'git checkout
> > otherbranch path.c', this could cause confusion and distress to the
> > user. IMO, it is a 'checkout' so the post-checkout hook should run.
> > Why is that so insane?
>
> Because I find it would be surprising if the following commands
> behave differently:
>
> $ git cat-file blob otherbranch:path.c >path.c
> $ git show otherbranch:path.c >path.c
> $ git diff -R otherbranch path.c | git apply
> $ git checkout otherbranch path.c
For all intents and purposes, these would still behave the same. The
existence of a post-checkout hook does not at all affect the outcome of
the checkout. Sure there is potential for someone to do something
stupid inside the hook script, but that is true of any hook.
Most git users would never even enable the hook, but for those that do I
would assume that they'd want the hook to run for all 'git-checkout'
variants -- as I do.
> These are all talking about various ways to _edit_ working tree
> files, and not about switching between revisions.
>
> That's why I said I found that what the second sentence from
> your original description implied ("the hook gets old and new
> commit object name" which means we are talking about switching
> between revisions) was sensible, but it needs to be stressed a
> bit.
>
> If you want to spacial case
>
> $ git checkout otherbranch path.c
>
> it raises another issue. Which commit should supply the
> "extended attribute description" for path.c? Should it be taken
> from the current commit (aka HEAD), otherbranch, or the index?
This already is a special case and your question is valid but not one
that git should necessary care about. Since extended attributes are not
built into git the only way to handle them is through hooks. A such, it
is up to the hook to worry about these kinds of issues. The hook I have
written handles this by updating path.c attributes to match whatever
exists in the (tracked) attributes file of the current HEAD.
This 'git-checkout otherbranch path.c' is a corner case, but one that
can result in broken behavior when handling metadata unless the hook
runs. I just want to close all the holes. I can change the description
of the hook to try to dispel any confusion if that would help.
-JE
^ permalink raw reply
* Re: [PATCH] user-manual: Explain what submodules are good for.
From: J. Bruce Fields @ 2007-09-24 21:33 UTC (permalink / raw)
To: Michael Smith; +Cc: git, Miklos Vajna
In-Reply-To: <11906036491118-git-send-email-msmith@cbnco.com>
On Sun, Sep 23, 2007 at 11:14:09PM -0400, Michael Smith wrote:
> Rework the introduction to the Submodules section to explain why
> someone would use them, and fix up submodule references from the
> tree-object and todo sections.
Thanks!
> +Some large projects are composed of smaller, self-contained parts. For
> +example, an embedded Linux distribution's source tree would include every
> +piece of software in the distribution; a movie player might need to build
> +against a specific, known-working version of a decompression library;
> +several independent programs might all share the same build scripts.
...
> +Git's submodule support allows a repository to contain, as a subdirectory, a
> +checkout of an external project. Submodules maintain their own identity;
> +the submodule support just stores the submodule repository location and
> +commit ID, so other developers who clone the superproject can easily clone
> +all the submodules at the same revision. The gitlink:git-submodule[1]
> +command manages submodules.
That looks helpful, thanks, but a little more detail might be nice.
Imagining myself as a reader trying to decide whether to use submodules
in a given case, I'm not sure this would tell me everything I need to
know. For example, how does this compare to just importing a snapshot
of the library into your tree? (Or possibly using the subtree merge
strategy?)
Some issues that pop to mind are scalability (when does a monolithic
tree get too large to work with?) and backwards compatibility (what
version does everybody working on your project need to have for it to
work? What problems will you see if a few people are stuck with an
older git?) I haven't followed submodule development, though, so may
have missed more important issues.
--b.
^ permalink raw reply
* Re: [PATCH] post-checkout hook, and related docs and tests
From: Junio C Hamano @ 2007-09-24 21:07 UTC (permalink / raw)
To: Josh England; +Cc: Junio C Hamano, git
In-Reply-To: <1190662396.6078.63.camel@beauty>
"Josh England" <jjengla@sandia.gov> writes:
> ... Granted, the
> branch (and HEAD) does not change for this operation, but that shouldn't
> matter. It is somewhat in line with the principle of 'least-surprise':
> if the hook runs for 'git checkout otherbranch', but not 'git checkout
> otherbranch path.c', this could cause confusion and distress to the
> user. IMO, it is a 'checkout' so the post-checkout hook should run.
> Why is that so insane?
Because I find it would be surprising if the following commands
behave differently:
$ git cat-file blob otherbranch:path.c >path.c
$ git show otherbranch:path.c >path.c
$ git diff -R otherbranch path.c | git apply
$ git checkout otherbranch path.c
These are all talking about various ways to _edit_ working tree
files, and not about switching between revisions.
That's why I said I found that what the second sentence from
your original description implied ("the hook gets old and new
commit object name" which means we are talking about switching
between revisions) was sensible, but it needs to be stressed a
bit.
If you want to spacial case
$ git checkout otherbranch path.c
it raises another issue. Which commit should supply the
"extended attribute description" for path.c? Should it be taken
from the current commit (aka HEAD), otherbranch, or the index?
^ permalink raw reply
* [PATCH] Add ability to specify SMTP server port when using git-send-email.
From: Glenn Rempe @ 2007-09-24 20:34 UTC (permalink / raw)
To: git; +Cc: Glenn Rempe
Add ability to specify custom SMTP server port using
smtpserverport config value or --smtp-server-port command
line option.
Will default to port 25 if smtpssl config is set
to false or --smtp-ssl command line is unset.
Will default to port 465 if smtpssl config is set
to true or --smtp-ssl is set.
User can specify any arbitrary port number for standard or
SSL connections.
Users should be aware that sending auth info over non-ssl
connections may be unsafe.
Signed-off-by: Glenn Rempe <glenn@rempe.us>
---
git-send-email.perl | 48 +++++++++++++++++++++++++++++++++++++-----------
1 files changed, 37 insertions(+), 11 deletions(-)
diff --git a/git-send-email.perl b/git-send-email.perl
index 4031e86..7c9c302 100755
--- a/git-send-email.perl
+++ b/git-send-email.perl
@@ -79,6 +79,10 @@ Options:
--smtp-server If set, specifies the outgoing SMTP server to use.
Defaults to localhost.
+ --smtp-server-port If set, specifies the port on the outgoing SMTP
+ server to use. Defaults to port 25 unless --smtp-ssl is set in
+ which case it will default to port 465.
+
--smtp-user The username for SMTP-AUTH.
--smtp-pass The password for SMTP-AUTH.
@@ -172,7 +176,7 @@ my ($quiet, $dry_run) = (0, 0);
# Variables with corresponding config settings
my ($thread, $chain_reply_to, $suppress_from, $signed_off_cc, $cc_cmd);
-my ($smtp_server, $smtp_authuser, $smtp_authpass, $smtp_ssl);
+my ($smtp_server, $smtp_server_port, $smtp_authuser, $smtp_authpass, $smtp_ssl);
my ($identity, $aliasfiletype, @alias_files);
my %config_bool_settings = (
@@ -185,6 +189,7 @@ my %config_bool_settings = (
my %config_settings = (
"smtpserver" => \$smtp_server,
+ "smtpserverport" => \$smtp_server_port,
"smtpuser" => \$smtp_authuser,
"smtppass" => \$smtp_authpass,
"cccmd" => \$cc_cmd,
@@ -204,6 +209,7 @@ my $rc = GetOptions("sender|from=s" => \$sender,
"bcc=s" => \@bcclist,
"chain-reply-to!" => \$chain_reply_to,
"smtp-server=s" => \$smtp_server,
+ "smtp-server-port=s" => \$smtp_server_port,
"smtp-user=s" => \$smtp_authuser,
"smtp-pass=s" => \$smtp_authpass,
"smtp-ssl!" => \$smtp_ssl,
@@ -375,6 +381,14 @@ if (!defined $smtp_server) {
$smtp_server ||= 'localhost'; # could be 127.0.0.1, too... *shrug*
}
+if (!defined $smtp_server_port) {
+ if ($smtp_ssl) {
+ $smtp_server_port = 465 # SSL port
+ } else {
+ $smtp_server_port = 25 # Non-SSL port
+ }
+}
+
if ($compose) {
# Note that this does not need to be secure, but we will make a small
# effort to have it be unique
@@ -604,20 +618,32 @@ X-Mailer: git-send-email $gitversion
} else {
if ($smtp_ssl) {
require Net::SMTP::SSL;
- $smtp ||= Net::SMTP::SSL->new( $smtp_server, Port => 465 );
+ $smtp ||= Net::SMTP::SSL->new( $smtp_server, Port => $smtp_server_port );
}
else {
require Net::SMTP;
- $smtp ||= Net::SMTP->new( $smtp_server );
+ $smtp ||= Net::SMTP->new( $smtp_server . ":" . $smtp_server_port );
}
- $smtp->auth( $smtp_authuser, $smtp_authpass )
- or die $smtp->message if (defined $smtp_authuser);
- $smtp->mail( $raw_from ) or die $smtp->message;
- $smtp->to( @recipients ) or die $smtp->message;
- $smtp->data or die $smtp->message;
- $smtp->datasend("$header\n$message") or die $smtp->message;
- $smtp->dataend() or die $smtp->message;
- $smtp->ok or die "Failed to send $subject\n".$smtp->message;
+
+ # we'll get an ugly error if $smtp was undefined above.
+ # If so we'll catch it and present something friendlier.
+ if ($smtp) {
+
+ if ((defined $smtp_authuser) && (defined $smtp_authpass)) {
+ $smtp->auth( $smtp_authuser, $smtp_authpass ) or die $smtp->message;
+ }
+
+ $smtp->mail( $raw_from ) or die $smtp->message;
+ $smtp->to( @recipients ) or die $smtp->message;
+ $smtp->data or die $smtp->message;
+ $smtp->datasend("$header\n$message") or die $smtp->message;
+ $smtp->dataend() or die $smtp->message;
+ $smtp->ok or die "Failed to send $subject\n".$smtp->message;
+
+ } else {
+ die "Unable to initialize SMTP properly. Is there something wrong with your config?";
+ }
+
}
if ($quiet) {
printf (($dry_run ? "Dry-" : "")."Sent %s\n", $subject);
--
1.5.3.2.83.gc6869
^ permalink raw reply related
* [PATCH] Fixed minor typo in t/t9001-send-email.sh test command line.
From: Glenn Rempe @ 2007-09-24 20:33 UTC (permalink / raw)
To: git; +Cc: Glenn Rempe
The git-send-email command line in the test was missing a single hyphen.
Signed-off-by: Glenn Rempe <glenn@rempe.us>
---
t/t9001-send-email.sh | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/t/t9001-send-email.sh b/t/t9001-send-email.sh
index e9ea33c..83f9470 100755
--- a/t/t9001-send-email.sh
+++ b/t/t9001-send-email.sh
@@ -30,7 +30,7 @@ test_expect_success 'Extract patches' '
'
test_expect_success 'Send patches' '
- git send-email -from="Example <nobody@example.com>" --to=nobody@example.com --smtp-server="$(pwd)/fake.sendmail" $patches 2>errors
+ git send-email --from="Example <nobody@example.com>" --to=nobody@example.com --smtp-server="$(pwd)/fake.sendmail" $patches 2>errors
'
cat >expected <<\EOF
--
1.5.3.2.83.gc6869
^ permalink raw reply related
* Re: [PATCH 7/7] Implement git commit as a builtin command.
From: Kristian Høgsberg @ 2007-09-24 20:27 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7vwsujizli.fsf@gitster.siamese.dyndns.org>
On Fri, 2007-09-21 at 12:32 -0700, Junio C Hamano wrote:
> Kristian Høgsberg <krh@redhat.com> writes:
>
> >> > +
> >> > + /* update the user index file */
> >> > + add_files_to_cache(fd, files, prefix);
> >> > +
> >> > + if (!initial_commit) {
> >> > + tree = parse_tree_indirect(head_sha1);
> >> > + if (!tree)
> >> > + die("failed to unpack HEAD tree object");
> >> > + if (read_tree(tree, 0, NULL))
> >> > + die("failed to read HEAD tree object");
> >> > + }
> >>
> >> Huh? Doesn't this read_tree() defeat the add_files_to_cache()
> >> you did earlier?
> >
> > This is the case where we add the files on the command line
> > to .git/index, but commit from a clean index file corresponding to HEAD
> > with the files from the command line added (partial commit?). The first
> > add_files_to_cache() updates .git/index, then we do read_tree() to build
> > a tmp index from HEAD and then we add the files again. The tmp index is
> > written to a tmp index file.
>
> Still, if you are doing read_tree() that reads into the same
> in-core cache you have just prepared in the add_fiels_to_cache()
> above, potentially overwriting whatever you did, doesn't it?
> That was what I was puzzled about...
Ah, I understand the confusion - add_files_to_cache() will write out the
cache to the given fd and close it. That's not clear, and I've moved
the write+close part back into prepare_index() in the follow-on patches
I sent that shares out add_files_to_cache() with builtin-add.c.
> > ... As for just using an in-memory
> > index, I wanted to do it that way originally, but you have to write it
> > to disk after all for the pre-commit hook.
>
> Ah, I completely forgot about the hook. Ok, scratch the idea of
> not using a temporary index file. The is not much potential for
> performance gain anyway.
Ok, cool, I'll keep the current structure of the code then.
Kristian
^ permalink raw reply
* Re: [PATCH] post-checkout hook, and related docs and tests
From: Josh England @ 2007-09-24 19:33 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7vsl53ap5x.fsf@gitster.siamese.dyndns.org>
On Mon, 2007-09-24 at 11:34 -0700, Junio C Hamano wrote:
> "Josh England" <jjengla@sandia.gov> writes:
>
> >> What's the _semantics_ you are trying to achieve?
> >
> > I'd like to get a hook that runs whenever the working dir gets
> > updated. The 'git-checkout otherbranch path.c' case should
> > run it also, so I view that as a bug.
>
> I think that _is_ INSANE. Do you run the hook for these then?
>
> $ edit path.c
> $ git-cat-file otherbranch:path.c >path.c
>
> Why "git checkout otherbranch path.c" should be any different?
It is different because the file is being updated through the 'git
checkout' interface. The user is not copying the file over by hand,
he/she is asking git to do it for them via 'git checkout'. Granted, the
branch (and HEAD) does not change for this operation, but that shouldn't
matter. It is somewhat in line with the principle of 'least-surprise':
if the hook runs for 'git checkout otherbranch', but not 'git checkout
otherbranch path.c', this could cause confusion and distress to the
user. IMO, it is a 'checkout' so the post-checkout hook should run.
Why is that so insane?
Look at it from the perspective of the intended use of this hook. I'm
trying to use this hook to keep working dir metadata (ownership/perms)
in a consistent state. When I do a 'git checkout otherbranch', the hook
runs, updating perms as needed, and all is well. As is, if I 'git
checkout otherbranch path.c', the file is created with the default
umask, the hook is not run, and path.c potentially (likely) has
incorrect perms. The working dir is now in an inconsistent state and
the worst part is that the next commit will propagate the faulty
metadata for that file.
-JE
^ permalink raw reply
* Re: git-send-email is omitting author and date lines
From: Junio C Hamano @ 2007-09-24 18:43 UTC (permalink / raw)
To: martin f krafft; +Cc: Johannes Schindelin, Hanspeter Kunz, git
In-Reply-To: <20070924173014.GB27816@lapse.madduck.net>
martin f krafft <madduck@madduck.net> writes:
> also sprach Johannes Schindelin <Johannes.Schindelin@gmx.de> [2007.09.24.1210 +0100]:
>> And that is perfectly okay, since as far as the public is
>> concerned, this is the date of the patch.
>
> If you say so. I don't find this at all convincing.
I think that is the reasoning for the current behaviour of
send-email, but it is not unreasonable to have an option to
always add in-body From: and Date: headers to send-email, with a
blessing from a recent post from Linus to the kernel mailing
list:
http://article.gmane.org/gmane.linux.kernel/582450
Notice the part he says he appreciates Andrew's practice and
talks about message being further forwarded by somebody else.
^ 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