* Re: Multi-head pulling series
From: Junio C Hamano @ 2005-08-20 18:54 UTC (permalink / raw)
To: Josef Weidendorfer; +Cc: git
In-Reply-To: <200508181245.58250.Josef.Weidendorfer@gmx.de>
Josef Weidendorfer <Josef.Weidendorfer@gmx.de> writes:
>> $ cat $GIT_DIR/remotes/www
>> URL: http://www.kernel.org/pub/scm/git/git.git/
>> Pull: master:ko-master pu:ko-pu
>> Push: master:master pu:pu foo:bar
>
> Isn't this mixing two kinds of information:
> 1) Some default/persistent mapping of local to remote heads
> 2) The default heads which are pulled/pushed when only giving the remote
I am not convinced myself that default/persistent mapping makes
much sense, and updating the stored mappings dynamically when
the user uses non-default mappings in push/pull as a one-shot
operation does not make any sense at all at least to me. You
should rather consider that the current specification does not
deal with (1) at all. The set of default pull/push refs does
not make much sense without mappings for them, so that is what
the file records.
^ permalink raw reply
* [PATCH] Use .git/remote/origin, not .git/branches/origin.
From: Junio C Hamano @ 2005-08-20 18:25 UTC (permalink / raw)
To: git
In-Reply-To: <7vvf20o4sp.fsf@assigned-by-dhcp.cox.net>
Now multi-head fetch is complete, let's migrate the
default configuration for new repositories created with
the "git clone" command.
The original $GIT_DIR/branches is not deprecated yet, but create
remotes directory by default from the templates as well.
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
git-clone-script | 8 +++++---
templates/remotes-- | 1 +
2 files changed, 6 insertions(+), 3 deletions(-)
create mode 100644 templates/remotes--
8ad3e7efb406377f6903171638c70b7d566254c5
diff --git a/git-clone-script b/git-clone-script
--- a/git-clone-script
+++ b/git-clone-script
@@ -127,6 +127,8 @@ yes,yes)
esac
# Update origin.
-mkdir -p "$D/.git/branches/" &&
-rm -f "$D/.git/branches/origin" &&
-echo "$repo" >"$D/.git/branches/origin"
+mkdir -p "$D/.git/remotes/" &&
+rm -f "$D/.git/remotes/origin" &&
+echo >"$D/.git/remotes/origin" \
+"URL: $repo
+Pull: master:origin"
diff --git a/templates/remotes-- b/templates/remotes--
new file mode 100644
--- /dev/null
+++ b/templates/remotes--
@@ -0,0 +1 @@
+: this is just to ensure the directory exists.
^ permalink raw reply
* [PATCH] Make "git pull" and "git fetch" default to origin
From: Junio C Hamano @ 2005-08-20 18:25 UTC (permalink / raw)
To: git
In-Reply-To: <7vvf20o4sp.fsf@assigned-by-dhcp.cox.net>
Amos Waterland sent in a patch for the pre-multi-head aware
version of "git pull" to do this, but the code changed quite a
bit since then. If there is no argument given to pull from, and
if "origin" makes sense, default to fetch/pull from "origin"
instead of barfing.
[jc: besides, the patch by Amos broke the non-default case where
explicit refspecs are specified, and did not make sure we know
what "origin" means before defaulting to it.]
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
git-fetch-script | 5 ++++-
1 files changed, 4 insertions(+), 1 deletions(-)
6d8fcdbf772f4fc4ec7ae67630b52bc8a07d7b6d
diff --git a/git-fetch-script b/git-fetch-script
--- a/git-fetch-script
+++ b/git-fetch-script
@@ -8,7 +8,10 @@ _x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x4
append=
case "$#" in
0)
- die "Where do you want to fetch from?" ;;
+ test -f "$GIT_DIR/branches/origin" ||
+ test -f "$GIT_DIR/remotes/origin" ||
+ die "Where do you want to fetch from?"
+ set origin ;;
*)
case "$1" in
-a|--a|--ap|--app|--appe|--appen|--append)
^ permalink raw reply
* [PATCH] Infamous 'octopus merge'
From: Junio C Hamano @ 2005-08-20 18:25 UTC (permalink / raw)
To: git
In-Reply-To: <7vvf20o4sp.fsf@assigned-by-dhcp.cox.net>
This script uses the list of heads and their origin multi-head "git
fetch" left in the $GIT_DIR/FETCH_HEAD file, and makes an octopus
merge on top of the current HEAD using them.
The implementation tries to be strict for the sake of safety. It
insists that your working tree is clean (no local changes) and matches
the HEAD, and when any of the merged heads does not automerge, the
whole process is aborted and tries to rewind your working tree is to
the original state.
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
Makefile | 1 +
git-octopus-script | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 104 insertions(+), 0 deletions(-)
create mode 100755 git-octopus-script
325918bdc88517826fb7f14fba87a34b92ea2b52
diff --git a/Makefile b/Makefile
--- a/Makefile
+++ b/Makefile
@@ -72,6 +72,7 @@ SCRIPTS += git-count-objects-script
# SCRIPTS += git-send-email-script
SCRIPTS += git-revert-script
SCRIPTS += git-show-branches-script
+SCRIPTS += git-octopus-script
PROG= git-update-cache git-diff-files git-init-db git-write-tree \
git-read-tree git-commit-tree git-cat-file git-fsck-cache \
diff --git a/git-octopus-script b/git-octopus-script
new file mode 100755
--- /dev/null
+++ b/git-octopus-script
@@ -0,0 +1,103 @@
+#!/bin/sh
+#
+# Copyright (c) 2005 Junio C Hamano
+#
+# Resolve two or more trees recorded in $GIT_DIR/FETCH_HEAD.
+#
+. git-sh-setup-script || die "Not a git archive"
+
+usage () {
+ die "usage: git octopus"
+}
+
+# Sanity check the heads early.
+while read SHA1 REPO
+do
+ test $(git-cat-file -t $SHA1) = "commit" ||
+ die "$REPO given to octopus is not a commit"
+done <"$GIT_DIR/FETCH_HEAD"
+
+head=$(git-rev-parse --verify HEAD) || exit
+
+git-update-cache --refresh ||
+ die "Your working tree is dirty."
+test "$(git-diff-cache --cached "$head")" = "" ||
+ die "Your working tree does not match HEAD."
+
+# MRC is the current "merge reference commit"
+# MRT is the current "merge result tree"
+
+MRC=$head MSG= PARENT="-p $head"
+MRT=$(git-write-tree)
+CNT=1 ;# counting our head
+NON_FF_MERGE=0
+while read SHA1 REPO
+do
+ common=$(git-merge-base $MRC $SHA1) ||
+ die "Unable to find common commit with $SHA1 from $REPO"
+
+ if test "$common" = $SHA1
+ then
+ echo "Already up-to-date: $REPO"
+ continue
+ fi
+
+ CNT=`expr $CNT + 1`
+ PARENT="$PARENT -p $SHA1"
+ MSG="$MSG
+ $REPO"
+
+ if test "$common,$NON_FF_MERGE" = "$MRC,0"
+ then
+ # The first head being merged was a fast-forward.
+ # Advance MRC to the head being merged, and use that
+ # tree as the intermediate result of the merge.
+ # We still need to count this as part of the parent set.
+
+ echo "Fast forwarding to: $REPO"
+ git-read-tree -u -m $head $SHA1 || exit
+ MRC=$SHA1 MRT=$(git-write-tree)
+ continue
+ fi
+
+ NON_FF_MERGE=1
+
+ echo "Trying simple merge with $REPO"
+ git-read-tree -u -m $common $MRT $SHA1 || exit
+ next=$(git-write-tree 2>/dev/null)
+ if test $? -ne 0
+ then
+ echo "Simple merge did not work, trying automatic merge."
+ git-merge-cache -o git-merge-one-file-script -a || {
+ git-read-tree --reset "$head"
+ git-checkout-tree -f -q -u -a
+ die "Automatic merge failed; should not be doing Octopus"
+ }
+ next=$(git-write-tree 2>/dev/null)
+ fi
+ MRC=$common
+ MRT=$next
+done <"$GIT_DIR/FETCH_HEAD"
+
+# Just to be careful in case the user feeds nonsense to us.
+case "$CNT" in
+1)
+ echo "No changes."
+ exit 0 ;;
+2)
+ echo "Not an Octopus; making an ordinary commit."
+ MSG="Merge "`expr "$MSG" : '. \(.*\)'` ; # remove LF and TAB
+ ;;
+*)
+ # In an octopus, the original head is just one of the equals,
+ # so we should list it as such.
+ HEAD_LINK=`readlink "$GIT_DIR/HEAD"`
+ MSG="Octopus merge of the following:
+
+ $HEAD_LINK from .$MSG"
+ ;;
+esac
+result_commit=$(echo "$MSG" | git-commit-tree $MRT $PARENT)
+echo "Committed merge $result_commit"
+echo $result_commit >"$GIT_DIR"/HEAD
+git-diff-tree -p $head $result_commit | git-apply --stat
^ permalink raw reply
* [PATCH] Retire git-parse-remote.
From: Junio C Hamano @ 2005-08-20 18:25 UTC (permalink / raw)
To: git
In-Reply-To: <7vvf20o4sp.fsf@assigned-by-dhcp.cox.net>
Update git-pull to match updated git-fetch and allow pull to
fetch from multiple remote references. There is no support for
resolving more than two heads, which will be done with "git
octopus".
Update "git ls-remote" to use git-parse-remote-script.
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
Makefile | 2 +
git-ls-remote-script | 4 +--
git-parse-remote | 79 --------------------------------------------------
git-pull-script | 14 ++++++---
4 files changed, 12 insertions(+), 87 deletions(-)
delete mode 100755 git-parse-remote
07c44b628e605c4e7fead8ff9e191711b7abe301
diff --git a/Makefile b/Makefile
--- a/Makefile
+++ b/Makefile
@@ -64,7 +64,7 @@ SCRIPTS=git git-apply-patch-script git-m
git-reset-script git-add-script git-checkout-script git-clone-script \
gitk git-cherry git-rebase-script git-relink-script git-repack-script \
git-format-patch-script git-sh-setup-script git-push-script \
- git-branch-script git-parse-remote git-parse-remote-script git-verify-tag-script \
+ git-branch-script git-parse-remote-script git-verify-tag-script \
git-ls-remote-script git-clone-dumb-http git-rename-script \
git-request-pull-script git-bisect-script
diff --git a/git-ls-remote-script b/git-ls-remote-script
--- a/git-ls-remote-script
+++ b/git-ls-remote-script
@@ -29,8 +29,8 @@ case ",$heads,$tags," in
,,,) heads=heads tags=tags other=other ;;
esac
-. git-parse-remote "$1"
-peek_repo="$_remote_repo"
+. git-parse-remote-script
+peek_repo="$(get_remote_url)"
shift
tmp=.ls-remote-$$
diff --git a/git-parse-remote b/git-parse-remote
deleted file mode 100755
--- a/git-parse-remote
+++ /dev/null
@@ -1,79 +0,0 @@
-: To be included in git-pull and git-fetch scripts.
-
-# A remote repository can be specified on the command line
-# in one of the following formats:
-#
-# <repo>
-# <repo> <head>
-# <repo> tag <tag>
-#
-# where <repo> could be one of:
-#
-# a URL (including absolute or local pathname)
-# a short-hand
-# a short-hand followed by a trailing path
-#
-# A short-hand <name> has a corresponding file $GIT_DIR/branches/<name>,
-# whose contents is a URL, possibly followed by a URL fragment #<head>
-# to name the default branch on the remote side to fetch from.
-
-_remote_repo= _remote_store= _remote_head= _remote_name=
-
-case "$1" in
-*:* | /* | ../* | ./* )
- _remote_repo="$1"
- ;;
-* )
- # otherwise, it is a short hand.
- case "$1" in
- */*)
- # a short-hand followed by a trailing path
- _token=$(expr "$1" : '\([^/]*\)/')
- _rest=$(expr "$1" : '[^/]*\(/.*\)$')
- ;;
- *)
- _token="$1"
- _rest=
- _remote_store="refs/heads/$_token"
- ;;
- esac
- test -f "$GIT_DIR/branches/$_token" ||
- die "No such remote branch: $_token"
-
- _remote_repo=$(cat "$GIT_DIR/branches/$_token")"$_rest"
- ;;
-esac
-
-case "$_remote_repo" in
-*"#"*)
- _remote_head=`expr "$_remote_repo" : '.*#\(.*\)$'`
- _remote_repo=`expr "$_remote_repo" : '\(.*\)#'`
- ;;
-esac
-
-_remote_name=$(echo "$_remote_repo" | sed 's|\.git/*$||')
-
-case "$2" in
-tag)
- _remote_name="tag '$3' of $_remote_name"
- _remote_head="refs/tags/$3"
- _remote_store="$_remote_head"
- ;;
-?*)
- # command line specified a head explicitly; do not
- # store the fetched head as a branch head.
- _remote_name="head '$2' of $_remote_name"
- _remote_head="refs/heads/$2"
- _remote_store=''
- ;;
-'')
- case "$_remote_head" in
- '')
- _remote_head=HEAD ;;
- *)
- _remote_name="head '$_remote_head' of $_remote_name"
- _remote_head="refs/heads/$_remote_head"
- ;;
- esac
- ;;
-esac
diff --git a/git-pull-script b/git-pull-script
--- a/git-pull-script
+++ b/git-pull-script
@@ -1,12 +1,16 @@
#!/bin/sh
#
. git-sh-setup-script || die "Not a git archive"
-. git-parse-remote "$@"
-merge_name="$_remote_name"
-
git-fetch-script "$@" || exit 1
+merge_head=$(sed -e 's/ .*//' "$GIT_DIR"/FETCH_HEAD | tr '\012' ' ')
+merge_name=$(sed -e 's/^[0-9a-f]* //' "$GIT_DIR"/FETCH_HEAD |
+ tr '\012' ' ')
+
+case "$merge_head" in
+'' | *' '?*) die "Cannot resolve multiple heads at the same time (yet)." ;;
+esac
+
git-resolve-script \
"$(cat "$GIT_DIR"/HEAD)" \
- "$(cat "$GIT_DIR"/FETCH_HEAD)" \
- "Merge $merge_name"
+ $merge_head "Merge $merge_name"
^ permalink raw reply
* [PATCH] Multi-head fetch.
From: Junio C Hamano @ 2005-08-20 18:25 UTC (permalink / raw)
To: git
In-Reply-To: <7vvf20o4sp.fsf@assigned-by-dhcp.cox.net>
Traditionally, fetch takes these forms:
$ git fetch <remote>
$ git fetch <remote> <head>
$ git fetch <remote> tag <tag>
This patch updates it to take
$ git fetch <remote> <refspec>...
where:
- A <refspec> of form "<src>:<dst>" is to fetch the objects
needed for the remote ref that matches <src>, and if <dst>
is not empty, store it as a local <dst>.
- "tag" followed by <next> is just an old way of saying
"refs/tags/<next>:refs/tags/<next>"; this mimics the
current behaviour of the third form above and means "fetch
that tag and store it under the same name".
- A single token <refspec> without colon is a shorthand for
"<refspec>:" That is, "fetch that ref but do not store
anywhere".
- when there is no <refspec> specified
- if <remote> is the name of a file under $GIT_DIR/remotes/
(i.e. a new-style shorthand), then it is the same as giving
the <refspec>s listed on Pull: line in that file.
- if <remote> is the name of a file under $GIT_DIR/branches/
(i.e. an old-style shorthand, without trailing path), then it
is the same as giving a single <refspec>
"<remote-name>:refs/heads/<remote>" on the command line, where
<remote-name> is the remote branch name (defaults to HEAD, but
can be overridden by .git/branches/<remote> file having the
URL fragment notation). That is, "fetch that branch head and
store it in refs/heads/<remote>".
- otherwise, it is the same as giving a single <refspec>
that is "HEAD:".
The SHA1 object names of fetched refs are stored in FETCH_HEAD,
one name per line, with a comment to describe where it came from.
This is later used by "git resolve" and "git octopus".
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
git-fetch-script | 193 ++++++++++++++++++++++++++++++++++++++++++------------
1 files changed, 149 insertions(+), 44 deletions(-)
d947289005049c67f1dded517a1a6a8843fcf4a3
diff --git a/git-fetch-script b/git-fetch-script
--- a/git-fetch-script
+++ b/git-fetch-script
@@ -1,54 +1,159 @@
#!/bin/sh
#
. git-sh-setup-script || die "Not a git archive"
-. git-parse-remote "$@"
-merge_repo="$_remote_repo"
-merge_head="$_remote_head"
-merge_store="$_remote_store"
-
-TMP_HEAD="$GIT_DIR/TMP_HEAD"
-
-case "$merge_repo" in
-http://* | https://*)
- if [ -n "$GIT_SSL_NO_VERIFY" ]; then
- curl_extra_args="-k"
- fi
- _x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]' &&
- _x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40" &&
- head=$(curl -nsf $curl_extra_args "$merge_repo/$merge_head") &&
- expr "$head" : "$_x40\$" >/dev/null || {
- echo >&2 "Failed to fetch $merge_head from $merge_repo"
- exit 1
- }
- echo Fetching "$merge_head" using http
- git-http-pull -v -a "$head" "$merge_repo/" || exit
- ;;
-rsync://*)
- rsync -L "$merge_repo/$merge_head" "$TMP_HEAD" || exit 1
- head=$(git-rev-parse TMP_HEAD)
- rm -f "$TMP_HEAD"
- rsync -avz --ignore-existing "$merge_repo/objects/" "$GIT_OBJECT_DIRECTORY/"
- ;;
+. git-parse-remote-script
+_x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'
+_x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40"
+
+append=
+case "$#" in
+0)
+ die "Where do you want to fetch from?" ;;
*)
- head=$(git-fetch-pack "$merge_repo" "$merge_head")
- if h=`expr "$head" : '\([^ ][^ ]*\) '`
+ case "$1" in
+ -a|--a|--ap|--app|--appe|--appen|--append)
+ append=t
+ shift ;;
+ esac
+esac
+remote_nick="$1"
+remote=$(get_remote_url "$@")
+refs=
+rref=
+rsync_slurped_objects=
+
+if test "" = "$append"
+then
+ : >$GIT_DIR/FETCH_HEAD
+fi
+
+append_fetch_head () {
+ head_="$1"
+ remote_="$2"
+ remote_name_="$3"
+ remote_nick_="$4"
+ local_name_="$5"
+
+ # 2.6.11-tree tag would not be happy to be fed to resolve.
+ if git-cat-file commit "$head_" >/dev/null 2>&1
+ then
+ head_=$(git-rev-parse --verify "$head_^0") || exit
+ note_="$head_ $remote_name_ from $remote_nick_"
+ echo "$note_" >>$GIT_DIR/FETCH_HEAD
+ echo >&2 "* committish: $note_"
+ else
+ echo >&2 "* non-commit: $note_"
+ fi
+ if test "$local_name_" != ""
+ then
+ # We are storing the head locally. Make sure that it is
+ # a fast forward (aka "reverse push").
+ fast_forward_local "$local_name_" "$head_" "$remote_" "$remote_name_"
+ fi
+}
+
+fast_forward_local () {
+ case "$1" in
+ refs/tags/*)
+ # Tags need not be pointing at commits so there
+ # is no way to guarantee "fast-forward" anyway.
+ echo "$2" >"$GIT_DIR/$1" ;;
+ refs/heads/*)
+ # NEEDSWORK: use the same cmpxchg protocol here.
+ echo "$2" >"$GIT_DIR/$1.lock"
+ if test -f "$GIT_DIR/$1"
then
- head=$h
+ local=$(git-rev-parse --verify "$1^0") &&
+ mb=$(git-merge-base "$local" "$2") &&
+ case "$2,$mb" in
+ $local,*)
+ echo >&2 "* $1: same as $4"
+ echo >&2 " from $3"
+ ;;
+ *,$local)
+ echo >&2 "* $1: fast forward to $4"
+ echo >&2 " from $3"
+ ;;
+ *)
+ false
+ ;;
+ esac || {
+ mv "$GIT_DIR/$1.lock" "$GIT_DIR/$1.remote"
+ echo >&2 "* $1: does not fast forward to $4"
+ echo >&2 " from $3; leaving it in '$1.remote'"
+ }
+ else
+ echo >&2 "* $1: storing $4"
+ echo >&2 " from $3."
fi
+ test -f "$GIT_DIR/$1.lock" &&
+ mv "$GIT_DIR/$1.lock" "$GIT_DIR/$1"
;;
-esac || exit 1
-
-git-rev-parse --verify "$head" > /dev/null || exit 1
+ esac
+}
-case "$merge_store" in
-'')
+for ref in $(get_remote_refs_for_fetch "$@")
+do
+ refs="$refs $ref"
+
+ # These are relative path from $GIT_DIR, typically starting at refs/
+ # but may be HEAD
+ remote_name=$(expr "$ref" : '\([^:]*\):')
+ local_name=$(expr "$ref" : '[^:]*:\(.*\)')
+
+ rref="$rref $remote_name"
+
+ # There are transports that can fetch only one head at a time...
+ case "$remote" in
+ http://* | https://*)
+ if [ -n "$GIT_SSL_NO_VERIFY" ]; then
+ curl_extra_args="-k"
+ fi
+ head=$(curl -nsf $curl_extra_args "$remote/$remote_name") &&
+ expr "$head" : "$_x40\$" >/dev/null ||
+ die "Failed to fetch $remote_name from $remote"
+ echo Fetching "$remote_name from $remote" using http
+ git-http-pull -v -a "$head" "$remote/" || exit
;;
+ rsync://*)
+ TMP_HEAD="$GIT_DIR/TMP_HEAD"
+ rsync -L "$remote/$remote_name" "$TMP_HEAD" || exit 1
+ head=$(git-rev-parse TMP_HEAD)
+ rm -f "$TMP_HEAD"
+ test "$rsync_slurped_objects" || {
+ rsync -avz --ignore-existing "$remote/objects/" \
+ "$GIT_OBJECT_DIRECTORY/" || exit
+ rsync_slurped_objects=t
+ }
+ ;;
+ *)
+ # We will do git native transport with just one call later.
+ continue ;;
+ esac
+
+ append_fetch_head "$head" "$remote" "$remote_name" "$remote_nick" "$local_name"
+
+done
+
+case "$remote" in
+http://* | https://* | rsync://* )
+ ;; # we are already done.
*)
- echo "$head" > "$GIT_DIR/$merge_store"
-esac &&
-
-# FETCH_HEAD is fed to git-resolve-script which will eventually be
-# passed to git-commit-tree as one of the parents. Make sure we do
-# not give a tag object ID.
-
-git-rev-parse "$head^0" >"$GIT_DIR/FETCH_HEAD"
+ git-fetch-pack "$remote" $rref |
+ while read sha1 remote_name
+ do
+ found=
+ for ref in $refs
+ do
+ case "$ref" in
+ $remote_name:*)
+ found="$ref"
+ break ;;
+ esac
+ done
+
+ local_name=$(expr "$found" : '[^:]*:\(.*\)')
+ append_fetch_head "$sha1" "$remote" "$remote_name" "$remote_nick" "$local_name"
+ done
+ ;;
+esac
^ permalink raw reply
* [PATCH] Start adding the $GIT_DIR/remotes/ support.
From: Junio C Hamano @ 2005-08-20 18:22 UTC (permalink / raw)
To: git
In-Reply-To: <7vvf20o4sp.fsf@assigned-by-dhcp.cox.net>
All the necessary parsing code is in git-parse-remote-script;
update git-push-script to use it.
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
** sorry I made a mistake of letting git send-email to
** send nonsense messages ...
Makefile | 2 -
git-parse-remote-script | 144 +++++++++++++++++++++++++++++++++++++++++++++++
git-push-script | 28 ++-------
3 files changed, 151 insertions(+), 23 deletions(-)
create mode 100755 git-parse-remote-script
284ba9655aedbdaaa897fdcc6aabae97de8d99d1
diff --git a/Makefile b/Makefile
--- a/Makefile
+++ b/Makefile
@@ -64,7 +64,7 @@ SCRIPTS=git git-apply-patch-script git-m
git-reset-script git-add-script git-checkout-script git-clone-script \
gitk git-cherry git-rebase-script git-relink-script git-repack-script \
git-format-patch-script git-sh-setup-script git-push-script \
- git-branch-script git-parse-remote git-verify-tag-script \
+ git-branch-script git-parse-remote git-parse-remote-script git-verify-tag-script \
git-ls-remote-script git-clone-dumb-http git-rename-script \
git-request-pull-script git-bisect-script
diff --git a/git-parse-remote-script b/git-parse-remote-script
new file mode 100755
--- /dev/null
+++ b/git-parse-remote-script
@@ -0,0 +1,144 @@
+#!/bin/sh
+
+. git-sh-setup-script || die "Not a git archive"
+
+get_data_source () {
+ case "$1" in
+ */*)
+ # Not so fast. This could be the partial URL shorthand...
+ token=$(expr "$1" : '\([^/]*\)/')
+ remainder=$(expr "$1" : '[^/]*/\(.*\)')
+ if test -f "$GIT_DIR/branches/$token"
+ then
+ echo branches-partial
+ else
+ echo ''
+ fi
+ ;;
+ *)
+ if test -f "$GIT_DIR/remotes/$1"
+ then
+ echo remotes
+ elif test -f "$GIT_DIR/branches/$1"
+ then
+ echo branches
+ else
+ echo ''
+ fi ;;
+ esac
+}
+
+get_remote_url () {
+ data_source=$(get_data_source "$1")
+ case "$data_source" in
+ '')
+ echo "$1" ;;
+ remotes)
+ sed -ne '/^URL: */{
+ s///p
+ q
+ }' "$GIT_DIR/remotes/$1" ;;
+ branches)
+ sed -e 's/#.*//' "$GIT_DIR/branches/$1" ;;
+ branches-partial)
+ token=$(expr "$1" : '\([^/]*\)/')
+ remainder=$(expr "$1" : '[^/]*/\(.*\)')
+ url=$(sed -e 's/#.*//' "$GIT_DIR/branches/$token")
+ echo "$url/$remainder"
+ ;;
+ *)
+ die "internal error: get-remote-url $1" ;;
+ esac
+}
+
+get_remote_default_refs_for_push () {
+ data_source=$(get_data_source "$1")
+ case "$data_source" in
+ '' | branches | branches-partial)
+ ;; # no default push mapping, just send matching refs.
+ remotes)
+ sed -ne '/^Push: */{
+ s///p
+ }' "$GIT_DIR/remotes/$1" ;;
+ *)
+ die "internal error: get-remote-default-ref-for-push $1" ;;
+ esac
+}
+
+# Subroutine to canonicalize remote:local notation
+canon_refs_list_for_fetch () {
+ for ref
+ do
+ expr "$ref" : '.*:' >/dev/null || ref="${ref}:"
+ remote=$(expr "$ref" : '\([^:]*\):')
+ local=$(expr "$ref" : '[^:]*:\(.*\)')
+ case "$remote" in
+ '') remote=HEAD ;;
+ *) remote="refs/heads/$remote" ;;
+ esac
+ case "$local" in
+ '') local= ;;
+ *) local="refs/heads/$local" ;;
+ esac
+ echo "${remote}:${local}"
+ done
+}
+
+# Returns list of src: (no store), or src:dst (store)
+get_remote_default_refs_for_fetch () {
+ data_source=$(get_data_source "$1")
+ case "$data_source" in
+ '' | branches-partial)
+ echo "HEAD:" ;;
+ branches)
+ remote_branch=$(sed -ne '/#/s/.*#//p' "$GIT_DIR/branches/$1")
+ case "$remote_branch" in '') remote_branch=master ;; esac
+ echo "refs/heads/${remote_branch}:refs/heads/$1"
+ ;;
+ remotes)
+ canon_refs_list_for_fetch $(sed -ne '/^Pull: */{
+ s///p
+ }' "$GIT_DIR/remotes/$1")
+ ;;
+ *)
+ die "internal error: get-remote-default-ref-for-push $1" ;;
+ esac
+}
+
+get_remote_refs_for_push () {
+ case "$#" in
+ 0) die "internal error: get-remote-refs-for-push." ;;
+ 1) get_remote_default_refs_for_push "$@" ;;
+ *) shift; echo "$@" ;;
+ esac
+}
+
+get_remote_refs_for_fetch () {
+ case "$#" in
+ 0)
+ die "internal error: get-remote-refs-for-fetch." ;;
+ 1)
+ get_remote_default_refs_for_fetch "$@" ;;
+ *)
+ shift
+ tag_just_seen=
+ for ref
+ do
+ if test "$tag_just_seen"
+ then
+ echo "refs/tags/${ref}:refs/tags/${ref}"
+ tag_just_seen=
+ continue
+ else
+ case "$ref" in
+ tag)
+ tag_just_seen=yes
+ continue
+ ;;
+ esac
+ fi
+ canon_refs_list_for_fetch "$ref"
+ done
+ ;;
+ esac
+}
diff --git a/git-push-script b/git-push-script
--- a/git-push-script
+++ b/git-push-script
@@ -20,8 +20,6 @@ do
-*)
die "Unknown parameter $1" ;;
*)
- remote="$1"
- shift
set x "$@"
shift
break ;;
@@ -29,27 +27,13 @@ do
shift
done
-case "$remote" in
-*:* | /* | ../* | ./* )
- # An URL, host:/path/to/git, absolute and relative paths.
- ;;
-* )
- # Shorthand
- if expr "$remote" : '..*/..*' >/dev/null
- then
- # a short-hand followed by a trailing path
- shorthand=$(expr "$remote" : '\([^/]*\)')
- remainder=$(expr "$remote" : '[^/]*\(/.*\)$')
- else
- shorthand="$remote"
- remainder=
- fi
- remote=$(sed -e 's/#.*//' "$GIT_DIR/branches/$remote") &&
- expr "$remote" : '..*:' >/dev/null &&
- remote="$remote$remainder" ||
- die "Cannot parse remote $remote"
- ;;
+. git-parse-remote-script
+remote=$(get_remote_url "$@")
+case "$has_all" in
+--all) set x ;;
+'') set x $(get_remote_refs_for_push "$@") ;;
esac
+shift
case "$remote" in
http://* | https://* | git://* | rsync://* )
^ permalink raw reply
* Updated multi-head downloads and $GIT_DIR/remotes/ support
From: Junio C Hamano @ 2005-08-20 18:13 UTC (permalink / raw)
To: git
Now I think all the pieces are glued together. I'll send the
following patches, which are already in the proposed updates
branch.
I sent an early WIP for some of them, but the patches are
reorganized for easier review and applies on top of the current
"master" branch.
This series consists of the following:
Start adding the $GIT_DIR/remotes/ support.
Multi-head fetch.
Retire git-parse-remote.
Infamous 'octopus merge'
Make "git pull" and "git fetch" default to origin
Use .git/remote/origin, not .git/branches/origin.
The issues I discussed in "Multi-head fetches, pulls, and a King
Ghidorah" are addressed there, and the examples in "MyGITDay"
message I sent earlier should work with these patches. I'll
work on adding some documentation, maybe in howto or tutorial
format, over the weekend.
-jc
^ permalink raw reply
* Re: "Publishing your work" questions?
From: Junio C Hamano @ 2005-08-20 17:42 UTC (permalink / raw)
To: Linus Torvalds; +Cc: git
In-Reply-To: <Pine.LNX.4.58.0508200911250.3317@g5.osdl.org>
Linus Torvalds <torvalds@osdl.org> writes:
> /*
> * Go look for quoted single-ticks. They are always
> * quoted as '\'', we don't accept anything else
> */
Oh, I am extremely glad to see that somebody else understands
exactly why I do things in the "seemingly very unoptimized" way
in sq_quote() --- it allows easy parsing for non-shell users.
^ permalink raw reply
* Re: "Publishing your work" questions?
From: Linus Torvalds @ 2005-08-20 16:12 UTC (permalink / raw)
To: Alan Chandler; +Cc: git
In-Reply-To: <Pine.LNX.4.58.0508200821220.3317@g5.osdl.org>
On Sat, 20 Aug 2005, Linus Torvalds wrote:
>
> But yes, you _should_ be able to do it with that ultra-simplistic login
> shell. Probably just a 5-liner main() function or something.
This is entirely untested, and a lot more than five lines of code. Edit
until it works.
Linus
----
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
static char *parse_argument(char *orig)
{
int i;
int len = strlen(orig);
/* We only accept properly quoted arguments */
if (len < 2 || orig[0] != '\'' || orig[len-1] != '\'')
exit(2);
orig[len-1] = 0;
orig++;
len -= 2;
/*
* Go look for quoted single-ticks. They are always
* quoted as '\'', we don't accept anything else
*/
for (i = 0; len ; i++, len--) {
char c = orig[i];
if (c != '\'')
continue;
if (len < 4 || memcmp(orig+i, "'\\''", 4))
exit(2);
len -= 3;
memmove(orig+1, orig+4, len+1);
}
return orig;
}
int main(int argc, char **argv)
{
int i;
char *cmd, *arg;
if (argc < 2)
exit(1);
i = 2;
cmd = argv[1];
if (!strcmp(cmd, "-c"))
cmd = argv[i++];
/* We're not going to allow anything else */
if (argc != i)
exit(1);
/*
* Right now we only accept "upload" commands, but
* we could have some maintenance commands too, to
* create new archives or delete old ones..
*/
if (strncmp(cmd, "git-upload-pack ", 16))
exit(1);
arg = parse_argument(cmd+16);
execlp("git-upload-pack", "git-upload-pack", arg, NULL);
exit(3);
}
^ permalink raw reply
* Subject: [PATCH] Fix git-commit-script to output on stderr when -v fails
From: Marco Costalba @ 2005-08-20 16:07 UTC (permalink / raw)
To: junkio; +Cc: git
From: Marco Costalba <mcostalba@yahoo.it>
Date: 1124553736 +0200
When git-commit-script is called with -v option and
verify test fails result is print on stdout
instead of stderr.
Signed-off-by: Marco Costalba <mcostalba@yahoo.it>
---
git-commit-script | 10 +++++-----
1 files changed, 5 insertions(+), 5 deletions(-)
676a1dcf50a5abc3bc9751c9dbb0146ae31ebfc9
diff --git a/git-commit-script b/git-commit-script
--- a/git-commit-script
+++ b/git-commit-script
@@ -113,16 +113,16 @@ t)
sub bad_line {
my ($why, $line) = @_;
if (!$found_bad) {
- print "*\n";
- print "* You have some suspicious patch lines:\n";
- print "*\n";
+ print STDERR "*\n";
+ print STDERR "* You have some suspicious patch lines:\n";
+ print STDERR "*\n";
$found_bad = 1;
}
if ($reported_filename ne $filename) {
- print "* In $filename\n";
+ print STDERR "* In $filename\n";
$reported_filename = $filename;
}
- print "* $why (line $lineno)\n$line\n";
+ print STDERR "* $why (line $lineno)\n$line\n";
}
open $fh, "-|", qw(git-diff-cache -p -M --cached HEAD);
while (<$fh>) {
__________________________________________________
Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com
^ permalink raw reply
* Re: "Publishing your work" questions?
From: Linus Torvalds @ 2005-08-20 15:52 UTC (permalink / raw)
To: Alan Chandler; +Cc: git
In-Reply-To: <200508201457.00725.alan@chandlerfamily.org.uk>
On Sat, 20 Aug 2005, Alan Chandler wrote:
>
> If I switch over to git, I assume I run git-daemon from inetd.
Yes. Use the "--inetd" flag, and open port 9418 instead.
> a) Is this what the git://my.domain.com/path/to/repository url refers to
> (neither get-pull-script nor git-fetch-script man pages actually say what
> this form means) ?
Yes.
> b) I can't find any mention in the documentation of what the default port
> should be. What is it?
The default one is 9418, although you can use "--port=xxx" to set it to
something else. Obviously, if you put it at some other port, you either
need to re-compile the client side with the new port number (it's
DEFAULT_GIT_PORT in cache.h) or need to use
git://my.domain.com:<port>/path/to/repository
> c) Is git-daemon multithreaded (ie do I use nowait in inetd.conf)?
Yup, it's entirely safe to run tons of them concurrently.
You can also run the git deamon without inetd, and it will do it's own
serving. That normally limits it to 25 connections at a time.
> d) Is it possible to ensure that external accesses can't access anywhere in my
> filesystem?
Yes. The first thing the git-deamon will do is to chdir to the argument
(and add ".git" to the end if it can't find the exact path), and then look
up a file called "git-daemon-export-ok". If that file does not exist, it
will exit.
This means, btw, that it will _not_ export any random git directory by
default, much less anything else. You literally have to mark your git
directories for export explicitly by doing a "touch git-daemon-export-ok"
in the .git directory.
See "daemon.c: upload()" for some of the details.
> e) If I put my public key in ~git/.ssh/authorized_keys on the server, I can
> act as user git on the server via ssh. Does git push support this?
Yes. That's the normal way to do it. The anonymous "git://" protocol can
only do reads (adn it is entirely anonymous). For pushes, you _have_ to
use ssh, either through
git push my.domain.com:/path/to/repository
or
git push ssh://my.domain.com/path/to/repository
(and you can obviously shorthand the format by putting it into your
.git/remotes/ files, so that you can do things like "git push public".)
> f) If I can do e), then perhaps [need to read the docs a bit harder] I can set
> up my user git on the machine to use git-receive-pack as its login shell.
> Will this work? - the tutorial talks about needing .bashrc to set up the
> $PATH environment, but are there any other hidden gotchas?
There shouldn't be any other gotchas. But no, you can't _quite_ use
git-receive-pack as the login shell. Why? Because if you have it as your
login shell, it will get the wrong arguments: it will get:
0: git-receive-pack
1: -c
2: git-receive-pack '/path/to/repository'
and you'd need to have some ultra-simple shell that took this, verified
the proper arguments, and turned it into an
execvp(git-receive-pack, /path/to/repository, NULL);
But yes, you _should_ be able to do it with that ultra-simplistic login
shell. Probably just a 5-liner main() function or something.
Linus
^ permalink raw reply
* "Publishing your work" questions?
From: Alan Chandler @ 2005-08-20 13:57 UTC (permalink / raw)
To: git
I am planning my way through switching over to using git (as opposed to
subversion - via svnserve) to publish some stuff.
At the moment I leave a hole in my firewall for port 3690 and svnserve is run
as a daemon from inetd. I use svnserve's own user/realm management to limit
the repositories I make public.
If I switch over to git, I assume I run git-daemon from inetd.
BUT
a) Is this what the git://my.domain.com/path/to/repository url refers to
(neither get-pull-script nor git-fetch-script man pages actually say what
this form means) ?
b) I can't find any mention in the documentation of what the default port
should be. What is it?
c) Is git-daemon multithreaded (ie do I use nowait in inetd.conf)?
d) Is it possible to ensure that external accesses can't access anywhere in my
filesystem?
e) If I put my public key in ~git/.ssh/authorized_keys on the server, I can
act as user git on the server via ssh. Does git push support this?
f) If I can do e), then perhaps [need to read the docs a bit harder] I can set
up my user git on the machine to use git-receive-pack as its login shell.
Will this work? - the tutorial talks about needing .bashrc to set up the
$PATH environment, but are there any other hidden gotchas?
--
Alan Chandler
http://www.chandlerfamily.org.uk
^ permalink raw reply
* Re: My GIT Day
From: Johannes Schindelin @ 2005-08-20 11:02 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7voe7tqpae.fsf@assigned-by-dhcp.cox.net>
Hi,
On Fri, 19 Aug 2005, Junio C Hamano wrote:
> $ git checkout pu
> $ git reset master
>
> This checks out the head of "pu" branch, and then resets the
> index file to match "master" and updates .git/refs/heads/pu.
>
> What it does _not_ do is to update my working tree to match the
> index file. Linus recommends to do "git checkout -f" at this
> point, but I typically do this instead:
>
> $ git diff -R -p | git apply
>
> Note. This is an embarrassingly expensive way; the only thing
> it buys me over "git checkout -f" is that it removes the files
> that were introduced in "pu" branch that did not exist in the
> "master" head. I have to come up with a not so expensive way to
> do this.
How about this?
$ git reset master
$ rm -i $(git-diff-tree ORIG_HEAD HEAD | grep "^.\{97\}D" | cut -c 100-)
$ git checkout -f
Ciao,
Dscho
^ permalink raw reply
* [PATCH] Call prune-packed from "git prune" as well.
From: Junio C Hamano @ 2005-08-20 4:41 UTC (permalink / raw)
To: git
Add -n (dryrun) flag to git-prune-packed, and call it from "git prune".
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
git-prune-script | 6 ++++--
prune-packed.c | 16 ++++++++++++----
2 files changed, 16 insertions(+), 6 deletions(-)
51890a64eb152fb914d0dd3676f549ab8d8cc49a
diff --git a/git-prune-script b/git-prune-script
--- a/git-prune-script
+++ b/git-prune-script
@@ -3,10 +3,11 @@
. git-sh-setup-script || die "Not a git archive"
dryrun=
+echo=
while case "$#" in 0) break ;; esac
do
case "$1" in
- -n) dryrun=echo ;;
+ -n) dryrun=-n echo=echo ;;
--) break ;;
-*) echo >&2 "usage: git-prune-script [ -n ] [ heads... ]"; exit 1 ;;
*) break ;;
@@ -20,6 +21,7 @@ sed -ne '/unreachable /{
s|\(..\)|\1/|p
}' | {
cd "$GIT_OBJECT_DIRECTORY" || exit
- xargs $dryrun rm -f
+ xargs $echo rm -f
}
+git-prune-packed $dryrun
diff --git a/prune-packed.c b/prune-packed.c
--- a/prune-packed.c
+++ b/prune-packed.c
@@ -1,6 +1,9 @@
#include "cache.h"
-static const char prune_packed_usage[] = "git-prune-packed (no arguments)";
+static const char prune_packed_usage[] =
+"git-prune-packed [-n]";
+
+static int dryrun;
static void prune_dir(int i, DIR *dir, char *pathname, int len)
{
@@ -18,7 +21,9 @@ static void prune_dir(int i, DIR *dir, c
if (!has_sha1_pack(sha1))
continue;
memcpy(pathname + len, de->d_name, 38);
- if (unlink(pathname) < 0)
+ if (dryrun)
+ printf("rm -f %s\n", pathname);
+ else if (unlink(pathname) < 0)
error("unable to unlink %s", pathname);
}
}
@@ -55,8 +60,11 @@ int main(int argc, char **argv)
const char *arg = argv[i];
if (*arg == '-') {
- /* Handle flags here .. */
- usage(prune_packed_usage);
+ if (!strcmp(arg, "-n"))
+ dryrun = 1;
+ else
+ usage(prune_packed_usage);
+ continue;
}
/* Handle arguments here .. */
usage(prune_packed_usage);
^ permalink raw reply
* My GIT Day
From: Junio C Hamano @ 2005-08-20 3:07 UTC (permalink / raw)
To: git
In-Reply-To: <7vy86y1ibg.fsf@assigned-by-dhcp.cox.net>
Junio C Hamano <junkio@cox.net> writes:
> *1* I should probably write a bit about how I do things in a
> separate message as a how-to.
So here it is.
Note that the version of git on my $PATH is usually the one from
the proposed updates branch, so some of the commands I use in
the following text may not work for you unless you also have
built "pu" one yourself.
I am planning to finish updating, testing and documenting what's
in the current proposed updates branch, and have most of them
graduate to the master branch over the weekend. I am aiming for
doing the 0.99.5 on Wednesday next week.
------------
I have the following heads all the time in my private
repository:
master - the one to be pushed to public "master" branch
pu - master plus various proposed changes
rc - master plus minimum release engineering
ko-master - a copy of public "master" branch head
ko-rc - a copy of public "rc" branch head
My GIT day always starts with this command:
$ git fetch ko
I have this in .git/remotes/ko:
$ cat .git/remotes/ko
URL: master.kernel.org:/pub/scm/git/git.git/
Pull: master:ko-master rc:ko-rc
Push: master pu rc
The Pull: line gives me the default set of <refspec>s to give to
the "git fetch" command. I slurp "master" and "rc" heads from
the public repository at master.kernel.org, and fast-forward my
ko-master and ko-rc branches with them. I do not touch these
two branches in any way other than this "git fetch" fast
forwarding.
I have a few "topic branches" in addition to the above; they
change from time to time. Recently I've been looking at
multi-head fetches, and that work is done in "mhf" branch.
There also is a catch-all topic called "misc". I started them
like this:
$ git branch mhf master
$ git branch misc master
The first thing I do during my GIT day is to process the patches
I received via e-mail. I store them one topic per file in my
working tree, like this:
$ ls +*.txt
+js-glossary.txt +mc-mailinfo.txt
Depending on the quality of the patch, seriousness of the bug
they fix, and the area of the code they touch, they either go
directly to "master", "misc", or sent back to the sender, but
the last one, luckily for me, rarely happens:
$ git checkout master
$ git applymbox -q ./+js-glossary.txt .git/info/signoff
$ git checkout misc
$ git applymbox -q ./+mc-mailinfo.txt please
The last parameter to the applymbox command is the name of a
file that has my signoff message. The latest applymbox in the
"pu" branch has a bit more useful extension to do the same thing
as what "git commit" does.
At this point, I may push out the "master" branch (and nothing
else), like this:
$ git push ko master
This pushes only "master", ignoring the default <refspec>s
defined in the .git/remotes/ko file you saw earlier.
Once I am done with the outside patches, I go back to where I
left off the previous day:
$ git checkout mhf
And I check where my head is relative to the master:
$ git show-branches master mhf
! [master] Yet another tweak
* [mhf] Make git-fetch-script a bit more chatty.
+ Yet another tweak
+ Another tweak in Makefile
+ Make git-fetch-script a bit more chatty.
+ Update git-ls-remote-script
+ ...
+ Start adding the $GIT_DIR/remotes/ support.
++ [PATCH] Allow file removal when "git commit --all" is used.
The output from show-branches is a poor-man's gitk. The named
branches are shown, and '+' sign in each column shows whether
the commit is contained in each branch, and the output stops
where all branches converge, or you hit ^C ;-).
If the mhf branch is way behind, I may choose to first rebase
it, to clean up my history:
$ git rebase master
$ git show-branches master mhf
! [master] Yet another tweak
* [mhf] Make git-fetch-script a bit more chatty.
+ Make git-fetch-script a bit more chatty.
+ Update git-ls-remote-script
+ ...
+ Start adding the $GIT_DIR/remotes/ support.
++ Yet another tweak
I keep working in my topic branches. I may make some other
changes in "misc" topic branch. It's a simple cycle of:
$ edit-and-test
$ git commit -s -a -v
Eventually I get to a good point where it makes sense to push
things to the public repository.
$ git show-branches master mhf misc
! [master] Yet another tweak
* [mhf] Make git-fetch-script a bit more chatty.
! [misc] Add hooks to tools/git-applypatch.
+ Make git-fetch-script a bit more chatty.
+ Update git-ls-remote-script
+ ...
+ Start adding the $GIT_DIR/remotes/ support.
++ Yet another tweak
++ Another tweak in Makefile
+ Add hooks to tools/git-applypatch.
+ Add commit hook and make the verification customizable.
+++ [PATCH] Allow file removal when "git commit --all" is used.
As you may have noticed, my topic branches are private and not
pushed to the public repository. Instead, I make a grand total
merge of them into "pu". The proposed update branch is always
rewound and made from the head of the master:
$ git checkout pu
$ git reset master
This checks out the head of "pu" branch, and then resets the
index file to match "master" and updates .git/refs/heads/pu.
What it does _not_ do is to update my working tree to match the
index file. Linus recommends to do "git checkout -f" at this
point, but I typically do this instead:
$ git diff -R -p | git apply
Note. This is an embarrassingly expensive way; the only thing
it buys me over "git checkout -f" is that it removes the files
that were introduced in "pu" branch that did not exist in the
"master" head. I have to come up with a not so expensive way to
do this.
Then before doing the grand total merge, check again where those
heads are:
$ git show-branches master mhf misc pu
! [master] Yet another tweak
! [mhf] Make git-fetch-script a bit more chatty.
! [misc] Add hooks to tools/git-applypatch.
* [pu] Yet another tweak
+ Make git-fetch-script a bit more chatty.
+ Update git-ls-remote-script
+ ...
+ Start adding the $GIT_DIR/remotes/ support.
++ + Yet another tweak
++ + Another tweak in Makefile
+ Add hooks to tools/git-applypatch.
+ Add commit hook and make the verification customizable.
++++ [PATCH] Allow file removal when "git commit --all" is used.
Notice that I did not rebase "misc" above, but that is OK. What
I want to do here is to make new "pu" an Octopus over "master",
merging in all my topic branches (currently "mhf" and "misc").
$ git fetch . mhf misc
Packing 0 objects
Unpacking 0 objects
* committish: a101f32...e5580 refs/heads/mhf from .
* committish: 4426ac7...0c5bc refs/heads/misc from .
This fetches two heads from the current repository (!). The
only reason I do it is that the tentative implementation of "git
octopus" always reads from $GIT_DIR/FETCH_HEAD, and "git fetch"
is the way to populate that file.
$ git octopus
Removing git-parse-remote
Removing git-parse-remote
Committed octopus merge fe1899156bffa4be6722b2ca0b74ff17b76523da
Makefile | 3 -
git-commit-script | 75 +++++-------------
...
tools/git-applypatch | 87 ++++++++++++++++----
15 files changed, 551 insertions(+), 224 deletions(-)
This makes an Octopus out of the master and other two topic
branches. I can make sure that resulting "pu" contains all the
necessary commits from the branches involved:
$ git show-branches master mhf misc pu
! [master] Yet another tweak
! [mhf] Make git-fetch-script a bit more chatty.
! [misc] Add hooks to tools/git-applypatch.
* [pu] Octopus merge of the following:
+ Octopus merge of the following:
+ + Make git-fetch-script a bit more chatty.
+ + Update git-ls-remote-script
+ + ...
+ + Start adding the $GIT_DIR/remotes/ support.
++ + Yet another tweak
++ + Another tweak in Makefile
++ Add hooks to tools/git-applypatch.
++ Add commit hook and make the verification customizable.
++++ [PATCH] Allow file removal when "git commit --all" is used.
And things are now ready to be pushed out. First I sanity check
the differences between ko-master and master (the earlier "git
fetch ko" was done only for this step):
$ git show-branches master ko-master
... and then run "git push":
$ git push ko
This will push "master" and "rc" but would fail to push "pu",
because that is rebased and not based on what is on the public
repository. So I push once more, this time with --force, like
this:
$ git push --force ko pu
This pushes only "pu", ignoring the default <refspec>s defined
in the .git/remotes/ko file you saw earlier. After that, I go
back to reading the mail and wait until the kernel.org mirror
network catches up.
^ permalink raw reply
* Re: gitweb "tag" display
From: Johannes Schindelin @ 2005-08-19 23:43 UTC (permalink / raw)
To: Paul Mackerras; +Cc: Junio C Hamano, git
In-Reply-To: <17158.27011.7426.577686@cargo.ozlabs.ibm.com>
Hi,
On Sat, 20 Aug 2005, Paul Mackerras wrote:
> Hmmm... now I suppose we want a way to use gitk to drive the git
> bisection process... :)
Ssshh! Let sleeping dogs lie! ;-)
Ciao,
Dscho
^ permalink raw reply
* Re: gitweb "tag" display
From: Paul Mackerras @ 2005-08-19 23:21 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7vpssq7vfa.fsf@assigned-by-dhcp.cox.net>
Junio C Hamano writes:
> If you can pop-up a temporary window that shows the tag contents
> when I hover over a tag icon for 2 seconds, and remove that
> temporary window when step outside it would be ideal. It is up
I did something a little easier - if you click on the tag, it now
displays the contents of the tag in the details pane. Is that good
enough?
> to you to implement the part to show my wife's picture, reading
> "object-content-type: image/jpeg" thing ;-). That one was not a
> serious request.
Well, Tk can display inline images in text widgets... :)
> I have two more requests to gitk, which are related to each
> other but not related to the "tag contents" one above:
>
> - if "gitk --all" slurped not just refs/heads and refs/tags but
> everything under refs/* recursively, that would help
> visualizing the bisect status. bisect creates bunch of
> commit object names in refs/bisect.
>
> - I have not looked at the code closely enough, but I cannot
> find how to re-read references. I would appreciate it if it
> allowed it. This relates to the bisect status visualization,
> where the set of references changes _after_ the user started
> gitk.
I implemented these two. There is now a "Reread references" button in
the File menu. References other than tags and heads get displayed in
a light blue box.
Hmmm... now I suppose we want a way to use gitk to drive the git
bisection process... :)
Paul.
^ permalink raw reply
* [PATCH] Make git pull default to origin
From: Amos Waterland @ 2005-08-19 22:14 UTC (permalink / raw)
To: junkio; +Cc: git
Currently, typing `git pull' without a third argument will result in an
error message. Make it default to orgin, which is what the user
typically means.
Signed-off-by: Amos Waterland <apw@rossby.metr.ou.edu>
---
git-pull-script | 11 +++++++++--
1 files changed, 9 insertions(+), 2 deletions(-)
de9b7753b008a1dc1bdd46f87c76ee3cd9a81d19
diff --git a/git-pull-script b/git-pull-script
--- a/git-pull-script
+++ b/git-pull-script
@@ -1,10 +1,17 @@
#!/bin/sh
#
. git-sh-setup-script || die "Not a git archive"
-. git-parse-remote "$@"
+
+if [ $# -eq 0 ]; then
+ remote="origin"
+else
+ remote="$@"
+fi
+
+. git-parse-remote "$remote"
merge_name="$_remote_name"
-git-fetch-script "$@" || exit 1
+git-fetch-script "$remote" || exit 1
git-resolve-script \
"$(cat "$GIT_DIR"/HEAD)" \
^ permalink raw reply
* Re: [RFC] Stgit - patch history / add extra parents
From: Catalin Marinas @ 2005-08-19 22:15 UTC (permalink / raw)
To: Jan Veldeman; +Cc: git
In-Reply-To: <20050819182732.GA5512@fanta>
On Fri, 2005-08-19 at 20:27 +0200, Jan Veldeman wrote:
> hmm, not exactly, for example, when reordering the patches (including the
> top one), I would like to see this in gitk.
> Or when a patch has been dropped (amongst a lot of patches), it should be
> easily spotted.
I tried your patch but the gitk image confused me. I will look again at
it tomorrow (it's quite late in the UK now).
One immediate thing I noticed was that the commits directly accessible
via .git/HEAD are shown as empty by gitk and you would need to follow
the parents to see what they contain. For every freeze, the patches
expand to the right in gitk and the graph could get very complex after
several freeze commands.
--
Catalin
^ permalink raw reply
* [PATCH] Add hooks to tools/git-applypatch.
From: Junio C Hamano @ 2005-08-19 21:41 UTC (permalink / raw)
To: git; +Cc: Linus Torvalds
In-Reply-To: <Pine.LNX.4.58.0508181257320.3412@g5.osdl.org>
This teachs git-applypatch, which is used from git-applymbox, three
hooks, similar to what git-commit-script uses.
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
This is still in the proposed updates branch, along with the
hooks for "git commit". Are people comfortable with the
three-hook arrangements these two commands use?
templates/hooks--applypatch-msg | 14 ++++++
templates/hooks--pre-applypatch | 14 ++++++
tools/git-applypatch | 87 +++++++++++++++++++++++++++++++--------
3 files changed, 97 insertions(+), 18 deletions(-)
create mode 100644 templates/hooks--applypatch-msg
create mode 100644 templates/hooks--pre-applypatch
b5df0d94bf045627e74cf7faef3f51ce5e567aa4
diff --git a/templates/hooks--applypatch-msg b/templates/hooks--applypatch-msg
new file mode 100644
--- /dev/null
+++ b/templates/hooks--applypatch-msg
@@ -0,0 +1,14 @@
+#!/bin/sh
+#
+# An example hook script to check the commit log message taken by
+# applypatch from an e-mail message.
+#
+# The hook should exit with non-zero status after issuing an
+# appropriate message if it wants to stop the commit. The hook is
+# allowed to edit the commit message file.
+#
+# To enable this hook, make this file executable.
+
+test -x "$GIT_DIR/hooks/commit-msg" &&
+ exec "$GIT_DIR/hooks/commit-msg" ${1+"$@"}
+:
diff --git a/templates/hooks--pre-applypatch b/templates/hooks--pre-applypatch
new file mode 100644
--- /dev/null
+++ b/templates/hooks--pre-applypatch
@@ -0,0 +1,14 @@
+#!/bin/sh
+#
+# An example hook script to verify what is about to be committed
+# by applypatch from an e-mail message.
+#
+# The hook should exit with non-zero status after issuing an
+# appropriate message if it wants to stop the commit.
+#
+# To enable this hook, make this file executable.
+
+test -x "$GIT_DIR/hooks/pre-commit" &&
+ exec "$GIT_DIR/hooks/pre-commit" ${1+"$@"}
+:
+
diff --git a/tools/git-applypatch b/tools/git-applypatch
--- a/tools/git-applypatch
+++ b/tools/git-applypatch
@@ -10,58 +10,109 @@
## $3 - "info" file with Author, email and subject
## $4 - optional file containing signoff to add
##
-signoff="$4"
+. git-sh-setup-script || die "Not a git archive."
+
final=.dotest/final-commit
##
## If this file exists, we ask before applying
##
query_apply=.dotest/.query_apply
+
+## We do not munge the first line of the commit message too much
+## if this file exists.
keep_subject=.dotest/.keep_subject
+
+
MSGFILE=$1
PATCHFILE=$2
INFO=$3
-EDIT=${VISUAL:-$EDITOR}
-EDIT=${EDIT:-vi}
+SIGNOFF=$4
+EDIT=${VISUAL:-${EDITOR:-vi}}
export GIT_AUTHOR_NAME="$(sed -n '/^Author/ s/Author: //p' .dotest/info)"
export GIT_AUTHOR_EMAIL="$(sed -n '/^Email/ s/Email: //p' .dotest/info)"
export GIT_AUTHOR_DATE="$(sed -n '/^Date/ s/Date: //p' .dotest/info)"
export SUBJECT="$(sed -n '/^Subject/ s/Subject: //p' .dotest/info)"
-if [ -n "$signoff" -a -f "$signoff" ]; then
- cat $signoff >> $MSGFILE
+if test '' != "$SIGNOFF"
+then
+ if test -f "$SIGNOFF"
+ then
+ SIGNOFF=`cat "$SIGNOFF"` || exit
+ elif case "$SIGNOFF" in yes | true | me | please) : ;; *) false ;; esac
+ then
+ SIGNOFF=`git-var GIT_COMMITTER_IDENT | sed -e '
+ s/>.*/>/
+ s/^/Signed-off-by: /'
+ `
+ else
+ SIGNOFF=
+ fi
+ if test '' != "$SIGNOFF"
+ then
+ LAST_SIGNED_OFF_BY=`
+ sed -ne '/^Signed-off-by: /p' "$MSGFILE" |
+ tail -n 1
+ `
+ test "$LAST_SIGNED_OFF_BY" = "$SIGNOFF" ||
+ echo "$SIGNOFF" >>"$MSGFILE"
+ fi
fi
+
patch_header=
test -f "$keep_subject" || patch_header='[PATCH] '
-(echo "$patch_header$SUBJECT" ; if [ -s $MSGFILE ]; then echo ; cat $MSGFILE; fi ) > $final
+{
+ echo "$patch_header$SUBJECT"
+ if test -s "$MSGFILE"
+ then
+ echo
+ cat "$MSGFILE"
+ fi
+} >"$final"
-f=0
-[ -f $query_apply ] || f=1
+interactive=yes
+test -f "$query_apply" || interactive=no
-while [ $f -eq 0 ]; do
+while [ "$interactive" = yes ]; do
echo "Commit Body is:"
echo "--------------------------"
- cat $final
+ cat "$final"
echo "--------------------------"
echo -n "Apply? [y]es/[n]o/[e]dit/[a]ccept all "
read reply
- case $reply in
- y|Y) f=1;;
+ case "$reply" in
+ y|Y) interactive=no;;
n|N) exit 2;; # special value to tell dotest to keep going
- e|E) $EDIT $final;;
- a|A) rm -f $query_apply
- f=1;;
+ e|E) "$EDIT" "$final";;
+ a|A) rm -f "$query_apply"
+ interactive=no ;;
esac
done
+if test -x "$GIT_DIR"/hooks/applypatch-msg
+then
+ "$GIT_DIR"/hooks/applypatch-msg "$final" || exit
+fi
+
echo
echo Applying "'$SUBJECT'"
echo
-git-apply --index $PATCHFILE || exit 1
+git-apply --index "$PATCHFILE" || exit 1
+
+if test -x "$GIT_DIR"/hooks/pre-applypatch
+then
+ "$GIT_DIR"/hooks/pre-applypatch || exit
+fi
+
tree=$(git-write-tree) || exit 1
echo Wrote tree $tree
-commit=$(git-commit-tree $tree -p $(cat .git/HEAD) < $final) || exit 1
+commit=$(git-commit-tree $tree -p $(cat "$GIT_DIR"/HEAD) < "$final") || exit 1
echo Committed: $commit
-echo $commit > .git/HEAD
+echo $commit > "$GIT_DIR"/HEAD
+
+if test -x "$GIT_DIR"/hooks/post-applypatch
+then
+ "$GIT_DIR"/hooks/post-applypatch
+fi
^ permalink raw reply
* Re: [PATCH] git-rev-list: avoid crash on broken repository
From: Junio C Hamano @ 2005-08-19 21:30 UTC (permalink / raw)
To: Sergey Vlasov; +Cc: git
In-Reply-To: <20050819182835.GA12057@procyon.home>
I humbly appreciate your patch, sir. I am really sorry to be in
the position of having to tell you this, but earlier the Emperor
Penguin himself gave me this shiny blue baseball bat and told me
to show it to any deserving person. Could you please come
closer and kindly extend your neck a little bit more, so I can
swing it well at your head...
Subject: Re: [PATCH] Teach applymbox to keep the Subject: line.
Date: Wed, 17 Aug 2005 13:42:57 -0700
Message-ID: <7vfyt8thv2.fsf@assigned-by-dhcp.cox.net>
Linus Torvalds <torvalds@osdl.org> writes:
> ...
> Ergo: if somebody sends you mime-encoded patches, hit them
> with a baseball bat (politely) and teach them not to do
> that...
I agree with you in principle and that is why I always run
applymbox with the -q flag. Maybe I should start trying the
baseball bat approach to see what happens.
;-)
Anyway, I have merged your fix and pushed it out. Thanks for
the patch.
^ permalink raw reply
* Re: [PATCH] Spell __attribute__ correctly in cache.h.
From: Junio C Hamano @ 2005-08-19 19:53 UTC (permalink / raw)
To: Jason Riedy; +Cc: git
In-Reply-To: <4091.1124463516@lotus.CS.Berkeley.EDU>
Jason Riedy <ejr@EECS.Berkeley.EDU> writes:
> And Junio C Hamano writes:
> - It turns out that your patch breaks GCC build
>
> Whoops, sorry. Your fix works with Sun's cc.
Thanks.
> BTW, how would people feel about replacing the
> setenv() and unsetenv() calls with the older putenv()?
> The Solaris version I have to work on doesn't have
> the nicer functions (and I'm not an admin). I have
> to check that the unsetenv() in git-fsck-cache.c works
> correctly as a putenv before I send along a patch.
No comment on this one at this moment until I do my own digging
a bit.
> There's also the issue that /bin/sh isn't bash, but an
> installation-time helper script can fix that.
My personal preference is to rewrite parts that are easily
unbashified first before going that route, but I suspect that it
would end up being the best practical solution to simply admit
that we depend on bash, start our scripts with "#!/bin/bash",
and rewrite them "#!/usr/local/bin/bash" upon installation;
modulo that it may be a stupid and ugly workaround.
^ permalink raw reply
* Re: git commit (or git-commit-script) question
From: Junio C Hamano @ 2005-08-19 19:52 UTC (permalink / raw)
To: Linus Torvalds; +Cc: git
In-Reply-To: <Pine.LNX.4.58.0508191028190.3412@g5.osdl.org>
Linus Torvalds <torvalds@osdl.org> writes:
> However, one thing to look out for is that if you've marked any files for
> update (with git-update-cache) those will always be committed regardless
> of what arguments you give to "git commit".
Another thing to look out for is that the files you told it
about with "git add" will be included and does not show up in
"git diff", because there currently is no way to record "intent
to add" (rather, "Mr GIT, please keep an eye on this file")
without actually adding a path to the index file for inclusion
in the next commit.
I have a couple of updates to git-commit-script in the proposed
updates branch, and one of the changes is that git-update-cache
in git-commit-script, used when either the --all flag or
explicit paths are given, has a --remove flag there. The reason
it does not need --add flag there as well is a direct
consequence of this asymmetry.
Although I do not think this asymmetry a major source of
confusion, I suspect that we could "fix" it by treating an index
entry with all-zero mode and sha1 as "keep-an-eye-on" entry with
a new flag "git-update-cache --watch <path>" or something like
that. "git-diff-files" would then treat that special entry as a
nonexistent path and would compare it with whatever happens to
be (or lack of it) in the working tree, and "git diff" would
show a diff that creates the file. This needs a tweak or two in
the diffcore machinery as well.
^ permalink raw reply
* Re: [RFC] Stgit - patch history / add extra parents
From: Jan Veldeman @ 2005-08-19 19:48 UTC (permalink / raw)
To: Catalin Marinas; +Cc: git
In-Reply-To: <tnx64u2p81k.fsf@arm.com>
Catalin Marinas wrote:
>
> The patch history feature was available in StGIT 0.1/0.2 releases
> where you should have run a 'stg commit' before 'stg refresh'. The
> commit was handling all the history changes, with separate commit
> messages and refresh was updating the main commit with 2 parents. I
> removed it in 0.3 after some people (I think it was Paul Jackson and
> Daniel Barkalow) convinced me that this would make it yet another SCM
> interface on top of GIT, which wasn't really my intention.
I've quickly reread the threads about stg commit. Am I right to assume that
_all_ history was being recorded? Because this is not what I want. The
person controlling the archive should specify when to record the history.
So for example, you only tag (freeze) the history when exporting the
patches. When an error is being reported on that version, it's easy to view
it and also view the progress that was already been made on those patches.
Best regards,
Jan
^ 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