* Git-aware Darcs: a tutorial
@ 2005-05-09 16:29 2% Juliusz Chroboczek
0 siblings, 0 replies; 200+ results
From: Juliusz Chroboczek @ 2005-05-09 16:29 UTC (permalink / raw)
To: darcs-devel; +Cc: darcs-users, Git Mailing List
0. What is Darcs-git
Darcs-git is a branch of Darcs that can work with Git repositories.
Darcs-git is deliberately Darcs, not Git. All commands either work in
the same way on Git repositories as on Darcs repositories, or they
fail. If you're a Darcs user, you'll like darcs-git. If you're a Git
user, you'll probably find it infuriating.
On the other hand, Darcs-git uses stock Git repositories; a Darcs
command either works as-is on a Git repository, or fails.
1. What you can expect
The following should work reasonably well on Git repositories:
darcs changes
darcs whatsnew
darcs pull
darcs send
darcs record
The following commands work, but have serious performance problems:
darcs diff
darcs changes with a file argument
The following commands should in principle work but haven't been tested:
darcs add
darcs remove
darcs dist
darcs trackdown
The following commands don't work because I'm lazy::
darcs push
darcs unrecord
darcs unpull
darcs amend-record
darcs annotate
darcs rollback
The following commands only work on native Darcs repositories, either
because they don't make sense on Git repositories, or because there
are perfectly good native Git tools to perform their function:
darcs initialize
darcs get/put
darcs check
darcs repair
darcs optimize
darcs mv
darcs replace
darcs resolve
darcs tag
darcs setpref
Remote Git repositories are not supported.
2. A tutorial
(0) Build darcs-git
$ darcs get --partial http://www.pps.jussieu.fr/~jch/software/repos/darcs-git
$ cd darcs-git
$ make darcs
$ make Context.hs
$ make darcs
$ cp darcs ~/bin/
(1) Get a copy of the Linux Git repository:
$ cd /usr/local/src
$ mkdir linux-2.6
$ cd linux-2.6
$ rsync -r rsync://rsync.kernel.org/pub/linux/kernel/people/torvalds/linux-2.6.git .git
$ curl http://rsync.kernel.org/pub/linux/kernel/people/torvalds/linux-2.6.git/HEAD > .git/HEAD
We still need to bring the cache and working directory into a state
that Darcs will be happy with. While this could in principle be done
with Darcs itself, it will be faster to do it with Git:
$ read-tree `cat .git/HEAD`
$ checkout-cache -a
$ update-cache --refresh
(2) Check what the friendly Linux hackers have been up to:
$ darcs changes | more
$ darcs changes -s | more
(3) Create a local clone of the Linux repository:
$ cd ..
$ mkdir linux-2.6-local
$ mkdir linux-2.6-local/.git
$ ln -s `pwd`/linux-2.6/.git/objects linux-2.6-local/.git
$ cp linux-2.6/.git/HEAD linux-2.6-local/.git
$ cd linux-2.6-local
$ read-tree `cat .git/HEAD`
$ checkout-cache -a
$ update-cache --refresh
(4) Commit some work
First, check that Darcs is happy with the new repository.
$ darcs whatsnew
This should take a few seconds at most; if it takes minutes instead,
try running ``update-cache --refresh''.
Okay, let's add myself to the list of Linux maintainers.
$ echo 'P: Juliusz Chroboczek' >> MAINTAINERS
Let's see if Darcs agrees.
$ darcs whatsnew -s
$ darcs whatsnew
Everything looks fine, let's record (commit) this patch.
$ darcs record -a
$ darcs changes | more
$ darcs changes -s | more
(5) Send it upstream
If Linus were using Darcs, we could just send him a Darcs patch, which
is a patch-like data structure that contains just enough context
information to allow Darcs to perform a history-sensitive merge:
$ darcs send ../linux-2.6
However, until Linus switches to Darcs, we're stuck with old-fashioned
patches.
$ darcs diff -u --patch='.' | mail bill@microsoft.com
Unfortunately, until I've spent some time optimising ``darcs diff'',
the above won't terminate on a repository the size of Linux'.
3. Caveats
There is little input validation. In particular, if you enter an
e-mail address that doesn't end in ``>'', Darcs will write a commit
that neither Git nor Darcs itself will be able to parse.
Darcs never updates the Git cache. If you perform many commits using
Darcs, you'll need to manually run ``update-cache --refresh''.
Darcs treats Git merges by reverse-engineering a Darcs merge (thanks
to David Roundy for outlining how that can be done). In practice,
this means that Darcs will collapse as soon as it sees a nontrivial
Git merge.
^ permalink raw reply [relevance 2%]
* Re: [PATCH] rev-list: add "--full-objects" flag.
@ 2005-07-11 16:38 1% ` Linus Torvalds
0 siblings, 0 replies; 200+ results
From: Linus Torvalds @ 2005-07-11 16:38 UTC (permalink / raw)
To: Eric W. Biederman; +Cc: Junio C Hamano, git
On Mon, 11 Jul 2005, Eric W. Biederman wrote:
>
> I guess I was expecting to pull from one tree into another unrelated
> tree. Getting a tree with two heads and then be able to merge them
> together.
You can do it, but you have to do it by hand. It's a valid operation, but
it's not an operation I want people to do by mistake, so it's not
something the trivial helper scripts help with.
The way to do it by hand is to just use something stupid that doesn't
understand what it's doing anyway, and just copy the files over. "cp -a"
or "rsync" works fine. Then just do "git resolve" by hand. It's not very
hard at all, but it's definitely something that should be a special case.
> A couple of questions.
>
> 1) Does git-clone-script when packed copy the entire repository
> or just take a couple of slices of the tree where you have
> references?
It only gets the objects needed for the references, nothing more.
So if you only get one branch, it will leave the objects that are specific
to other branches alone.
> 2) Is there a way for a pack to create deltas against objects
> that are not in the tree? For a dumb repository making incremental
> changes this is ideal.
A pack can only have deltas against objects in that pack. It caan't even
have deltas to other objects in the same tree, it literally is only
_within_ a pack. This is so that each pack is totally independent: you can
always unpack (and verify) the objects in a pack _without_ having anything
else (of course, the end result is often not a full project, and you won't
have any references, but at least the _objects_ are valid).
I don't want to have deltas to outside the pack, because while it's
obviously very nice from a size packing standpoint, it's totally horrid
from an infrastructure standpoint. It would make it possible to have
circular dependencies (ie deltas against each other) that could only be
resolved by having a third pack (or the unpacked object).
It would also means that you may have to have two packs mapped at the same
time to unpack them, which was very much against what I was aiming for: I
think that in the long run, for truly huge projects, you'd want to have a
history of packs, each maybe a gigabyte in size, and you may be in the
situation that you simply cannot have two packs mapped at the same time
because you don't have enough virtual memory for it.
So then inter-pack deltas would mean that you'd have to have "partial pack
mapping" etc horrid special case logic. Right now, because a pack is
always self-sufficient, you know that in order to unpack an object, if you
find it in the index file, you will be able to unpack it by just mapping
that pack and going off..
So the rule is: don't pack too often. The unpacked objects are actually
working really really well as long as you don't have tens of thousands of
them. Having a few hundred (or even a few thousand) unpacked objects is
not a problem at all. Then you do a "git repack" when it starts getting
uncomfortable, and you you continue.
Linus
^ permalink raw reply [relevance 1%]
* [PATCH] fetch/pull: short-hand notation for remote repositories.
@ 2005-07-16 7:16 3% ` Junio C Hamano
0 siblings, 0 replies; 200+ results
From: Junio C Hamano @ 2005-07-16 7:16 UTC (permalink / raw)
To: Linus Torvalds; +Cc: git
Since pull and fetch are done often against the same remote
repository repeatedly, keeping the URL to pull from along with
the name of the head to use in $GIT_DIR/branches/$name makes a
lot of sense. Adopt that convention from Cogito, and try to be
compatible when possible; storing a partial URL and completing
it with a trailing path may not be understood by Cogito.
While we are at it, fix pulling a tag. Earlier, we updated only
refs/tags/$tag without updating FETCH_HEAD, and called
resolve-script using a stale (or absent) FETCH_HEAD.
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
Makefile | 2 +
git-fetch-script | 36 ++++++++++++++-----------
git-parse-remote | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
git-pull-script | 19 ++-----------
4 files changed, 104 insertions(+), 32 deletions(-)
create mode 100755 git-parse-remote
431b72ee18b73aac44048ac6c4cb62e0618c6f6e
diff --git a/Makefile b/Makefile
--- a/Makefile
+++ b/Makefile
@@ -36,7 +36,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-branch-script git-parse-remote
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-fetch-script b/git-fetch-script
--- a/git-fetch-script
+++ b/git-fetch-script
@@ -1,33 +1,39 @@
#!/bin/sh
#
-destination=FETCH_HEAD
-
-merge_repo=$1
-merge_name=${2:-HEAD}
-if [ "$2" = "tag" ]; then
- merge_name="refs/tags/$3"
- destination="$merge_name"
-fi
-
. 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://*)
- head=$(wget -q -O - "$merge_repo/$merge_name") || exit 1
- echo Fetching $head using http
- git-http-pull -v -a "$head" "$merge_repo/"
+ head=$(wget -q -O - "$merge_repo/$merge_head") || exit 1
+ echo Fetching "$merge_head" using http
+ git-http-pull -v -a "$merge_head" "$merge_repo/"
;;
rsync://*)
- rsync -L "$merge_repo/$merge_name" "$TMP_HEAD" || exit 1
+ 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/"
;;
*)
- head=$(git-fetch-pack "$merge_repo" "$merge_name")
+ head=$(git-fetch-pack "$merge_repo" "$merge_head")
;;
esac || exit 1
+
git-rev-parse --verify "$head" > /dev/null || exit 1
-echo "$head" > "$GIT_DIR/$destination"
+
+case "$merge_store" in
+'')
+ 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"
diff --git a/git-parse-remote b/git-parse-remote
new file mode 100755
--- /dev/null
+++ b/git-parse-remote
@@ -0,0 +1,79 @@
+: 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_head="refs/heads/$_remote_head"
+ _remote_name="head '$_remote_head' of $_remote_name"
+ ;;
+ esac
+ ;;
+esac
diff --git a/git-pull-script b/git-pull-script
--- a/git-pull-script
+++ b/git-pull-script
@@ -1,23 +1,10 @@
#!/bin/sh
#
. git-sh-setup-script || die "Not a git archive"
+. git-parse-remote "$@"
+merge_name="$_remote_name"
-merge_repo=$1
-
-merge_name=$(echo "$1" | sed 's:\.git/*$::')
-merge_head=HEAD
-type=head
-if [ "$2" = "tag" ]; then
- type=tag
- shift
-fi
-if [ "$2" ]
-then
- merge_name="$type '$2' of $merge_name"
- merge_head="refs/${type}s/$2"
-fi
-
-git-fetch-script "$merge_repo" "$merge_head" || exit 1
+git-fetch-script "$@" || exit 1
git-resolve-script \
"$(cat "$GIT_DIR"/HEAD)" \
^ permalink raw reply [relevance 3%]
* [PATCH 1/3] Start adding the $GIT_DIR/remotes/ support.
@ 2005-08-18 7:39 6% ` Junio C Hamano
0 siblings, 0 replies; 200+ results
From: Junio C Hamano @ 2005-08-18 7:39 UTC (permalink / raw)
To: GIT mailing list; +Cc: Junio C Hamano
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>
---
Makefile | 2 -
git-parse-remote-script | 122 +++++++++++++++++++++++++++++++++++++++++++++++
git-push-script | 28 ++---------
3 files changed, 129 insertions(+), 23 deletions(-)
create mode 100755 git-parse-remote-script
f8892bf17675056cd18a252d3bc4e4ba381fb3bc
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,122 @@
+#!/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 caninicalize 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; canon_refs_list_for_fetch "$@" ;;
+ 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 [relevance 6%]
* [PATCH] Start adding the $GIT_DIR/remotes/ support.
@ 2005-08-20 18:22 6% ` Junio C Hamano
0 siblings, 0 replies; 200+ results
From: Junio C Hamano @ 2005-08-20 18:22 UTC (permalink / raw)
To: git
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 [relevance 6%]
* Re: [BUG] git-show-branch cant show --more
@ 2005-09-19 8:12 3% ` Junio C Hamano
0 siblings, 0 replies; 200+ results
From: Junio C Hamano @ 2005-09-19 8:12 UTC (permalink / raw)
To: Jon Loeliger; +Cc: git
Jon Loeliger <jdl@freescale.com> writes:
> I realize I probably dumbly expected more history out
> of a partial git repository than is actually present,
> but a segmentation fault wasn't a nice way to tell me. :-)
>
> Start with just Paul's repo over here:
>
> rsync://rsync.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc-merge.git
Hmph. That repository does not look partial to me, although it
seems to use alternates to borrow heavily from Linus.
$ git clone rsync://rsync.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc-merge.git ppc-merge
$ git show-branch --more=10
[master] ppc32: Allow user to individual select CHRP/PMAC/PREP config
[master~1] powerpc: Merge simplified sections.h into asm-powerpc
[master~2] powerpc: Remove section free() and linker script bits
[master~3] powerpc: Remove sections use from ppc64 and drivers
[master~4] powerpc: Remove sections use from ppc
[master~5] ppc32: Removed non-inlined versions of local_irq* functions
[master~6] powerpc: Merged ppc_asm.h
[master~7] powerpc: Merge kmap_types.h
[master~8] [NETFILTER]: Solve Kconfig dependency problem
[master~9] [IPV6]: Check connect(2) status for IPv6 UDP socket (Re: xfrm_lookup)
[master~10] [BOND]: Fix bond_init() error path handling.
$ git --version
git version 0.99.7
But in any case you are right. We should barf a bit nicely when
we encounter an corrupt repository. How about something like
this (not fully tested)?
------------
[PATCH] Be nice when running in a corrupt repository.
We may end up trying to print a commit we do not have but only
whose existence is known to us because another commit we have
refer to it.
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
diff --git a/show-branch.c b/show-branch.c
--- a/show-branch.c
+++ b/show-branch.c
@@ -196,8 +196,11 @@ static void show_one_commit(struct commi
{
char pretty[128], *cp;
struct commit_name *name = commit->object.util;
- pretty_print_commit(CMIT_FMT_ONELINE, commit->buffer, ~0,
- pretty, sizeof(pretty));
+ if (commit->object.parsed)
+ pretty_print_commit(CMIT_FMT_ONELINE, commit->buffer, ~0,
+ pretty, sizeof(pretty));
+ else
+ strcpy(pretty, "(unavailable)");
if (!strncmp(pretty, "[PATCH] ", 8))
cp = pretty + 8;
else
^ permalink raw reply [relevance 3%]
* Re: Cogito: cg-clone doesn't like packed tag objects
@ 2005-09-27 17:56 3% ` Linus Torvalds
2005-09-27 18:36 2% ` Junio C Hamano
0 siblings, 1 reply; 200+ results
From: Linus Torvalds @ 2005-09-27 17:56 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Petr Baudis, Tom Prince, git
On Tue, 27 Sep 2005, Junio C Hamano wrote:
>
> This is a bit hard and needs some thinking to do cleanly,
> because what is in info/refs is what is sent from the publisher
> side over git-native protocol at the beginning of the handshake,
> and it is not easy to add that to git-native protocol cleanly
> and backward-compatibly (I think I know how without breaking
> existing clients, but it is not clean).
Argh.
"git-upload-pack" very much on purpose never sends partial object stores:
it really doesn't want to send a tag-object for you to even _look_ at
unless it also sends all the objects that you are missing that the tag
refers to.
I'd really be much happier with the tag fetching being separate.
For example, making
git fetch --tags <dest>
fetch all tags _and_ the objects that they depend on would seem a _lot_
more appropriate.
The thing is, tags really may be totally private. For example, it makes
sense to fetch tags when you pull an official tree (ie my kernel tree, or
your git tree), but it does NOT make sense for me to fetch tags
(automatically or not) when I pull from a developers tree.
That's why git fetch doesn't get the tags by default. It's WRONG.
But we could certainly make it _easier_ to get tags when you want them.
"git-ls-remote" already helps you, and
git-ls-remote ... | cut -f2 | grep '^refs/tags/'
completes the picture. No protocol changes necessary, just some added
magic to git-fetch.sh.
Actually, here's a simple and stupid patch.
Untested as usual, but hey, how hard can it be?
Linus
----
diff --git a/git-fetch.sh b/git-fetch.sh
--- a/git-fetch.sh
+++ b/git-fetch.sh
@@ -5,6 +5,7 @@
_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"
+tags=
append=
force=
update_head_ok=
@@ -17,6 +18,9 @@ do
-f|--f|--fo|--for|--forc|--force)
force=t
;;
+ --tags)
+ tags=t
+ ;;
-u|--u|--up|--upd|--upda|--updat|--update|--update-|--update-h|\
--update-he|--update-hea|--update-head|--update-head-|\
--update-head-o|--update-head-ok)
@@ -151,7 +155,12 @@ case "$update_head_ok" in
;;
esac
-for ref in $(get_remote_refs_for_fetch "$@")
+taglist=
+if [ "$tags" ]; then
+ taglist=$(git-ls-remote "$remote" | awk '/refs\/tags/ { print $2":"$2 }')
+fi
+
+for ref in $(get_remote_refs_for_fetch "$@" $taglist)
do
refs="$refs $ref"
^ permalink raw reply [relevance 3%]
* Re: Cogito: cg-clone doesn't like packed tag objects
2005-09-27 17:56 3% ` Linus Torvalds
@ 2005-09-27 18:36 2% ` Junio C Hamano
0 siblings, 0 replies; 200+ results
From: Junio C Hamano @ 2005-09-27 18:36 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Petr Baudis, Tom Prince, git
Linus Torvalds <torvalds@osdl.org> writes:
> On Tue, 27 Sep 2005, Junio C Hamano wrote:
>>
>> This is a bit hard and needs some thinking to do cleanly,
>> because what is in info/refs is what is sent from the publisher
>> side over git-native protocol at the beginning of the handshake,
>> and it is not easy to add that to git-native protocol cleanly
>> and backward-compatibly (I think I know how without breaking
>> existing clients, but it is not clean).
>
> Argh.
>
> "git-upload-pack" very much on purpose never sends partial object stores:
> it really doesn't want to send a tag-object for you to even _look_ at
> unless it also sends all the objects that you are missing that the tag
> refers to.
>
> I'd really be much happier with the tag fetching being separate.
What Pasky wants to do, which I misunderstood first and gave
essentially the same response to, is to help this senario:
User tracks git.git#master and nothing else, i.e. she pulls
from my master branch from time to time. The tool notices
that I tagged a commit on the master branch (not necessarily
the tip at the time of pulling) with v0.99.8 tag, which she
has not have, and fetches v0.99.8 tag and stores it under
.git/refs/. Currently Cogito does not let her specify
where on the receiving end to place that tag and always
places it in .git/refs/tags/v0.99.8, but that can be fixed
later.
The current ls-remote (or underlying fetch-pack protocol) does
not help this because the SHA1 given to Cogito is the object
name of the tag, and without fetching the tag object and looking
at what it refers to, Pasky cannot say "Oh, this new v0.99.8 tag
is the commit on the branch being tracked".
The protocol extension I had in mind, which I said is not clean,
is from upload_pack(), in addition to the existing send_ref()
call which sends "object-name refname" list like this:
4899334e96a076bb8780968c5075b214aa80fab9 HEAD
d5bc7eecbbb0b9f6122708bf5cd62f78ebdaafd8 refs/heads/maint
3cc35e29ec252d0dca1139106fbaa70cb9ad6ef1 refs/heads/master
4899334e96a076bb8780968c5075b214aa80fab9 refs/heads/pu
348c4c66dacb1810a9bcd592e72f98a465233488 refs/heads/rc
0918385dbd9656cab0d1d81ba7453d49bbc16250 refs/tags/junio-gpg-pub
d6602ec5194c87b0fc87103ca4d67251c76f233a refs/tags/v0.99
f25a265a342aed6041ab0cc484224d9ca54b6f41 refs/tags/v0.99.1
...
we could send phony entries like this:
b92c9c07fe2d0d89c4f692573583c4753b5355d2 deref/tags/junio-gpg-pub
a3eb250f996bf5e12376ec88622c4ccaabf20ea8 deref/tags/v0.99
78d9d414123ad6f4f522ffecbcd9e4a7562948fd deref/tags/v0.99.1
These phony entries tell the receiver what the tags eventually
resolve to. Pasky could use this to see if he has the named
object from the usual fetch path, and if he finds matches,
ask git-fetch-pack to get them.
We would need to teach git-clone and git-fetch to ignore deref/
if they do not already do so.
^ permalink raw reply [relevance 2%]
* GIT 0.99.8
@ 2005-10-03 0:12 3% Junio C Hamano
0 siblings, 0 replies; 200+ results
From: Junio C Hamano @ 2005-10-03 0:12 UTC (permalink / raw)
To: git
Here is 0.99.8. GIT has been doing everything I personally
wanted it to do since mid 0.99.7, and now it has almost
everything I want it to contain, except for a couple of minor
points. I feel that we are ready to finish the last mile for
1.0. Many thanks to everybody who contributed the comments,
eyeballs, and code.
Done in 0.99.8
==============
New Features, Commands, and Enhancements
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* 'git pull' now uses 'git-merge' instead of 'git-resolve', so you can
specify alternative merge strategy to use on its command line.
* 'git pull -s recursive' has been taught about renaming merges,
which may deal with HPA's klibc vs klibc-kbuild situation better.
* Symbolic refs -- instead of using symlinks to express .git/HEAD,
you can have a regular file that stores a single line
'ref: refs/heads/master' in it.
git-update-ref is the preferred way to write into .git/HEAD,
not "echo >.git/HEAD". git-symbolic-ref is the preferred way
to check which underlying ref a symbolic ref .git/HEAD refers
to, not "readlink .git/HEAD".
* A couple of new diff options (-l<num> and --name-status).
* Commit walker over http acquired more SSL options.
* 'git clone' checks out the working tree by default.
Fixes
~~~~~
* Removed unused commands (diff-helper, rev-tree, and export).
* Platforms with only Python 2.3 installed can use recursive merge
strategy.
* Octopus documented.
* Merge is more careful noticing potentially ambiguous situation.
* Git pull does not blindly do Octopus when Pull: lines in remotes
file specifies more than one remote branches.
* Commit walker got safer to use after interrupted downloads.
* Commit walker over http can resume partial downloads.
* More portability fixes for BSD and Solaris.
^ permalink raw reply [relevance 3%]
* [WIP] Implement a test for git-fetch-pack
@ 2005-10-25 21:34 7% Johannes Schindelin
0 siblings, 0 replies; 200+ results
From: Johannes Schindelin @ 2005-10-25 21:34 UTC (permalink / raw)
To: git
It does some basic things right now, but I'll add more.
---
t/t5500-fetch-pack.sh | 142 +++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 142 insertions(+), 0 deletions(-)
diff --git a/t/t5500-fetch-pack.sh b/t/t5500-fetch-pack.sh
new file mode 100755
index 0000000..a5d3a25
--- /dev/null
+++ b/t/t5500-fetch-pack.sh
@@ -0,0 +1,142 @@
+#!/bin/sh
+#
+# Copyright (c) 2005 Johannes Schindelin
+#
+
+test_description='Testing multi_ack pack fetching
+
+'
+. ./test-lib.sh
+
+# Test fetching for an empty, a partial, a full copy, and for a repository,
+# which is not empty but has no common commits (think coolest merge ever).
+
+function add () {
+ local name=$1
+ local branch=$(expr $name : '\(.\)')
+ local text="$@"
+ local parents=""
+
+ shift
+ while test $1; do
+ local sha1=$(eval echo \$$1)
+ test -z "$sha1" && sha1=$1
+ parents="$parents -p $sha1"
+ shift
+ done
+
+ echo "$text" > test.txt
+ git-update-index --add test.txt
+ tree=$(git-write-tree)
+ commit=$(echo "$text" | git-commit-tree $tree $parents 2>/dev/null)
+ export $name=$commit
+ echo $commit > .git/refs/heads/$branch
+ git-symbolic-ref HEAD refs/heads/$branch 2>/dev/null
+}
+
+function tag () {
+ local name=$1
+ local commit=$(eval echo \$$2)
+ local text="$@"
+
+ git-tag -m "$text" $name $commit
+}
+
+function count_objects () {
+ local line="$(git-count-objects)"
+ expr "$line" : '\([^ ]*\)'
+}
+
+function test_expect_object_count () {
+ local repository=$1
+ local count=$2
+
+ expect="$count objects, $count kilobytes"
+ output="$(git-count-objects)"
+ test_expect_success "$repository repository is valid" \
+ "test \"$output\" = \"$expect\""
+}
+
+function check_rep () {
+ local rep=$1
+ local count=$2
+
+ cd $rep
+ test_expect_success "fetch from upstream into $rep" \
+ 'git-fetch-pack -v .. A B C 2> log.txt'
+ git-update-ref HEAD $A46
+ test_expect_success "fsck $rep" 'git-fsck-objects --full'
+ test_expect_object_count $rep $count
+ cd ..
+}
+
+# A1 - A2 - A3 - A4 - A5 - .. - A47
+# \ \ / /
+# B1 - B2 ------ B3 - B4 - B5
+# \ / \
+# C1 - C2 - C3
+
+# the partial copy is cloned at A1-B3-C2 time.
+
+(
+ mkdir empty &&
+ cd empty &&
+ git-init-db 2>/dev/null
+)
+
+add B1
+
+pre_tag_count=$(count_objects)
+
+i=1; while [ $i -le 40 ]; do
+ tag T$i B1
+ i=$(expr $i + 1)
+done
+
+post_tag_count=$(count_objects)
+
+add A1
+add B2 B1 A1
+add B3 B2
+add C1 B2
+add C2 C1
+
+# clone
+git-clone . partial 2>/dev/null
+
+partial_count=$(count_objects)
+
+add A2 A1
+add A3 A2
+add A4 A3 C1
+add C3 C2 B3
+add A5 A4 B3
+add B4 B3
+add B5 B4
+i=5
+while [ $i -le 46 ]; do
+ next=$(expr $i + 1)
+ add A$next A$i
+ i=$next
+done
+
+total_count=$(count_objects)
+
+git-clone . full 2>/dev/null
+
+# let the testing begin
+
+test_expect_success 'precalculated counts' \
+ "test $post_tag_count:$partial_count:$total_count = 43:58:205"
+
+tag_count=$(expr $post_tag_count - $pre_tag_count)
+empty_diff=$(expr $total_count - $tag_count)
+partial_diff=$(expr $total_count - $partial_count)
+
+check_rep empty $empty_diff
+check_rep partial $partial_diff
+check_rep full 0
+
+#gitk --all
+
+test_done
^ permalink raw reply related [relevance 7%]
* Re: git push sends more objects than it needs to
@ 2005-10-31 19:36 2% ` Linus Torvalds
0 siblings, 0 replies; 200+ results
From: Linus Torvalds @ 2005-10-31 19:36 UTC (permalink / raw)
To: Luck, Tony; +Cc: git
On Mon, 31 Oct 2005, Linus Torvalds wrote:
> >
> > Now the "unpack" on kernel.org did the right thing and noticed
> > that over 9000 of the objects were already in the packfile. But
> > I wonder if it couldn't have been smarter and not sent them?
>
> It should have been smarter, but I suspect you got caught by the fact that
> kernel.org by default has git-0.99.8f on it, which has the old
> pre-multi_ack code to figure out what the common commit was.
Oh, actually, I take that back.
This is not the multi-ack code at all, I suspect.
The problem is totally different: you copied the new pack to your
master.kernel.org repository, but you never updated any branches there.
So you had the objects, but git had no way of knowing. The pack generation
doesn't look at what _objects_ you have, it looks at what _refs_ you have.
And your refs were all to the old state.
So git actually did everything right (you can never rely on objects: you
may have a partial object list due to some earlier incomplete pull/push).
This is actually easy enough to fix up in one of several ways:
a) The "don't do that then" approach:
Don't go behind git's back and add objects on your own, and expect git
to realize what you did. ;^p
b) The "live with it" approach:
You copied the pack by hand, and that will keep git-unpack-objects
from duplicating the objects, but you'll still waste time and network
when trying pushing the objects (just once, though).
Ie this is what happened this time: nothing really lost, and the end
result is fine. Now you know why it happened, and you're fine.
c) The "I'm smarter than git" approach:
When you copy my objects, copy my reference to the top-of-tree too
(and rename it). NOTE! Now you need to be really careful, and you need
to make sure you copy _all_ the objects, because if you screw this up,
your repo will be missing objects that you claim are there, and it
will be all your fault.
I really don't advocate this approach at all. It's certainly doable,
but it's also the only approach where you can really screw up.
d) Just let git do it for you.
Copy the pack-files, or add my object directory as an "alternates" for
your object directory, do the "git prune-objects", and then _locally_
on master.kernel.org just do something like
git fetch ..linus-directory.. master:linus
which will still create the unnecessary pack-file and unpack it into
nothingness (since you have the objects in the pack-file you copied by
hand), but at least it won't eat any network bandwidth, and it will do
the right thing if it turns out that I've pushed something after doing
the pack-file, and fetch those individual objects in _addition_ to the
pack-file you snarfed by hand. It will also obviously update a ref in
your tree (the "linus" branch), so now when you send stuff later, it
will know all about the objects you already have.
e) Re-create the tree entirely
Blow away your tree on master entirely, just re-create it locally with
"git clone -l -s" from my tree (which will do all the "alternates"
object files for you), and then populate the result with a simple push
from your home tree.
f) any number of variations on a theme. IOW, there are endless ways to do
this.
Hmm?
Linus
^ permalink raw reply [relevance 2%]
* Re: hgmq vs. StGIT
@ 2005-11-10 16:20 3% ` Catalin Marinas
0 siblings, 0 replies; 200+ results
From: Catalin Marinas @ 2005-11-10 16:20 UTC (permalink / raw)
To: Petr Baudis
Cc: Chris Mason, Chuck Lever, Theodore Ts'o, Joel Becker,
Junio C Hamano, pavel, git
On 09/11/05, Petr Baudis <pasky@suse.cz> wrote:
> A night city, the snow slowly falling. Approaching the roofs covered in
> white and illuminated by the yellow street lighting, dark windows - but
> one dimly glowing, a computer screen inside. Close-up on a hacker:
> $EDITOR opened, lost deep in hack mode, fingers dancing over the
> keyboard. Dreamy-monumental music in the background.
I agree with Pavel here :-)
> StGIT user, only part of the patches in stack, and the rest depends on
> the one currently edited, and I want to record my work on this one.
> I can either:
>
> (i) Just keep per-patch history only.
That's probably the simplest.
> (ii) Keep _both_ per-patch and per-stack history (since I don't want to
> record the stack when I have to keep some patches out of it - the
> history would look like randomly removing and adding tons of patches,
> and jumping around would be difficult because of this too).
It happens to me to keep some patches popped which aren't really part
of the stack (i.e. splitting a big patch, I still keep it in the
unapplied patches to push it later and check what was left after
splitting). From this point of view, (ii) would be better but with the
drawback that you need to have a valid stack with all the patches
pushed.
> (iii) Keep per-patchlist history - do not actually record only our
> current stack, but all the patches StGIT knows about. The patches
> depending on the one currently being changed will not be in consistent
> state, but that's tough. Actually, this seems to be the most viable
> strategy. One question is whether to record if some patch is actually
> applied right now or not (I'd say don't record it since you again have
> the "bouncing problem" otherwise).
(iii) is the most comprehensive method and, as Pavel said, we should
record what patches were applied or not and reproduce them exactly
when retrieving a different state.
Another big problem is the base of the stack, which can change. Would
retrieving an old state of the stack also restore the old the base? I
think it should and its up to the user to rebase it.
A simple way to partially achieve (iii) is to extend the existing
'branch' command to clone the whole series into a new one, including
all the patches. The problem with this approach is that there is no
temporal relation between branches.
How would you expect to switch between different states of the stack?
As Chris Mason mentioned, once you start doing this people might ask
for full SCM features (like diffs between revisions) where the objects
are stack states. This would complicate StGIT quite a lot.
--
Catalin
^ permalink raw reply [relevance 3%]
* Re: [QUESTION] Access to a huge GIT repository.
@ 2005-11-22 9:50 3% ` Junio C Hamano
2005-11-22 10:40 0% ` Franck
0 siblings, 1 reply; 200+ results
From: Junio C Hamano @ 2005-11-22 9:50 UTC (permalink / raw)
To: Franck; +Cc: git
Franck <vagabon.xyz@gmail.com> writes:
> 2005/11/21, Junio C Hamano <junkio@cox.net>:
>> Franck <vagabon.xyz@gmail.com> writes:
>>
>> > ... But since I used grafting to "cut"
>> > my light repo and .git/info/grafts file is not copied during
>> > push/pull/clone operations it's not going to work. Is it a scheme that
>> > could work ?
>>
>> If you tell your downloaders that your repository is incomplete
>> and they need to have at least up to such and such commits from
>> another repository, they should be able to slurp from you.
I was not talking about _your_ case specifically. If you happen
to have based your partial history on top of a single commit
then the set of "such and such commits" might be only one, but
you could for example clone from Linus tip, merge in a couple of
jgarzik branch heads, put your own commits on top of them and
then cauterize your history, stopping at those foreign commits.
In such a case you obviously need to tell others where you
chopped your history off.
^ permalink raw reply [relevance 3%]
* Re: [QUESTION] Access to a huge GIT repository.
2005-11-22 9:50 3% ` Junio C Hamano
@ 2005-11-22 10:40 0% ` Franck
0 siblings, 0 replies; 200+ results
From: Franck @ 2005-11-22 10:40 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
2005/11/22, Junio C Hamano <junkio@cox.net>:
> I was not talking about _your_ case specifically. If you happen
> to have based your partial history on top of a single commit
> then the set of "such and such commits" might be only one, but
> you could for example clone from Linus tip, merge in a couple of
> jgarzik branch heads, put your own commits on top of them and
> then cauterize your history, stopping at those foreign commits.
> In such a case you obviously need to tell others where you
> chopped your history off.
>
I built the lite repository and got an error depending on which
original repo I used to push the lite one. Here is the history:
--------------------------------------------------------------
#
# building my pub repo from the "lite" repository
#
$ git checkout -b lite
$ git-show-branch
* [lite] Merge with Linux 2.6.14.
! [master] Merge with Linux 2.6.14.
! [origin] Merge with db93a82fa9d8b4d6e31c227922eaae829253bb88.
---
# push the initial commit object
$ git push /home/franck/pub/linux/git/linux-lite.git lite
updating 'refs/heads/lite'
from 0000000000000000000000000000000000000000
to 8643db584b46a61c968ae230897869f789bae020
Packing 19558 objects
Unpacking 19558 objects
100% (19558/19558) done
refs/heads/lite: 0000000000000000000000000000000000000000 ->
8643db584b46a61c968ae230897869f789bae020
#
# push first changes from lite repositoy -> KO
#
$ making some hard work
$ git commit -m "Did some hard work"
$ git push /home/franck/pub/linux/git/linux-lite.git lite
updating 'refs/heads/lite'
from 8643db584b46a61c968ae230897869f789bae020
to 730518eea7523afd5b7891bb7849973cab52d963
Packing 0 objects
Unpacking 0 objects
error: unpack should have generated
730518eea7523afd5b7891bb7849973cab52d963, but I can't find it!
$
#
# push first changes from "full" repository -> OK
#
# go to full repository and checkout linux.2.6.14
$ git commit -m "Did some hard work"
$ git push /home/franck/pub/linux/git/linux-lite.git lite
updating 'refs/heads/lite'
from 8643db584b46a61c968ae230897869f789bae020
to 067d05600fe7251b8c923fbeb9ba0068ee272110
Packing 108 objects
Unpacking 108 objects
100% (108/108) done
refs/heads/lite: 8643db584b46a61c968ae230897869f789bae020 ->
067d05600fe7251b8c923fbeb9ba0068ee272110
--------------------------------------------------------------
It seems that the "lite" repository can't be used as a working
repository. And If I use the last method to push some work, I can only
pull that changes from a full repository. From a lite one (without any
changes of course) I get this error:
$ git pull /home/franck/pub/linux/git/linux-lite.git lite
Packing 108 objects
Unpacking 108 objects
100% (108/108) done
Merging HEAD with f42aaff3bf8041c2d43f1ff6fdfe5df6e8a5b00b
Merging:
8643db584b46a61c968ae230897869f789bae020 Merge with Linux 2.6.14.
f42aaff3bf8041c2d43f1ff6fdfe5df6e8a5b00b Did some hard work
found 0 common ancestor(s):
Traceback (most recent call last):
File "/home/fbuihuu/bin/git-merge-recursive", line 870, in ?
firstBranch, secondBranch, graph)
File "/home/fbuihuu/bin/git-merge-recursive", line 67, in merge
mergedCA = ca[0]
IndexError: list index out of range
No merge strategy handled the merge.
Do you have any clues ?
Thanks
--
Franck
^ permalink raw reply [relevance 0%]
* as promised, docs: git for the confused
@ 2005-12-08 6:34 1% ` linux
0 siblings, 0 replies; 200+ results
From: linux @ 2005-12-08 6:34 UTC (permalink / raw)
To: git; +Cc: linux
As I mentioned with all my questions, I was writing up the answers
I got. Here's the current status. If anyone would like to comment on
its accuracy or usefulness, feedback is appreciated.
I've tried to omit or skim very lightly over subjects I think
are adequately explained in existing docs, unless that would
leave an uncomfortable hole in the explanation.
TODO: Describe the config file. It's a recent invention, and I
haven't found a good description of its contents.
"I Don't Git It"
Git for the confused
Git is hardly lacking in documentation, but coming at it fresh, I found
it somewhat confusing.
Git is a toolkit in the Unix tradition. There are a number of primitives
written in C, which are made friendly by a layer of shell scripts.
These are known in git-speak, as the "plumbing" and the "porcelain",
respectively. The porcelain should work and look nice. The plumbing
should just deal with lots of crap efficiently.
Much of git's documentation was first written to explain the plumbing to
the people writing the porcelain. Since then, although the essentials
haven't changed, porcelain has been added and conventions have been
established that make it a lot more pleasant to deal with. Some commands
have been changed or replaced, and it's not quite the same.
Using the original low-level commands is now most likely more difficult
than necessary, unless you want to do something not supported by the
existing porcelain.
This document retraces (with fewer false turns) how I learned my
way around git. There are some concepts I didn't understand so well
the first time through, and an overview of all the git commands, grouped
by application.
A good rule of thumb is that the commands with one-word names (git-diff,
git-commit, git-merge, git-push, git-pull, git-status, git-tag, etc.) are
designed for end-user use. Multi-word names (git-count-objects,
git-write-tree, git-cat-file) are generally designed for use from
a script.
This isn't ironclad. The first command to start using git is git-init-db,
and git-show-branch is pure porcelain, while git-mktag is a primitive.
And you don't often run git-daemon by hand. But still, it's a useful
guideline.
* Background material.
To start with, read "man git". Or Documentation/git.txt in the git
source tree, which is the same thing. Particularly note the description
of the index, which is where all the action in git happens.
One thing that's confusing is why git allows you to have one version of
a file in the current HEAD, a second version in the index, and possibly a
third in the working directory. Why doesn't the index just contain a copy
of the current HEAD until you commit a new one? The answer is merging,
which does all its work in the index. Neither the object database nor
the working directory let you have multiple files with the same name.
The index is really very simple. It's a series of structures, each
describing one file. There's an object ID (SHA1) of the contents,
some file metadata to detect changes (time-stamps, inode number, size,
permissions, owner, etc.), and the path name relative to the root of
the working directory. It's always stored sorted by path name, for
efficient merging.
At (almost) any time, you can take a snapshot of the index and write
it as a tree object.
The only interesting feature is that each entry has a 2-bit stage number.
Normally, this is always zero, but each path name is allowed up to three
different versions (object IDs) in the index at once. This is used to
represent an incomplete merge, and an unmerged index entry (with more
than one version) prevents committing the index to the object database.
* Terminology - heads, branches, refs, and revisions
(This is a supplement to what's already in "man git".)
The most common object needed by git primitives is a tree. Since a
commit points to a tree and a tag points to a commit, both of these are
acceptable "tree-ish" objects and can be used interchangeably. Likewise,
a tag is "commit-ish" and can be used where a commit is required.
As soon as you get to the porcelain, the most commonly used object is
a commit. Also known as a revision, this is a tree plus a history.
While you can always use the full object ID, you can also use a reference.
A reference is a file that contains a 40-character hex SHA1 object ID
(and a trailing newline). When you specify the name of a reference,
it is searched for in one of the directories:
.git/ (or $GIT_DIR)
.git/refs/ (or $GIT_DIR/refs/)
.git/refs/heads/ (or $GIT_DIR/refs/heads/)
.git/refs/tags/ (or $GIT_DIR/refs/tags/)
You may use subdirectories by including slashes in the reference name.
There is no search order; if searching the above four path prefixes
produces more than one match for the reference name (it's ambiguous),
then the name is not valid.
There is additional syntax (which looks like "commit~3^2~17") for
specifying an ancestor of a given commit (or tag). This is documented
in detail in the documentation for git-rev-parse. Briefly, commit^
is the parent of the given commit. commit^^ is the grandparent, etc..
If there is more than one ancestor (a merge), then they can be referenced
as commit^1 (a synonym for commit^), commit^2, commit^3, etc. (commit^0
gives the commit object itself. A no-op if you're starting from a commit,
but it lets you get the commit object from a tag object.)
As long strings of ^ can be annoying, they can be abbreviated using ~
syntax. commit^^^ is the same as commit~3, ^^^^ is the same as ~4, etc.
You can see lots of examples in the output of "git-show-branch".
Now, the although the most primitive git tools don't care, a convention
among all the porcelain is that the current head of development is
.git/HEAD, a symbolic link to a reference under refs/heads/.
git-init-db creates HEAD pointing to refs/heads/master, and that is
traditionally the name used for the "main trunk" of development.
Note that initially refs/heads/master doesn't exist - HEAD is a
dangling symlink! This is okay, and will cause the initial commit
to have zero parents.
A "head" is mostly synonymous with a "branch", but the terms have
different emphasis. The "head" is particularly the tip of the branch,
where future development will be appended. A "branch" is the entire
development history leading to the head. However, as far as git is
concerned, they're both references to commit objects, referred to from
refs/heads/.
When you actually do more (with git-commit, or git-merge), then the
current HEAD reference is overwritten with the new commit's id, and
the old HEAD becomes HEAD^. Since HEAD is a symlink, it's the file
in refs/heads/ that's actually overwritten. (See the git-update-ref
documentation for further details.)
The git-checkout command actually changes the HEAD symlink. git-checkout
enforces the rule that it will only check out a branch under refs/heads.
You can use refs/tags as a source for git-diff or any other command that
only examines the revision, but if you want to check it out, you have
to copy it to refs/heads.
* Resetting
The "undo" command for commits to the object database is git-reset.
Like all deletion-type commands, be careful or you'll hurt yourself.
Given a commit (using any of the syntaxes mentioned above), this
sets the current HEAD to refer to the given commit.
This does NOT alter the HEAD symlink (as git-checkout <branch> will
do), but actually changes the reference pointed to by HEAD
(e.g. refs/heads/master) to contain a new object ID.
The classic example is to undo an erroneous commit, use
"git-reset HEAD^".
There are actually three kinds of git-reset:
git-reset --soft: Only overwrite the reference. If you can find the
old object ID, you can put everything back with a second
git-reset --soft OLD_HEAD.
git-reset --mixed: This is the default, which I always think of
as "--medium". Overwrite the reference, and (using
git-read-tree) read the commit into the index. The
working directory is unchanged.
git-reset --hard: Do everything --mixed does, and also check out
the index into the working directory. This really erases
all traces of the previous version. (One caveat: this
will not delete any files in the working directory that
were added as part of the changes being undone.)
The space taken up by the abandoned commit won't actually be
reclaimed until you collect garbage with git-prune.
git-reset with no commit specified is "git-reset HEAD", which is much
safer because the object reference is not actually changed. This can
be used to undo changes in the index or working directory that you did
not intend. Note, however, that it is not selective. "git-commit"
has options for doing this selectively.
Like being sure what directory you're in when typing "rm -r", think
carefully about what branch you're on when typing "git-reset <commit>".
There is an undelete: git-reset stores the previous HEAD commit
in OLD_HEAD. And git-lost-found can find leftover commits
until you do a git-prune.
* Merging
Merging is central to git operations. Indeed, a big difference between
git and other version control systems is that git assumes that a change
will be merged more often than it's written, as it's passed around
different developers' repositories. Even "git checkout" is a merge.
The heart of merging is git-read-tree, but if you can understand it from
the man page, you're doing better than me.
As mentioned, the index and the working directory versions of a file
could both be different from the HEAD. Git lets you merge "under" your
current working directory edits, as long as the merge doesn't change
the files you're editing.
There are some special cases of merging, but let me start with the
procedure for the general 3-way merge case: merging branch B into branch A
(the current HEAD).
1) Given two commits, find a common ancestor O to server as the origin
of the merge. The basic "resolve" algorithm uses git-merge-base for
the task, but the "recursive" merge strategy gets more clever in the
case where there are multiple candidates. I won't got into what it
does, but it does a pretty good job.
2) Add all three input trees (the Origin, A, and B) to the index by
"git-read-tree -m O A B". The index now contains up to three copies
of every file. (Four, including the original, but that is discarded
before git-read-tree returns.)
Then, for each file in the index, git-read-tree does the following:
2a) For each file, git-merge-tree tries to collapse the various
versions into one using the "trivial in-index merge". This just
uses the file blob object names to see if the file contents
are identical, and if two or more of the three trees contain an
identical copy of this file, it is merged. A missing (deleted)
file matches another missing file.
Note that this is NOT a majority vote. If A and B agree on the
contents of the file, that's what is used. (Whether O agrees is
irrelevant in this case.) But if O and A agree, then the change
made in B is taken as the final value. Likewise, if O and B agree,
then A is used.
2b) If this is possible, then a check is made to see if the merge would
conflict with any uncommitted work in the index or change the index
out from under a modified working directory file. If either of
those cases happen, the entire merge is backed out and fails.
(In the git source, the test "t/t1000-read-tree-m-3way.sh" has
a particularly detailed description of the various cases.)
If the merge is possible and safe, the versions are collapsed
into one final result version.
2c) If all three versions differ, the trivial in-index merge is
not possible, and the three source versions are left in the
index unmerged. Again, if there was uncommitted work in the
index or the working directory, the entire merge fails.
3) Use git-merge-index to iterate over the remaining unmerged files, and
apply an intra-file merge. The intra-file merge is usually done with
git-merge-one-file, which does a standard RCS-style three-way merge
(see "man merge").
4) Check out all the successfully merged files into the working directory.
5) If automatic merging was successful on every file, commit the merged
version immediately and stop.
6) If automatic merging was not complete, then replace the working
directory copies of any remaining unmerged files with a merged copy
with conflict markers (again, just like RCS or CVS) in the working
directory. All three source versions are available in the index for
diffing against.
(We have not destroyed anything, because in step 2c), we checked to make
sure the working directory file didn't have anything not in the
repository.)
7) Manually edit the conflicts and resolve the merge. As long as an
unmerged, multi-version file exists in the index, committing the
index is forbidden. (You can use the options to git-diff to
see the changes.)
8) Commit the final merged version of the conflicting file(s), replacing
the unmerged versions with the single finished version.
Note that if the merge is simple, with no one file edited on both
branches, git never has to open a single file. It reads three tree
objects (recursively) and stat(2)s some working directory files to
verify that they haven't changed.
Also note that this aborts and backs out rather than overwrite
anything not committed. You can merge "under" uncommitted edits
only if those edits are to files not affected by the merge.
* 2-way merging
A "2-way merge" is basically a 3-way merge with the contents of the
index as the "current HEAD", and the original HEAD as the Origin.
However, this merge is designed only for simple cases and only supports
the "trivial merge" cases. It does not fall back to an intra-file merge.
[[ I'm not sure why it couldn't, I confess. For reversibility? Or
just because it's likely to be too confusing. ]]
This merge is used by git-checkout to switch between two branches,
while preserving any changes in the working directory and index.
Like the 3-way case, if a particular file hasn't changed between
the two heads, then git will preserve any uncommitted edits.
If the file has changed in any way, git doesn't try to perform
any sort of intra-file merge, it just fails.
* 1-way merging
This is not actually used by the git-core porcelain, and so is only
useful to someone writing more porcelain, but I'll describe it for
completeness.
Plain (non-merging) git-read-tree will overwrite the index entries with
those from the tree. This invalidates the cached stat data, causing
git to think all the working directory files are "potentially changed"
until you do a git-update-index --refresh.
By specifying a 1-way merge, any index entry whose contents (object ID)
matches the incoming tree will have its cached stat data preserved.
Thus, git will know if the working directory file is not changed, and
will not overwrite if you execute git-checkout-index.
This is purely an efficiency hack.
* Special merges - already up to date, and fast-forward
There are two cases of 3-way or 2-way merging that are special.
Recall that the basic merge pattern is
B--------> A+B
/ /
/ /
O -----> A
The two special cases arise if one of A or B is a direct ancestor of
the other. In that case, the common ancestor of both A and B is the
older of the two commits. And the merged result is simply the
newer of the two, unchanged.
Recalling that we are merging B into A, if B is a direct ancestor of A,
then A already includes all of B. A is "already up to date" and not
changed at all by the merge.
The other case you'll hear mentioned, because it happens a lot when
pulling, is when A is a direct ancestor of B. In this case, the
result of the merge is a "fast-forward" to B.
Both of these cases are handled very efficiently by the in-index merge
done by git-read-tree.
* Deleted files during merges
There is one small wrinkle in git's merge algorithm that will probably
never bite you, but I ought to explain anyway, just because it's so rare
that it's difficult to discover it by experiment.
The index contains a list of all files that git is tracking. If the
index file is empty or missing and you do a commit, you write an empty
tree with no files.
When merging, if git finds no pre-existing index entry for a path it is
trying to merge, it considers that to mean "status unknown" rather than
"modified by being deleted". Thus, this is not uncommitted work
in the index file, and does not block the merge. Instead, the
file will reappear in the merge.
This is because it is possible to blow away the index file (rm .git/index
will do it quite nicely), and if this was considered a modification to
be preserved, it would cause all sorts of conflicts.
So the one change to the index that will NOT be preserved by a merge is
the removal of a file. A missing index entry is treated the same as an
unmodified index entry. The index will be updated, and when you check
out the revision, the working directory file will be (re-)created.
Note that none of this affects you in the usual case where you make
changes in the working directory only, and leave the index equal to HEAD
until you're ready to commit.
* Packs
Originally, git stored every object in its own file, and used rsync
to share repositories. It was quickly discovered that this brought
mighty servers to their knees. It's great for retrieving a small
subset of the database the way git usually does, but rsync scans the
whole .git/objects tree every time.
So packs were developed. A pack is a file, built all at once, which
contains many delta-compressed objects. With each .pack file,
there's an accompanying .idx file that indexes the pack so that
individual objects can be retrieved quickly.
You can reduce the disk space used by your repositories by periodically
repacking them with git-repack. Normally, this makes a new incremental
pack of everything not already packed. With the -a flag, this repacks
everything for even greater compression (but takes longer).
The git wire protocol basically consists of negotiation over what
objects needs to be transferred followed by sending a custom-built pack.
The .idx file can be reconstructed from the .pack file, so it's
never transferred.
[[ Is once every few hundred commits a good rule of thumb for repacking?
When .git/objects/?? reaches X megabytes? I think too many packs is
itself a bad thing, since they all have to be searched. ]]
* Raw diffs
A major source of git's speed is that it tries to avoid accessing files
unnecessarily. In particular, files can be compared based on their
object IDs without needing to open and read them. As part of this,
the responsibility for finding file differences (printing diffs) is
divided into finding what files have changed, and finding the changes
within those files.
This is all explained in the Documentation/diffcore.txt in the git
distribution, but the basics is that many of the primitives spit out a
line like this:
:100755 100755 68838f3fad1d22ab4f14977434e9ce73365fb304 0000000000000000000000000000000000000000 M git-bisect.sh
when asked for a diff. This is known as a "raw diff". They can be
told to generate a human-readable diff with the "-p" (patch) flag.
The git-diff command includes this by default.
* Advice on using git
If you're used to CVS, where branches and merges are "advanced" features
that you can go a long time, you need to learn to use branches in git a
lot more. Branch early and often. Every time you think about developing
a feature or fixing a bug, create a branch to do it on.
In fact, avoid doing any development on the master branch. Merges only.
A branch is the git equivalent of a patch, and merging a branch is the
equivalent of applying that patch. A branch gives it a name that
you can use to refer to it. This is particularly useful if you're
sharing your changes.
Once you're done with a branch, you can delete it. This is basically
just removing the refs/heads/<branch> file, but "git-branch -d" adds a
few extra safety checks. Assuming you merged the branch in, you can
still find all the commits in the history, it's just the name that's
been deleted.
You can also rename a branch by renaming the refs/heads/branch file.
There's no git command to do this, but as long as you update
the HEAD symlink if necessary, you don't need one.
Periodically merge all of the branches you're working on into a testing
branch to see if everything works. Blow away and re-create the
testing branch whenever you do this. When you like the result,
merge them into the master.
* The .git directory
There are a number of files in the .git directory used by the
porcelain. In case you're curious (I was), this is what they are:
index
- The actual index file.
objects/
- The object database. Can be overridden by $GIT_OBJECT_DIRECTORY
hooks/
- where the hook scripts are kept. The standard git template includes
examples, but disabled by being marked non-executable.
info/exclude
- Default project-wide list of file patterns to exclude from notice.
To this is added the per-directory list in .gitignore.
See the git-ls-files docs for full details.
refs/
- References to development heads (branches) and tags.
remotes/
- Short names of remote repositories we pull from or push to.
Details are in the "git-fetch" man page.
HEAD
- The current default development head.
- Created by git-init-db and never deleted
- Changed by git-checkout
- Used by git-commit and any other command that commits changes.
- May be a dangling pointer, in which case git-commit
does an "initial checkin" with no parent.
COMMIT_EDITMSG
- Temp used by git-commit to edit a commit message.
COMMIT_MSG
- Temp used by git-commit to form a commit message,
post-processed from COMMIT_EDITMSG.
FETCH_HEAD
- Just-fetched commits, to be merged into the local trunk.
- Created by git-fetch.
- Used by git-pull as the source of data to merge.
MERGE_HEAD
- Keeps track of what heads are currently being merged into HEAD.
- Created by git-merge --no-commit with the heads used
- Deleted by git-checkout and git-reset (since you're abandoning
the merge)
- Used by git-commit to supply additional parents to the current commit.
(And deleted when done.)
MERGE_MSG
- Generated by git-merge --no-commit.
- Used by git-commit as the commit message for a merge
(If present, git-commit doesn't prompt.)
MERGE_SAVE
- cpio archive of all locally modified files created by
"git-merge" before starting to do anything, if multiple
merge strategies are being attempted.
Used to rewind the tree in case a merge fails.
ORIG_HEAD
- Previous HEAD commit prior to a merge or reset operation.
LAST_MERGE
- Set by the "resolve" strategy to the most recently merged-in branch.
Basically, a copy of MERGE_HEAD. Not used by the other merge strategies,
and resolve is no longer the default, so its utility is very limited.
BISECT_LOG
- History of a git-bisect operation.
- Can be replayed (or, more usefully, a prefix can) by "git-bisect replay"
BISECT_NAMES
- The list of files to be modified by git-bisect.
- Set by "git-bisect start"
TMP_HEAD (used by git-fetch)
TMP_ALT (used by git-fetch)
* Git command summary
There are slightly over a hundred git commands. This section tries to
classify them by purpose, so you can know which commands are intended to
be used for what. You can always use the low-level plumbing directly,
but that's inconvenient and error-prone.
Helper programs (not for direct use) for a specific utility are shown
indented under the program they help.
Note that all of these can be invoked using the "git" wrapper by replacing
the leading "git-" with "git ". The results are exactly the same.
There is a suggestion to reduce the clutter in /usr/bin and move all
the git binaries to their own directory, leaving just the git wrapper
in /usr/bin. so you'll have to use it or adjust your $PATH. But that
hasn't happened yet. In the meantime, including the hyphen makes
tab-completion work.
I include ".sh", ".perl", etc. suffixes to show what the programs are
written in, so you can read those scripts written in languages you're
familiar with. These are the names in the git source tree, but the
suffix is not included in the /usr/bin copies.
+ Administrative commands
git-init-db
+ Object database maintenance:
git-convert-objects
git-fsck-objects
git-lost-found.sh
git-prune.sh
git-relink.perl
+ Pack maintenance
git-count-objects.sh
git-index-pack
git-pack-objects
git-pack-redundant
git-prune-packed
git-repack.sh
git-show-index
git-unpack-objects
git-verify-pack
+ Important primitives
git-commit-tree
git-rev-list
git-rev-parse
+ Useful primitives
git-ls-files
git-update-index
+ General script helpers (used only by scripts)
git-cat-file
git-check-ref-format
git-checkout-index
git-fmt-merge-msg.perl
git-hash-object
git-ls-tree
git-repo-config
git-unpack-file
git-update-ref
git-sh-setup.sh
git-stripspace
git-symbolic-ref
git-var
git-write-tree
+ Oddballs
git-mv.perl
+ Code browsing
git-diff.sh
git-diff-files
git-diff-index
git-diff-tree
git-diff-stages
git-grep.sh
git-log.sh
git-name-rev
git-shortlog.perl
git-show-branch
git-whatchanged.sh
+ Making local changes
git-add.sh
git-bisect.sh
git-branch.sh
git-checkout.sh
git-commit.sh
git-reset.sh
git-status.sh
+ Cherry-picking
git-cherry.sh
git-patch-id
git-cherry-pick.sh
git-rebase.sh
git-revert.sh
+ Accepting changes by e-mail
git-apply
git-am.sh
git-mailinfo
git-mailsplit
git-applypatch.sh
git-applymbox.sh
+ Publishing changes by e-mail
git-format-patch.sh
git-send-email.perl
+ Merging
git-merge.sh
git-merge-base
git-merge-index
git-merge-one-file.sh
git-merge-octopus.sh
git-merge-ours.sh
git-merge-recursive.py
git-merge-resolve.sh
git-merge-stupid.sh
git-read-tree
git-resolve.sh
git-octopus.sh
+ Making releases
git-get-tar-commit-id
git-tag.sh
git-mktag
git-tar-tree
git-verify-tag.sh
+ Accepting changes by network
git-clone.sh
git-clone-pack
git-fetch.sh
git-fetch-pack
git-local-fetch
git-http-fetch
git-ssh-fetch
git-ls-remote.sh
git-peek-remote
git-parse-remote.sh
git-pull.sh
git-ssh-pull
git-shell
git-receive-pack
+ Publishing changes by network
git-daemon
git-push.sh
git-http-push
git-ssh-push
git-ssh-upload
git-request-pull.sh
git-send-pack
git-update-server-info
git-upload-pack
All of the basic git commands are designed to be scripted. When
scripting, use the "--" option to ensure that files beginning with
"-" won't be interpreted as options, and the "-z" option to output
NUL-terminated file names so embedded newlines won't break things.
(A person who'd do either of these on purpose is probably crazy, but
it's not actually illegal.)
Looking at existing shell scripts can be very informative.
* Detailed list
Here's a repeat, including descriptions. I don't try to include
every detail you can find on the man page, but to explain when
you'd want to use a command.
+ Administrative commands
git-init-db
This creates an empty git repository in ./.git (or $GIT_DIR if
that is non-null) using a system-wide template.
It won't hurt an existing repository.
+ Object database maintenance:
git-convert-objects
You will *never* need to use this command.
The git repository format has undergone some revision since its
first release. If you have an ancient and crufty git repository
from the very very early days, this will convert it for you.
But as you're new to git, it doesn't apply.
git-fsck-objects
Validate the object database. Checks that all references
point somewhere, all the SHA1 hashes are correct, and that
sort of thing.
This walks the entire repository, uncompressing and hashing
every object, so it takes a while. Note that by default,
it skips over packs, which can make it seem misleadingly fast.
git-lost-found.sh
Find (using git-fsck-objects) any unreferenced commits and
tags in the object database, and place them in a .git/lost-found
directory. This can be used to recover from accidentally
deleting a tag or branch reference that you wanted to keep.
This is the opposite of git-prune.
git-prune.sh
Delete all unreachable objects from the object database.
It deletes useless packs, but does not remove useless
objects from the middle of partially useful packs.
Git leaks objects in a number of cases, such as unsuccessful
merges. The leak rate is generally a small fraction of
the rate at which the desired history grows, so it's not
very alarming, but occasionally running git-prune will
eliminate the
If you deliberately throw away a development branch, you
will need to run this command to fully reclaim the disk space.
On something like the full Linux repository, this takes
a while.
git-relink.perl
Merge the objects stores of multiple git repositories by
making hard links between them. Useful to save space if
duplicate copies are accidentally created on one machine.
+ Pack maintenance
The classic git format is to compress and store each object
separately. This is still used for all newly created changes.
However, objects can also be stored en masse in "packs" which
contain many objects and tan take advantage of delta-compressing.
Repacking your repositories periodically can save space.
(Repacking is pretty quick but not quick enough to be
comfortable doing every commit.)
git-count-objects.sh
Print the number and total size of unpacked objects in the
repository, to help you decide when is a good time to repack.
git-index-pack
A pack file has an accompanying .idx file to allow rapid lookup.
This regenerates the .idx file from the .pack. This is almost never
needed directly, but can be used after transferring a .pack file
between machines.
git-pack-objects
Given a list of objects on stdin, build a pack file. This is
a helper used by the various network communication scripts.
git-pack-redundant
Produce a list of redundant packs, for feeding to "xargs rm".
A helper for git-prune.
git-prune-packed
Delete unpacked object files that are duplicated in packs.
(With -n, only lists them.) A helper for git-prune.
git-repack.sh
Make a new pack with all the unpacked objects.
With -a, include already-packed objects in the new pack.
With -d as well, deletes all the old packs thereby made redundant.
git-show-index
Dump the contents of a pack's .idx file. Mostly for
debugging git itself.
git-unpack-objects
Unpack a .pack file, the opposite of git-pack-objects. With -n,
doesn't actually create the files. With -q, suppresses the
progress indicator.
git-verify-pack
Validate a pack file. Useful when debugging git, and when
downloading from a remote source. A helper for git-clone.
+ Important primitives
Although these primitives are not used directly very frequently,
understanding them will help you understand other git commands
that wrap them.
git-commit-tree
Create a new commit object from a tree and a list of parent
commits. This is the primitive that's the heart of git-commit.
(It's also used by git-am, git-applypatch, git-merge, etc.)
git-rev-list
Print a list of commits (revisions), in reverse chronological
order. This is the heart of git-log and other history examination
commands, and the options for specifying parts of history are
shared by all of them.
In particular, it takes an arbitrary number of revisions as
arguments, some of which may be prefixed with ^ to negate them.
These make up "include" and "exclude" sets. git-rev-list
lists all revisions that are ancestors of the "include" set
but not ancestors of the "exclude" set.
For this purpose, a revision is considered an ancestor of itself.
Thus, "git-rev-list ^v1.1 v1.2" will list all revisions from
the v1.2 release back to (but not including) the v1.1 release.
Because this is so convenient, a special syntax, "v1.1..v1.2"
is allowed as an equivalent. However, occasionally the general
form is useful. For example, adding ^branch will show the trunk
(including merges from the branch), but exclude the branch itself.
Similarly, "branch ^trunk", a.k.a. trunk..branch, will show
all work on the branch that hasn't been merged to the trunk.
This works even though trunk is not a direct ancestor of branch.
Git-rev-list has a variety of flags to control it output format.
The default is to just print the raw SHA1 object IDs of the
commits, but --pretty produces a human-readable log.
You can also specify a set of files names (or directories),
in which case output will be limited to commits that modified
those files.
This command is used extensively by the git:// protocol to compute
a set of objects to send to update a repository.
git-rev-parse
This is a very widely used command line canonicalizer for git
scripts. It converts relative commit references (e.g. master~3)
to absolute SHA1 hashes, and can also pass through arguments
not recognizable as references, so the script can interpret them.
It is important because it defines the <rev> syntax.
This takes a variety of options to specify how to prepare the
command line for the script's use. --verify is a particularly
important one.
+ Useful primitives
These primitives are potentially useful directly.
git-ls-files
List files in the index and/or working directory. A variety of
options control which files to list, based on whether they
are the same in both places or have been modified. This command
is the start of most check-in scripts.
git-update-index
Copy the given files from the working directory into the index.
This create the blob objects, but no trees yet. (Note that
editing a file executing this multiple times without creating a
commit will generate orphaned objects. Harmless.)
One common safe option is "git-update-index --refresh". This
looks for files whose metadata (modification time etc.) has
changed, but not their contents, and updates the metadata in the
index so the file contents won't have to be examined again.
+ General script helpers (used only by scripts)
These are almost exclusively helpers for use in porcelain
scripts and have little use by themselves from the command line.
git-cat-file
Extract a file from the object database. You can ask for
an object's type or size given only an object ID, but
to get its contents, you have to specify the type. This
is a deliberate safety measure.
git-check-ref-format
Verify that the reference specified on the command line is
syntactically valid for a new reference name under $GIT_DIR/refs.
A number of characters (^, ~, :, and ..) are reserved; see the man
page for the full list of rules.
git-checkout-index
Copy files from the index to the working directory, or to a
specified directory. Most important as a helper for git-checkout,
this is also used by git-merge and git-reset.
git-fmt-merge-msg.perl
Generate a reasonable default commit message for a merge.
Used by git-pull and git-octopus.
git-hash-object
Very primitive helper to turn an arbitrary file into an object,
returning just the ID or actually adding it to the database.
Used by the cvs-to-git and svn-to-git import filters.
git-ls-tree
List the contents of a tree object. Will tell you all the files
in a commit. Used by the checkout scripts git-checkout and git-reset.
git-repo-config
Get and set options in .git/config. The .git/config format
is designed to be human-readable. This gives programmatic
access to the settings. This currently has a lot of overlap
with the function of git-var.
git-unpack-file
Write the contents of the given block to a temporary file,
and return the name of that temp file. Used most often
by merging scripts.
git-update-ref
Rewrite a reference (in .git/refs/) to point to a new object.
"echo $sha1 > $file" is mostly equivalent, but this adds locking
so two people don't update the same reference at once.
git-sh-setup.sh
This is a general prefix script that sets up
$GIT_DIR and $GIT_OBJECT_DIRECTORY for a script,
or errors out if the git control files can't be found.
git-stripspace
Remove unnecessary whitespace. Used mostly on commit messages
received by e-mail.
git-symbolic-ref
This queries or creates symlinks to references such as HEAD.
Basically equivalent to readlink(1) or ln -s, this also works
on platforms that don't have symlinks. See the man page.
git-var
Provide access to the GIT_AUTHOR_IDENT and/or GIT_COMMITTER_IDENT
values, used in various commit scripts. This currently has a
lot of overlap with the function of git-repo-config.
git-write-tree
Generate a tree object reflecting the current index. The output
is the tree object; if you don't remember it somewhere (usually,
pass it to git-commit-tree), it'll be lost.
This requires that the index be fully merged. If any incomplete
merges are present in the index (files in stages 1, 2 or 3),
git-write-tree will fail.
+ Oddballs
git-mv.perl
I have to admit, I'm not quite sure what advantages this is
supposed to have over plain "mv" followed by "git-update-index",
or why it's complex enough to need perl.
Basically, this renames a file, deleting its old name and adding
its new name to the index. Otherwise, it's a two-step process
to rename a file:
- Rename the file
- git-add the new name
Followed by which you must commit both the old and new names
+ Code browsing
git-diff.sh
Show changes between various trees. Takes up to two tree
specifications, and shows the difference between the versions.
Zero arguments: index vs. working directory (git-diff-files)
One: tree vs. working directory (git-diff-index)
One, --cached: tree vs. index (git-diff-index)
Two: tree vs. tree (git-diff-tree)
This wrapper always produces human-readable patch output.
The helpers all produce "diff-raw" format unless you supply
the -p option.
There are some interesting options. Unfortunately, the git-diff
man page is annoyingly sparse, and refers to the helper scripts'
documentation rather than describing the many useful options
they all have in common. Please do read the man pages of the
helpers to see what's available.
In particular, although git does not explicitly record file
renames, it has some pretty good heuristics to notice things.
-M tries to detect renamed files by matching up deleted files
with similar newly created files. -C tries to detect copies
as well. By default, -C only looks among the modified files for
the copy source. For common cases like splitting a file in two,
this works well. The --find-copies-harder searches ALL files
in the tree for the copy source. This can be slow on large trees!
See Documentation/diffcore.txt for an explanation of how all
this works.
git-diff-files
Compare the index and the working directory.
git-diff-index
Compare the working directory and a given tree. This is the
git equivalent of the single-operand form of "cvs diff".
If "--cached" is specified, uses the index rather than the working
directory.
git-diff-tree
Compare two trees. This is the git equivalent of the two-operand
form of "cvs diff". This command is sometimes useful by itself
to see the changes made by a single commit. If you give it
only one commit on the command line, it shows the diff between
that commit and its first parent. If the commit specification
is long and awkward to type, using "git-diff-tree -p <commit>"
can be easier than "git-diff <commit>^ <commit>".
git-diff-stages
Although not called by git-diff, there is a fourth diff helper
routine, used to compare the various versions of an unmerged
file in the index. It is intended for use by merging porcelain.
git-grep.sh
A very simple wrapper that runs git-ls-files and greps the
output looking for a file name. Does nothing fancy except
saves typing.
git-log.sh
Wrapper around git-rev-list --pretty. Shows a history
of changes made to the repository. Takes all of git-rev-list's
options for specifying which revisions to list.
git-name-rev
Find a symbolic name for the commit specified on the
command line, and returns a symbolic name of the form
"maint~404^2~7". Basically, this does a breadth-first search
from all the heads in .git/refs looking for the given commit.
git-shortlog.perl
This is a filter for the output of "git-log --pretty=short"
to generate a one-line-per-change "shortlog" as Linus likes.
git-show-branch
Visually show the merge history of the references given as
arguments. Prints one column per reference and one line per
commit showing whether that commit is an ancestor of each
reference.
git-whatchanged.sh
A simple wrapper around git-rev-list and git-diff-tree,
this shows the change history of a repository. Specify a
directory or file on the command line to limit the
output to changes affecting those files. This isn't
the same as "cvs annotate", but it serves a similar purpose
among git folks.
You can add the -p option to include patches as well as log
comments. You can also add the -M or -C option to follow
history back through file renames.
-S is interesting: it's the "pickaxe" option. Given a string,
this limits the output to changes that make that string appear
or disappear. This is for "digging through history" to see when
a piece of code was introduced. The string may (and often does)
contain embedded newlines. See Documentation/cvs-migration.txt.
+ Making local changes
All of these are examples of "porcelain" scripts. Reading the
scripts themselves can be informative; they're generally not
too confusing.
git-add.sh
A simple wrapper around "git-ls-files | git-update-index --add"
to add new files to the index. You may specify directories.
You need to invoke this for every new file you want git to
track.
git-bisect.sh
Utility to do a binary search to find the change that broke something.
The heart of this is in "git-rev-list --bisect"
A very handy little utility! Kernel developers love it
when you tell them exactly which patch broke something.
NOTE: this uses the head named "bisect", and will blow
away any existing branch by that name. Try not to
create a branch with that name.
There are three steps:
git-bisect start [<files>]
- Reset to start bisecting. If any files are specified,
only they will be checked out as bisection proceeds.
git-bisect good [<revision>]
- Record the revision as "good". The change being sought
must be after this revision.
git-bisect bad [<revision>]
- Record the revision as "bad". The change being sought
must be before or equal to this revision.
As soon as you have specified one good version and one bad version,
git-bisect will find a halfway point and check out that
revision. Build and test it, then report it as good or bad,
and git-bisect will narrow the search. Finally, git-bisect
will tell you exactly which change caused the problem.
git-bisect log
- Show a history of revisions.
git-bisect replay
- Replay (part of) a git-bisect log. Generally used
to recover from a mistake, you can truncate the log
before the mistake and replay it to continue.
If git-bisect chooses a version that cannot build, or you
are otherwise unable to determine whether it is good or bad,
you can change revisions with "git-reset --hard <revision>"
to another checkout between the current good and bad limits, and
continue from there. "git-reset --hard <revision>" is generally
dangerous, but you are on a scratch branch.
This can, of course, be used to look for any change, even
one for the better, if you can avoid being confused by the
terms "good" and "bad".
git-branch.sh
Most commonly used bare, to show the available branches.
Show, create, or delete a branch. The current branches
are simply the contents of .git/refs/heads/.
Note that this does NOT switch to the created branch!
For the common case of creating a branch and immediately
switching to it, "git-checkout -b <branch>" is simpler.
git-checkout.sh
This does two superficially similar but very different things
depending on whether any files or paths are specified on the
command line.
git-checkout [-f] [-b <new-branch>] <branch>
This switches (changes the HEAD symlink to) the specified
branch, updating the index and working directory to
reflect the change. This preserves changes in the
working directory unless -f is specified.
If -b is specified, a new branch is started from the
specified point and switched to. If <branch> is omitted,
it defaults to HEAD. This is the usual way to start a
new branch.
git-checkout [<branch>] [--] <paths>...
This replaces the files specified by the given paths with
the versions from the index or the specified branch.
It does NOT affect the HEAD symlink, just replaces the
specified paths. This form is like a selective form of
"git-reset". Normally, this can guess whether the first
argument is a branch name or a path, but you can use
"--" to force the latter interpretation.
With no branch, this is used to revert a botched edit of a
particular file.
Both forms use git-read-tree internally, but the net effect is
quite different.
git-commit.sh
Commit changes to the revision history. In terms of primitives,
this does three things:
1) Updates the index file with the working directory files
specified on the command line, or -a for all
(using git-diff-files --name-only | git-update_index),
2) Prompts for or generates a commit message, and then
3) Creates a commit object with the current index contents.
This also executes the pre-commit, commit-msg, and
post-commit hooks if present.
This will remove deleted files from the index, but will not
add new files to the index, even if explicitly specified on the
command line; you must use git-add for that.
git-reset.sh
Explained in detail in "resetting", above. This modifies the
current branch head reference (as pointed to by .git/HEAD)
to refer to the given commit. It does not modify .git/HEAD
Reset the current HEAD to the specified commit, so that future
checkins will be relative to it. There are three
variations:
--soft: Just move the HEAD link. The index is unchanged.
--mixed (default): Move the HEAD link and update the index file.
Any local changes will appear not checked in.
--hard: Move the HEAD links, update the index file, and
check out the index, overwriting the working
directory. Like "cvs update -C".
In case of accidents, this copies the previous head
object ID to ORIG_HEAD (which is NOT a symlink).
git-status.sh
Show all files in the directory not current with respect
to the git HEAD. The basic categories are:
1) Changed in the index, will be included in the next commit.
2) Changed in the working directory but NOT in the index; will
be committed only if added via git-update-index or the
git-commit command line.
3) Not tracked by git.
+ Cherry-picking
Cherry-picking is the process of taking part of the changes
introduced on one tree and applying those changes to another.
This doesn't produce a parent/descendant relationship in the
commit history.
To produce that relationship, there's a special type of merge you
can do if you've taken everything you want off a branch and
want to show it in the merge history without actually importing
any changes from it: ours. "git-merge -s ours" will generate a
commit that shows some branches were merged in, but not
actually alter the current HEAD source code in any way.
One thing cherry-picking is sometimes used for is taking a
development branch and re-organizing the changes into a patch
series for submission to the Linux kernel.
git-cherry.sh
This searches a branch for patches which have not been applied
to another. Basically, it finds the unpicked cherries.
It searches back to the common ancestor of the named branch and
the current head using git-patch-id to identify similarity
in patches.
git-patch-id
Generate a hash of a patch, ignoring whitespace and line numbers
so that "the same" patch, even relative to a different code base,
probably has the same hash, and different patches probably have
different ones. git-cherry looks for patch hashes which
are present on the branch (source branch) that are not present
on the trunk (destination branch).
git-cherry-pick.sh
Given a commit (on a different branch), compute a diff between
it and its immediate parent, and apply it to the current HEAD.
This is actually the same script as "git revert", but
works forward. git-cherry finds the patches, this merges them.
Handles failures gracefully.
git-rebase.sh
Move a branch to a more recent "base" release. This just extracts
all the patches applied on the local head since the last merge
with upstream (using git-format-patch) and re-applies them
relative to the current upstream with git-am (explained under
"accepting changes by e-mail"). Finally, it deletes the old
branch and gives its name to the new one, so your branch now
contains all the same changes, but relative to a different base.
Basically the same as cherry-picking an entire branch.
git-revert.sh
Undo a commit. Basically "patch -R" followed by a commit.
This is actually the same script as "git-cherry-pick", just
applies the patch in reverse, undoing a change that you don't
wish to back up to using git-reset. Handles failures gracefully
by telling the user what to do.
+ Accepting changes by e-mail
git-apply
Apply a (git-style extended) patch to the current index
and working directory.
git-am.sh
The new and improved "apply an mbox" script. Takes an
mbox-style concatenation of e-mails as input and batch-applies
them, generating one commit per message. Can resume after
stopping on a patch problem.
(Invoke it as "git-am --skip" or "git-am --resolved" to
deal with the problematic patch and continue.)
git-mailinfo
Given a single mail message on stdin (in the Linux standard
SubmittingPatches format), extract a commit message and
the patch proper.
git-mailsplit
Split an mbox into separate files.
git-applypatch.sh
Tries simple git-apply, then tries a few other clever merge
strategies to get a patch to apply. Used in the main loop
of git-am and git-applymbox.
git-applymbox.sh
This is Linus's original apply-mbox script. Mostly superseded by
git-am (which is friendlier and has more features), but he still
uses it, so it's maintained. This is so old it was originally
a test of the git core called "dotest", and that name is still
lurking in the temp file names.
+ Publishing changes by e-mail
git-format-patch.sh
Generate a series of patches, in the preferred Linux kernel
(Documentation/SubmittingPatches) format, for posting to lkml
or the like. This formats every commit on a branch as a separate
patch.
git-send-email.perl
Actually e-mail the output of git-format-patch.
(This uses direct SMTP, a matter of some controversy. Others feel
that /bin/mail is the correct local mail-sending interface.)
+ Merging
git-merge.sh
Merge one or more "remote" heads into the current head.
Some changes, when there has been change only on one branch or
the same change has been made to all branches, can be resolved
by the "trivial in-index" merge done by git-read-tree. For more
complex cases, git provides a number of different merge strategies
(with reasonable defaults).
Note that merges are done on a filename basis. While git tries
to detect renames when generating diffs, most merge strategies
don't track them by renaming. (The "recursive" strategy, which
recently became the default, is a notable exception.)
git-merge-base
Finds a common ancestor to use when comparing the changes made
on two branches. The simple case is straightforward, but if
there have been cross-merges between the branches, it gets
somewhat hairy. The algorithm is not 100% final yet.
(There's also --all, which lists all candidates.)
git-merge-index
This is the outer merging loop. It takes the name of a one-file
merge executable as an argument, and runs it for every incomplete
merge.
git-merge-one-file.sh
This is the standard git-merge-index helper, that tries to
resolve a 3-way merge. A helper used by all the merge strategies.
(Except "recursive" which has its own equivalent.)
git-merge-octopus.sh
Many-way merge. Overlaps should be negligible.
git-merge-ours.sh
A "dummy" merge strategy helper. Claims that we did the merge, but
actually takes the current tree unmodified. This is used to
cleanly terminate side branches that heve been cherry-picked in.
git-merge-recursive.py
A somewhat fancier 3-way merge. This handles multiple cross-merges
better by using multiple common ancestors.
git-merge-resolve.sh
git-merge-stupid.sh
Not actually used by git-merge, this is a simple example
merge strategy.
git-read-tree
Read the given tree into the index. This is the difference
between the "--soft" and "--mixed" modes of git-reset, but the
important thing this command does is simple merging.
If -m is specified, this can take up to three trees as arguments.
git-resolve.sh
OBSOLETE. Perform a merge using the "resolve" strategy.
Has been superseded by the "-s resolve" option to git-merge
and git-pull.
git-octopus.sh
OBSOLETE. Perform a merge using the "octopus" strategy.
Has been superseded by the "-s octopus" option to git-merge
and git-pull.
+ Making releases
git-get-tar-commit-id
Reads out the commit ID that git-tar-tree puts in its output.
(Or fails if this isn't a git-generated tar file.)
git-tag.sh
Create a tag in the refs/tags directory. There are two kinds:
"lightweight tags" are just references to commits. More
serious tags are GPG-signed tag objects, and people receiving
the git tree can verify that it is the version that you released.
git-mktag
Creates a tag object. Verifies syntactic correctness of its
input. (If you want to cheat, use git-hash-object.)
git-tar-tree
Generate a tar archive of the named tree. Because git does NOT
track file timestamps, this uses the timestamp of the commit,
or the current time if you specify a tree.
Also stores the commit ID in an extended tar header.
git-verify-tag.sh
Given a tag object, GPG-verify the embedded signature.
+ Accepting changes by network
Pulling consists of two steps: retrieving the remote commit
objects and everything they point to (including ancestors),
then merging that into the desired tree. There are still
separate fetch and merge commands, but it's more commonly done
with a single "git-pull" command. git-fetch leaves the commit
objects, one per line, in .git/FETCH_HEAD. git-merge will
merge those in if that file exists when it is run.
References to remote repositories can be made with long URLs,
or with files in the .git/remotes/ directory. The latter
also specifies the local branches to merge the fetched data into,
making it very easy to track a remote repository.
git-clone.sh
Create a new local clone of a remote repository.
(Can do a couple of space-sharing hacks when "remote" is on
a local machine.)
You only do this once.
git-clone-pack
Runs git-upload-pack remotely and places the resultant pack
into the local repository. Supports a variety of network
protocols, but "remote" can also be a different directory on
the current machine.
git-fetch.sh
Fetch the named refs and all linked objects from a remote repository.
The resultant refs (tags and commits) are stored in .git/FETCH_HEAD,
which is used by a later git-resolve or git octopus.
This is the first half of a "git pull" operation.
git-fetch-pack
Retrieve missing objects from a remote repository.
git-local-fetch
Duplicates a git repository from the local system.
(Er... is this used anywhere???)
git-http-fetch
Do a fetch via http. Http requires some kludgery on the
server (see git-update-server-info), but it works.
git-ssh-fetch
Do a fetch via ssh.
git-ls-remote.sh
Show the contents of the refs/heads/ and/or refs/tags/ directories
of a remote repository. Useful to see what's available.
git-peek-remote
Helper C program for the git-ls-remote script. Implements the
git protocol form of it.
git-parse-remote.sh
Helper script to parse a .git/remotes/ file. Used by a number
of these programs.
git-pull.sh
Fetches specific commits from the given remote repository,
and merges everything into the current branch. If a remote
commit is named as src:dst, this merges the remote head "src"
into the branch "dst" as well as the trunk. Typically, the "dst"
branch is not modified locally, but is kept as a pristine copy
of the remote branch.
One very standard example of this contention is that
a repository that is tracking another specifies "master:origin"
to provide a pristine local copy of the remote "master"
branch in the local branch named "origin".
git-ssh-pull
A helper program that pulls over ssh.
git-shell
A shell that can be used for git-only users. Allows git
push (git-receive-pack) and pull (git-upload-pack) only.
git-receive-pack
Receive a pack from git-send-pack, validate it, and add it to
the repository. Adding just the bare objects has no security
implications, but this can also update branches and tags, which
does have an effect.
Runs pre-update and post-update hooks; the former may do
permissions checking and disallow the upload.
This is the command run remotely via ssh by git-push.
+ Publishing changes by network
git-daemon
A daemon that serves up the git native protocol so anonymous
clients can fetch data. For it to allow export of a directory,
the magic file name "git-daemon-export-ok" must exist in it.
This does not accept (receive) data under any circumstances.
git-push.sh
Git-pull, only backwards. Send local changes to a remote
repository. The same .git/remotes/ short-cuts can be used,
and the same src:dst syntax. (But this time, the src is local
and the dst is remote.)
git-http-push
A helper to git-push to implement the http: protocol.
git-ssh-push
A helper to git-push to push over ssh.
git-ssh-upload
Another helper. This just does the equivalent of "fetch"
("throw"?) and doesn't actually merge the result. Obsolete?
git-request-pull.sh
Generate an e-mail summarizing the changes between two commits,
and request that the recipient pull them from your repository.
Just a little helper to generate a consistent and informative
format.
git-send-pack
Pack together a pile of objects missing at the destination and
send them. This is the sending half that talks to a remote
git-receive-pack.
git-update-server-info
To run git over http, auxiliary info files are required that
describes what objects are in the repository (since git-upload-pack
can't generate this on the fly). If you want to publish a
repository via http, run this after every commit. (Typically
via the hooks/post-update script.)
git-upload-pack
Like git-send-pack, but this is invoked by a remote git-fetch-pack.
^ permalink raw reply [relevance 1%]
* Re: as promised, docs: git for the confused
[not found] <7vbqzrcmgr.fsf@assigned-by-dhcp.cox.net>
@ 2005-12-09 5:44 1% ` linux
0 siblings, 0 replies; 200+ results
From: linux @ 2005-12-09 5:44 UTC (permalink / raw)
To: git; +Cc: linux
The revised version, with the changes previously noted.
TODO: Describe the config file. It's a recent invention, and I
haven't found a good description of its contents.
"I Don't Git It"
Git for the confused
Git is hardly lacking in documentation, but coming at it fresh, I found
it somewhat confusing.
Git is a toolkit in the Unix tradition. There are a number of primitives
written in C, which are made friendly by a layer of shell scripts.
These are known in git-speak, as the "plumbing" and the "porcelain",
respectively. The porcelain should work and look nice. The plumbing
should just deal with lots of crap efficiently.
Much of git's documentation was first written to explain the plumbing to
the people writing the porcelain. Since then, although the essentials
haven't changed, porcelain has been added and conventions have been
established that make it a lot more pleasant to deal with. Some commands
have been changed or replaced, and it's not quite the same.
Using the original low-level commands is now most likely more difficult
than necessary, unless you want to do something not supported by the
existing porcelain.
This document retraces (with fewer false turns) how I learned my way
around git. There are some concepts I didn't understand so well the
first time through, and an overview of all the git commands, grouped
by application.
A good rule of thumb is that the commands with one-word names (git-diff,
git-commit, git-merge, git-push, git-pull, git-status, git-tag, etc.) are
designed for end-user use. Multi-word names (git-count-objects,
git-write-tree, git-update-index) are generally designed for use from
a script.
This isn't ironclad. The first command to start using git is git-init-db,
and git-show-branch is pure porcelain, while git-mktag is a primitive.
And you don't often run git-daemon by hand. But still, it's a useful
guideline.
* Background material.
To start with, read "man git". Or Documentation/git.txt in the git
source tree, which is the same thing. Particularly note the description
of the index, which is where all the action in git happens.
This document is to supplement that, not replace it.
Like other version control systems, git has a current version (referred
to as HEAD) in its object database, you make changes in the working
directory, and then commit them, which appends a new version and makes
that the new HEAD.
However, there's also this "index" thing interposed. As "man git"
explains, you can have one version of the file in the HEAD, a second
in the index, and a third in the working directory. That's weird
and confusing - why does git allow that? Why isn't the index just an
implementation detail that caches the HEAD until you commit a new one?
The answer is merging, which does all its work in the index. Being a
toolkit, git has to pass partial merges around between its various
tools, which means keeping track of multiple files all competing for
the same name. Neither the object database nor the working directory
let you have multiple files with the same name.
The index is really very simple. It's a series of structures, each
describing one file. There's an object ID (SHA1) of the contents,
some file metadata to detect changes (time-stamps, inode number, size,
permissions, owner, etc.), and the path name relative to the root of the
working directory. It's always stored sorted by path name, for efficient
merging. By watching for metadata changes, git can efficiently detect
that a a file may have changed, and only open and examine those files.
At (almost) any time, you can take a snapshot of the index and write
it as a tree object.
The only interesting feature is that each entry has a 2-bit stage number.
Normally, this is always zero, but each path name is allowed up to three
different versions (object IDs) in the index at once. This is used to
represent an incomplete merge, and an unmerged index entry (with more
than one version) prevents committing the index to the object database.
Some porcelain layers, such as cogito, work to hide the index and this
potential confusion, but core git (shich is being described here) exposes
it.
* Terminology - heads, branches, refs, and revisions
(This is a supplement to what's already in "man git".)
The most common object needed by git primitives is a tree. Since every
commit or tag refers to a unique tree, both of these are acceptable
"tree-ish" objects and can be used basically anywhere a tree is required.
Likewise, a tag almost always refers to a commit, so is "commit-ish"
and can be used where a commit is required.
(I'd say a tag *always* points to a commit, but it's possible to tag
a tree directly. Probably the only time you will ever see this is
the v2.6.11 tag in the Linux history, because git was still under
heavy development and Linus was still making up the rules as he went
along.)
As soon as you get to the porcelain, the most commonly used object is
a commit. Also known as a revision, this is a tree plus a history.
While you can always use the full object ID, you can also use a reference.
A reference is a file that contains a 40-character hex SHA1 object ID
(and a trailing newline). When you specify the name of a reference,
it is searched for in one of the directories:
.git/ (or $GIT_DIR)
.git/refs/ (or $GIT_DIR/refs/)
.git/refs/heads/ (or $GIT_DIR/refs/heads/)
.git/refs/tags/ (or $GIT_DIR/refs/tags/)
You may use subdirectories by including slashes in the reference name.
There is no search order; if searching the above four path prefixes
produces more than one match for the reference name (it's ambiguous),
then the name is not valid.
There is additional syntax (which looks like "commit~3^2~17") for
specifying an ancestor of a given commit (or tag). This is documented
in detail in the documentation for git-rev-parse. Briefly, commit^
is the parent of the given commit. commit^^ is the grandparent, etc..
If there is more than one ancestor (a merge), then they can be referenced
as commit^1 (a synonym for commit^), commit^2, commit^3, etc. (commit^0
gives the commit object itself. A no-op if you're starting from a commit,
but it lets you get the commit object from a tag object.)
As long strings of ^ can be annoying, they can be abbreviated using ~
syntax. commit^^^ is the same as commit~3, ^^^^ is the same as ~4, etc.
You can see lots of examples in the output of "git-show-branch".
Now, the although the most primitive git tools don't care, a convention
among all the porcelain is that the current head of development is
.git/HEAD, a symbolic link to a reference under refs/heads/.
git-init-db creates HEAD pointing to refs/heads/master, and that is
traditionally the name used for the "main trunk" of development.
Note that initially refs/heads/master doesn't exist - HEAD is a
dangling symlink! This is okay, and will cause the initial commit
to have zero parents.
A "head" is mostly synonymous with a "branch", but the terms have
different emphasis. The "head" is particularly the tip of the branch,
where future development will be appended. A "branch" is the entire
development history leading to the head. However, as far as git is
concerned, they're both references to commit objects, referred to from
refs/heads/.
When you actually do more (with git-commit, or git-merge), then the
current HEAD reference is overwritten with the new commit's id, and
the old HEAD becomes HEAD^. Since HEAD is a symlink, it's the file
in refs/heads/ that's actually overwritten. (See the git-update-ref
documentation for further details.)
The git-checkout command actually changes the HEAD symlink. git-checkout
enforces the rule that it will only check out a branch under refs/heads.
You can use refs/tags as a source for git-diff or any other command that
only examines the revision, but if you want to check it out, you have
to copy it to refs/heads.
* The git command
Git commands are generally separate executables or scripts, named with
a common "git-" prefix. There's also a small wrapper called simply
"git" which converts a command like "git commit file.c" into "git-commit
file.c". This usage resembles CVS and many other version control systems.
People vary in which form they prefer to use. I use the git- prefixed
commands, because you have to ask for the man pages by those names,
and you can get tab-completion of the command names in the shell.
(With no special effort; yes, I know it can be done in many shells.)
However, there are plans for change here. Due to the large number of git
commands (many of which are helpers not designed for interactive use),
there have been complaints about the clutter in /usr/bin. There has
been motion towards putting the git-* commands in their own directory,
to be invoked by the /usr/bin/git wrapper.
In this case, you'll have to leave out the initial hyphen, or add the
git binary directory to your $PATH.
* Resetting
The "undo" command for commits to the object database is git-reset.
Like all deletion-type commands, be careful or you'll hurt yourself.
Given a commit (using any of the syntaxes mentioned above), this
sets the current HEAD to refer to the given commit.
This does NOT alter the HEAD symlink (as git-checkout <branch> will
do), but actually changes the reference pointed to by HEAD
(e.g. refs/heads/master) to contain a new object ID.
The classic example is to undo an erroneous commit, use
"git-reset HEAD^".
There are actually three kinds of git-reset:
git-reset --soft: Only overwrite the reference. If you need to, you
can put everything back with a second git-reset --soft OLD_HEAD.
git-reset --mixed: This is the default, which I always think of as
"--medium". Overwrite the reference, and (using git-read-tree)
read the commit into the index. The working directory is unchanged.
git-reset --hard: Do everything --mixed does, and also check out the index
into the working directory, and delete any working directory
files whose names were in the old version but not in the new.
This really erases all traces of the previous version.
The space taken up by the abandoned commit won't actually be
reclaimed until you collect garbage with git-prune.
git-reset with no commit specified is "git-reset HEAD", which is much
safer because the object reference is not actually changed. This can be
used to undo changes in the index (or, with --hard, working directory)
that you did not intend. Note, however, that it is not selective.
"git-checkout" has options for doing this selectively.
Like being sure what directory you're in when typing "rm -r", think
carefully about what branch you're on when typing "git-reset <commit>".
There is an undelete: git-reset stores the previous HEAD commit in
OLD_HEAD. And git-lost-found can find leftover commits until you do
a git-prune.
* Merging
Merging is central to git operations. Indeed, a big difference between
git and other version control systems is that git assumes that a change
will be merged more often than it's written, as it's passed around
different developers' repositories. Even "git checkout" is a specialized
sort of merge.
The heart of merging is git-read-tree, but if you can understand it from
the man page, you're doing better than me.
As mentioned, the index and the working directory versions of a file
could both be different from the HEAD. Git lets you merge "under" your
current working directory edits, as long as the merge doesn't change
the files you're editing.
There are some special cases of merging, but let me start with the
procedure for the general 3-way merge case: merging branch B into branch A
(the current HEAD).
1) Given two commits, find a common ancestor O to server as the origin
of the merge. The basic "resolve" algorithm uses git-merge-base for
the task, but the "recursive" merge strategy gets more clever in the
case where there are multiple candidates. I won't got into what it
does, but it does a pretty good job.
2) Add all three input trees (the Origin, A, and B) to the index by
"git-read-tree -m O A B". The index now contains up to three copies
of every file. (Four, including the original, but that is discarded
before git-read-tree returns.)
Then, for each file in the index, git-read-tree does the following:
2a) For each file, git-merge-tree tries to collapse the various
versions into one using the "trivial in-index merge". This just
uses the file blob object names to see if the file contents
are identical, and if two or more of the three trees contain an
identical copy of this file, it is merged. A missing (deleted)
file matches another missing file.
Note that this is NOT a majority vote. If A and B agree on the
contents of the file, that's what is used. (Whether O agrees is
irrelevant in this case.) But if O and A agree, then the change
made in B is taken as the final value. Likewise, if O and B agree,
then A is used.
2b) If this is possible, then a check is made to see if the merge would
conflict with any uncommitted work in the index or change the index
out from under a modified working directory file. If either of
those cases happen, the entire merge is backed out and fails.
(In the git source, the test "t/t1000-read-tree-m-3way.sh" has
a particularly detailed description of the various cases.)
If the merge is possible and safe, the versions are collapsed
into one final result version.
2c) If all three versions differ, the trivial in-index merge is
not possible, and the three source versions are left in the
index unmerged. Again, if there was uncommitted work in the
index or the working directory, the entire merge fails.
3) Use git-merge-index to iterate over the remaining unmerged files, and
apply an intra-file merge. The intra-file merge is usually done with
git-merge-one-file, which does a standard RCS-style three-way merge
(see "man merge").
4) Check out all the successfully merged files into the working directory.
5) If automatic merging was successful on every file, commit the merged
version immediately and stop.
6) If automatic merging was not complete, then replace the working
directory copies of any remaining unmerged files with a merged copy
with conflict markers (again, just like RCS or CVS) in the working
directory. All three source versions are available in the index for
diffing against.
(We have not destroyed anything, because in step 2c), we checked to make
sure the working directory file didn't have anything not in the
repository.)
7) Manually edit the conflicts and resolve the merge. As long as an
unmerged, multi-version file exists in the index, committing the
index is forbidden. (You can use the options to git-diff to
see the changes.)
8) Commit the final merged version of the conflicting file(s), replacing
the unmerged versions with the single finished version.
Note that if the merge is simple, with no one file edited on both
branches, git never has to open a single file. It reads three tree
objects (recursively) and stat(2)s some working directory files to
verify that they haven't changed.
Also note that this aborts and backs out rather than overwrite
anything not committed. You can merge "under" uncommitted edits
only if those edits are to files not affected by the merge.
There's one special case to the rule that "you can't merge a file with
uncommitted changes in the index": if the changes match what the merge
would produce anyway (the patch from branch B has already been applied),
the merge succeeds. There's no point in making you undo a change just
so the merge can redo it.
* 2-way merging
This merge is used by git-checkout to switch between two branches,
while preserving any changes in the working directory and index.
A "2-way merge" is actually a 3-way merge with the contents of the
index as the "current HEAD", and the original HEAD as the Origin.
However, this merge is designed only for simple cases and only supports
the "trivial merge" cases. It does not fall back to an intra-file merge.
Like the 3-way case, if a particular file hasn't changed between
the previous and new two heads, then git will preserve any uncommitted
edits, in both the index and the working directory.
If the file has changed in any way, git doesn't try to perform
any sort of intra-file merge, it just fails.
(Exception: like the 3-way merge, if the uncommitted change makes the
file the same as in the new head, the merge will succeed.)
* 1-way merging
This is only used by git-reset, and is just an optimization over
plain git-read-tree, but still it's interesting.
Plain (non-merging) git-read-tree will overwrite the index entries with
those from the tree. This invalidates the cached stat data, causing
git to think all the working directory files are "potentially changed"
until you do a git-update-index --refresh.
In particular, this means that a subsequenct git-checkout-index,
such as "git-reset --hard" performs, would overwrite every file
in the working directory, even if only with a copy of itself,
causing a lot of extra work next time you run make.
By specifying a 1-way merge, any index entry whose contents (object ID)
matches the incoming tree will have its cached stat data preserved.
Thus, git will know if the working directory file is not changed, and
will not overwrite if you execute git-checkout-index.
This is just an efficiency hack, so it's not terribly important
to remember.
* Special merges - already up to date, and fast-forward
There are two cases of 3-way or 2-way merging that are special.
Recall that the basic merge pattern is
B--------> A+B
/ /
/ /
O -----> A
The two special cases arise if one of A or B is a direct ancestor of
the other. In that case, the common ancestor of both A and B is the
older of the two commits. And the merged result is simply the
newer of the two, unchanged.
Recalling that we are merging B into A, if B is a direct ancestor of A,
then A already includes all of B. A is "already up to date" and not
changed at all by the merge.
The other case you'll hear mentioned, because it happens a lot when
pulling, is when A is a direct ancestor of B. In this case, the
result of the merge is a "fast-forward" to B.
Both of these cases are handled very efficiently by the in-index merge
done by git-read-tree.
* Deleted files during merges
There is one small wrinkle in git's merge algorithm that will probably
never bite you, but I ought to explain anyway, just because it's so rare
that it's difficult to discover it by experiment.
The index contains a list of all files that git is tracking. If the
index file is empty or missing and you do a commit, you write an empty
tree with no files.
When merging, if git finds no pre-existing index entry for a path it is
trying to merge, it considers that to mean "status unknown" rather than
"modified by being deleted". Thus, this is not uncommitted work
in the index file, and does not block the merge. Instead, the
file will reappear in the merge.
This is because it is possible to blow away the index file (rm .git/index
will do it quite nicely), and if this was considered a modification to
be preserved, it would cause all sorts of conflicts.
So the one change to the index that will NOT be preserved by a merge is
the removal of a file. A missing index entry is treated the same as an
unmodified index entry. The index will be updated, and when you check
out the revision, the working directory file will be (re-)created.
Note that none of this affects you in the usual case where you make
changes in the working directory only, and leave the index equal to HEAD
until you're ready to commit.
* Packs
Originally, git stored every object in its own file, and used rsync
to share repositories. It was quickly discovered that this brought
mighty servers to their knees. It's great for retrieving a small
subset of the database the way git usually does, but rsync scans the
whole .git/objects tree every time.
So packs were developed. A pack is a file, built all at once, which
contains many delta-compressed objects. With each .pack file,
there's an accompanying .idx file that indexes the pack so that
individual objects can be retrieved quickly.
You can reduce the disk space used by your repositories by periodically
repacking them with git-repack. Normally, this makes a new incremental
pack of everything not already packed. With the -a flag, this repacks
everything for even greater compression (but takes longer).
The git wire protocol basically consists of negotiation over what
objects needs to be transferred followed by sending a custom-built pack.
The .idx file can be reconstructed from the .pack file, so it's
never transferred.
[[ Is once every few hundred commits a good rule of thumb for repacking?
When .git/objects/?? reaches X megabytes? I think too many packs is
itself a bad thing, since they all have to be searched. ]]
* Raw diffs
A major source of git's speed is that it tries to avoid accessing files
unnecessarily. In particular, files can be compared based on their
object IDs without needing to open and read them. As part of this,
the responsibility for finding file differences (printing diffs) is
divided into finding what files have changed, and finding the changes
within those files.
This is all explained in the Documentation/diffcore.txt in the git
distribution, but the basics is that many of the primitives spit out a
line like this:
:100755 100755 68838f3fad1d22ab4f14977434e9ce73365fb304 0000000000000000000000000000000000000000 M git-bisect.sh
when asked for a diff. This is known as a "raw diff". They can be
told to generate a human-readable diff with the "-p" (patch) flag.
The git-diff command includes this by default.
* Advice on using git
If you're used to CVS, where branches and merges are "advanced" features
that you can go a long time, you need to learn to use branches in git a
lot more. Branch early and often. Every time you think about developing
a feature or fixing a bug, create a branch to do it on.
In fact, avoid doing any development on the master branch. Merges only.
A branch is the git equivalent of a patch, and merging a branch is the
equivalent of applying that patch. A branch gives it a name that
you can use to refer to it. This is particularly useful if you're
sharing your changes.
Once you're done with a branch, you can delete it. This is basically
just removing the refs/heads/<branch> file, but "git-branch -d" adds a
few extra safety checks. Assuming you merged the branch in, you can
still find all the commits in the history, it's just the name that's
been deleted.
You can also rename a branch by renaming the refs/heads/branch file.
There's no git command to do this, but as long as you update
the HEAD symlink if necessary, you don't need one.
Periodically merge all of the branches you're working on into a testing
branch to see if everything works. Blow away and re-create the
testing branch whenever you do this. When you like the result,
merge them into the master.
* The .git directory
There are a number of files in the .git directory used by the
porcelain. In case you're curious (I was), this is what they are:
index
- The actual index file.
objects/
- The object database. Can be overridden by $GIT_OBJECT_DIRECTORY
hooks/
- where the hook scripts are kept. The standard git template includes
examples, but disabled by being marked non-executable.
info/exclude
- Default project-wide list of file patterns to exclude from notice.
To this is added the per-directory list in .gitignore.
See the git-ls-files docs for full details.
refs/
- References to development heads (branches) and tags.
remotes/
- Short names of remote repositories we pull from or push to.
Details are in the "git-fetch" man page.
HEAD
- The current default development head.
- Created by git-init-db and never deleted
- Changed by git-checkout
- Used by git-commit and any other command that commits changes.
- May be a dangling pointer, in which case git-commit
does an "initial checkin" with no parent.
COMMIT_EDITMSG
- Temp used by git-commit to edit a commit message.
COMMIT_MSG
- Temp used by git-commit to form a commit message,
post-processed from COMMIT_EDITMSG.
FETCH_HEAD
- Just-fetched commits, to be merged into the local trunk.
- Created by git-fetch.
- Used by git-pull as the source of data to merge.
MERGE_HEAD
- Keeps track of what heads are currently being merged into HEAD.
- Created by git-merge --no-commit with the heads used
- Deleted by git-checkout and git-reset (since you're abandoning
the merge)
- Used by git-commit to supply additional parents to the current commit.
(And deleted when done.)
MERGE_MSG
- Generated by git-merge --no-commit.
- Used by git-commit as the commit message for a merge
(If present, git-commit doesn't prompt.)
MERGE_SAVE
- cpio archive of all locally modified files created by
"git-merge" before starting to do anything, if multiple
merge strategies are being attempted.
Used to rewind the tree in case a merge fails.
ORIG_HEAD
- Previous HEAD commit prior to a merge or reset operation.
LAST_MERGE
- Set by the "resolve" strategy to the most recently merged-in branch.
Basically, a copy of MERGE_HEAD. Not used by the other merge strategies,
and resolve is no longer the default, so its utility is very limited.
BISECT_LOG
- History of a git-bisect operation.
- Can be replayed (or, more usefully, a prefix can) by "git-bisect replay"
BISECT_NAMES
- The list of files to be modified by git-bisect.
- Set by "git-bisect start"
TMP_HEAD (used by git-fetch)
TMP_ALT (used by git-fetch)
* Git command summary
There are slightly over a hundred git commands. This section tries to
classify them by purpose, so you can know which commands are intended to
be used for what. You can always use the low-level plumbing directly,
but that's inconvenient and error-prone.
Helper programs (not for direct use) for a specific utility are shown
indented under the program they help.
Note that all of these can be invoked using the "git" wrapper by replacing
the leading "git-" with "git ". The results are exactly the same.
There is a suggestion to reduce the clutter in /usr/bin and move all
the git binaries to their own directory, leaving just the git wrapper
in /usr/bin. so you'll have to use it or adjust your $PATH. But that
hasn't happened yet. In the meantime, including the hyphen makes
tab-completion work.
I include ".sh", ".perl", etc. suffixes to show what the programs are
written in, so you can read those scripts written in languages you're
familiar with. These are the names in the git source tree, but the
suffix is not included in the /usr/bin copies.
+ Administrative commands
git-init-db
+ Object database maintenance:
git-convert-objects
git-fsck-objects
git-lost-found.sh
git-prune.sh
git-relink.perl
+ Pack maintenance
git-count-objects.sh
git-index-pack
git-pack-objects
git-pack-redundant
git-prune-packed
git-repack.sh
git-show-index
git-unpack-objects
git-verify-pack
+ Important primitives
git-commit-tree
git-rev-list
git-rev-parse
+ Useful primitives
git-ls-files
git-update-index
+ General script helpers (used only by scripts)
git-cat-file
git-check-ref-format
git-checkout-index
git-fmt-merge-msg.perl
git-hash-object
git-ls-tree
git-repo-config
git-unpack-file
git-update-ref
git-sh-setup.sh
git-stripspace
git-symbolic-ref
git-var
git-write-tree
+ Oddballs
git-mv.perl
+ Code browsing
git-diff.sh
git-diff-files
git-diff-index
git-diff-tree
git-diff-stages
git-grep.sh
git-log.sh
git-name-rev
git-shortlog.perl
git-show-branch
git-whatchanged.sh
+ Making local changes
git-add.sh
git-bisect.sh
git-branch.sh
git-checkout.sh
git-commit.sh
git-reset.sh
git-status.sh
+ Cherry-picking
git-cherry.sh
git-patch-id
git-cherry-pick.sh
git-rebase.sh
git-revert.sh
+ Accepting changes by e-mail
git-apply
git-am.sh
git-mailinfo
git-mailsplit
git-applypatch.sh
git-applymbox.sh
+ Publishing changes by e-mail
git-format-patch.sh
git-send-email.perl
+ Merging
git-merge.sh
git-merge-base
git-merge-index
git-merge-one-file.sh
git-merge-octopus.sh
git-merge-ours.sh
git-merge-recursive.py
git-merge-resolve.sh
git-merge-stupid.sh
git-read-tree
git-resolve.sh
git-octopus.sh
+ Making releases
git-get-tar-commit-id
git-tag.sh
git-mktag
git-tar-tree
git-verify-tag.sh
+ Accepting changes by network
git-clone.sh
git-clone-pack
git-fetch.sh
git-fetch-pack
git-local-fetch
git-http-fetch
git-ssh-fetch
git-ls-remote.sh
git-peek-remote
git-parse-remote.sh
git-pull.sh
git-ssh-pull
git-shell
git-receive-pack
+ Publishing changes by network
git-daemon
git-push.sh
git-http-push
git-ssh-push
git-ssh-upload
git-request-pull.sh
git-send-pack
git-update-server-info
git-upload-pack
All of the basic git commands are designed to be scripted. When
scripting, use the "--" option to ensure that files beginning with
"-" won't be interpreted as options, and the "-z" option to output
NUL-terminated file names so embedded newlines won't break things.
(A person who'd do either of these on purpose is probably crazy, but
it's not actually illegal.)
Looking at existing shell scripts can be very informative.
* Detailed list
Here's a repeat, including descriptions. I don't try to include
every detail you can find on the man page, but to explain when
you'd want to use a command.
+ Administrative commands
git-init-db
This creates an empty git repository in ./.git (or $GIT_DIR if
that is non-null) using a system-wide template.
It won't hurt an existing repository.
+ Object database maintenance:
git-convert-objects
You will *never* need to use this command.
The git repository format has undergone some revision since its
first release. If you have an ancient and crufty git repository
from the very very early days, this will convert it for you.
But as you're new to git, it doesn't apply.
git-fsck-objects
Validate the object database. Checks that all references
point somewhere, all the SHA1 hashes are correct, and that
sort of thing.
This walks the entire repository, uncompressing and hashing
every object, so it takes a while. Note that by default,
it skips over packs, which can make it seem misleadingly fast.
git-lost-found.sh
Find (using git-fsck-objects) any unreferenced commits and
tags in the object database, and place them in a .git/lost-found
directory. This can be used to recover from accidentally
deleting a tag or branch reference that you wanted to keep.
This is the opposite of git-prune.
git-prune.sh
Delete all unreachable objects from the object database.
It deletes useless packs, but does not remove useless
objects from the middle of partially useful packs.
Git leaks objects in a number of cases, such as unsuccessful
merges. The leak rate is generally a small fraction of
the rate at which the desired history grows, so it's not
very alarming, but occasionally running git-prune will
eliminate the
If you deliberately throw away a development branch, you
will need to run this command to fully reclaim the disk space.
On something like the full Linux repository, this takes
a while.
git-relink.perl
Merge the objects stores of multiple git repositories by
making hard links between them. Useful to save space if
duplicate copies are accidentally created on one machine.
+ Pack maintenance
The classic git format is to compress and store each object
separately. This is still used for all newly created changes.
However, objects can also be stored en masse in "packs" which
contain many objects and tan take advantage of delta-compressing.
Repacking your repositories periodically can save space.
(Repacking is pretty quick but not quick enough to be
comfortable doing every commit.)
git-count-objects.sh
Print the number and total size of unpacked objects in the
repository, to help you decide when is a good time to repack.
git-index-pack
A pack file has an accompanying .idx file to allow rapid lookup.
This regenerates the .idx file from the .pack. This is almost never
needed directly, but can be used after transferring a .pack file
between machines.
git-pack-objects
Given a list of objects on stdin, build a pack file. This is
a helper used by the various network communication scripts.
git-pack-redundant
Produce a list of redundant packs, for feeding to "xargs rm".
A helper for git-prune.
git-prune-packed
Delete unpacked object files that are duplicated in packs.
(With -n, only lists them.) A helper for git-prune.
git-repack.sh
Make a new pack with all the unpacked objects.
With -a, include already-packed objects in the new pack.
With -d as well, deletes all the old packs thereby made redundant.
git-show-index
Dump the contents of a pack's .idx file. Mostly for
debugging git itself.
git-unpack-objects
Unpack a .pack file, the opposite of git-pack-objects. With -n,
doesn't actually create the files. With -q, suppresses the
progress indicator.
git-verify-pack
Validate a pack file. Useful when debugging git, and when
downloading from a remote source. A helper for git-clone.
+ Important primitives
Although these primitives are not used directly very frequently,
understanding them will help you understand other git commands
that wrap them.
git-commit-tree
Create a new commit object from a tree and a list of parent
commits. This is the primitive that's the heart of git-commit.
(It's also used by git-am, git-applypatch, git-merge, etc.)
git-rev-list
Print a list of commits (revisions), in reverse chronological
order. This is the heart of git-log and other history examination
commands, and the options for specifying parts of history are
shared by all of them.
In particular, it takes an arbitrary number of revisions as
arguments, some of which may be prefixed with ^ to negate them.
These make up "include" and "exclude" sets. git-rev-list
lists all revisions that are ancestors of the "include" set
but not ancestors of the "exclude" set.
For this purpose, a revision is considered an ancestor of itself.
Thus, "git-rev-list ^v1.1 v1.2" will list all revisions from
the v1.2 release back to (but not including) the v1.1 release.
Because this is so convenient, a special syntax, "v1.1..v1.2"
is allowed as an equivalent. However, occasionally the general
form is useful. For example, adding ^branch will show the trunk
(including merges from the branch), but exclude the branch itself.
Similarly, "branch ^trunk", a.k.a. trunk..branch, will show
all work on the branch that hasn't been merged to the trunk.
This works even though trunk is not a direct ancestor of branch.
Git-rev-list has a variety of flags to control it output format.
The default is to just print the raw SHA1 object IDs of the
commits, but --pretty produces a human-readable log.
You can also specify a set of files names (or directories),
in which case output will be limited to commits that modified
those files.
This command is used extensively by the git:// protocol to compute
a set of objects to send to update a repository.
git-rev-parse
This is a very widely used command line canonicalizer for git
scripts. It converts relative commit references (e.g. master~3)
to absolute SHA1 hashes, and can also pass through arguments
not recognizable as references, so the script can interpret them.
It is important because it defines the <rev> syntax.
This takes a variety of options to specify how to prepare the
command line for the script's use. --verify is a particularly
important one.
+ Useful primitives
These primitives are potentially useful directly.
git-ls-files
List files in the index and/or working directory. A variety of
options control which files to list, based on whether they
are the same in both places or have been modified. This command
is the start of most check-in scripts.
git-update-index
Copy the given files from the working directory into the index.
This create the blob objects, but no trees yet. (Note that
editing a file executing this multiple times without creating a
commit will generate orphaned objects. Harmless.)
A lot of early git documentation emphasizes this command,
since you need to have modified files in the index before you
can generate tree and commit objects. But this is done by
git-commit, and you rarely want to invoke git-update-index
directly any more.
One common safe option is "git-update-index --refresh". This
looks for files whose metadata (modification time etc.) has
changed, but not their contents, and updates the metadata in the
index so the file contents won't have to be examined again.
+ General script helpers (used only by scripts)
These are almost exclusively helpers for use in porcelain
scripts and have little use by themselves from the command line.
git-cat-file
Extract a file from the object database. You can ask for
an object's type or size given only an object ID, but
to get its contents, you have to specify the type. This
is a deliberate safety measure.
git-check-ref-format
Verify that the reference specified on the command line is
syntactically valid for a new reference name under $GIT_DIR/refs.
A number of characters (^, ~, :, and ..) are reserved; see the man
page for the full list of rules.
git-checkout-index
Copy files from the index to the working directory, or to a
specified directory. Most important as a helper for git-checkout,
this is also used by git-merge and git-reset.
git-fmt-merge-msg.perl
Generate a reasonable default commit message for a merge.
Used by git-pull and git-octopus.
git-hash-object
Very primitive helper to turn an arbitrary file into an object,
returning just the ID or actually adding it to the database.
Used by the cvs-to-git and svn-to-git import filters.
git-ls-tree
List the contents of a tree object. Will tell you all the files
in a commit. Used by the checkout scripts git-checkout and git-reset.
git-repo-config
Get and set options in .git/config. The .git/config format
is designed to be human-readable. This gives programmatic
access to the settings. This currently has a lot of overlap
with the function of git-var.
git-unpack-file
Write the contents of the given block to a temporary file,
and return the name of that temp file. Used most often
by merging scripts.
git-update-ref
Rewrite a reference (in .git/refs/) to point to a new object.
"echo $sha1 > $file" is mostly equivalent, but this adds locking
so two people don't update the same reference at once.
git-sh-setup.sh
This is a general prefix script that sets up
$GIT_DIR and $GIT_OBJECT_DIRECTORY for a script,
or errors out if the git control files can't be found.
git-stripspace
Remove unnecessary whitespace. Used mostly on commit messages
received by e-mail.
git-symbolic-ref
This queries or creates symlinks to references such as HEAD.
Basically equivalent to readlink(1) or ln -s, this also works
on platforms that don't have symlinks. See the man page.
git-var
Provide access to the GIT_AUTHOR_IDENT and/or GIT_COMMITTER_IDENT
values, used in various commit scripts. This currently has a
lot of overlap with the function of git-repo-config.
git-write-tree
Generate a tree object reflecting the current index. The output
is the tree object; if you don't remember it somewhere (usually,
pass it to git-commit-tree), it'll be lost.
This requires that the index be fully merged. If any incomplete
merges are present in the index (files in stages 1, 2 or 3),
git-write-tree will fail.
+ Oddballs
git-mv.perl
I have to admit, I'm not quite sure what great advantages this is
supposed to have over plain "mv" followed by "git-update-index",
or why it's complex enough to need perl.
Basically, this renames a file, deleting its old name and adding
its new name to the index. Git doesn't have the concept of a
permanent file ID tracked across renames, so there's no need to
use a special tool, but it is a two-step process to rename a file:
- Rename the file
- git-add the new name
Followed by which you must commit both the old and new names.
I suppose if you have a mixture of version-controlled and
non-version-controlled files with similar names, the fact that
git-mv knows not to touch the latter could be useful.
+ Code browsing
git-diff.sh
Show changes between various trees. Takes up to two tree
specifications, and shows the difference between the versions.
Zero arguments: index vs. working directory (git-diff-files)
One: tree vs. working directory (git-diff-index)
One, --cached: tree vs. index (git-diff-index)
Two: tree vs. tree (git-diff-tree)
This wrapper always produces human-readable patch output.
The helpers all produce "diff-raw" format unless you supply
the -p option.
There are some interesting options. Unfortunately, the git-diff
man page is annoyingly sparse, and refers to the helper scripts'
documentation rather than describing the many useful options
they all have in common. Please do read the man pages of the
helpers to see what's available.
In particular, although git does not explicitly record file
renames, it has some pretty good heuristics to notice things.
-M tries to detect renamed files by matching up deleted files
with similar newly created files. -C tries to detect copies
as well. By default, -C only looks among the modified files for
the copy source. For common cases like splitting a file in two,
this works well. The --find-copies-harder searches ALL files
in the tree for the copy source. This can be slow on large trees!
See Documentation/diffcore.txt for an explanation of how all
this works.
git-diff-files
Compare the index and the working directory.
git-diff-index
Compare the working directory and a given tree. This is the
git equivalent of the single-operand form of "cvs diff".
If "--cached" is specified, uses the index rather than the working
directory.
git-diff-tree
Compare two trees. This is the git equivalent of the two-operand
form of "cvs diff". This command is sometimes useful by itself
to see the changes made by a single commit. If you give it
only one commit on the command line, it shows the diff between
that commit and its first parent. If the commit specification
is long and awkward to type, using "git-diff-tree -p <commit>"
can be easier than "git-diff <commit>^ <commit>".
git-diff-stages
Although not called by git-diff, there is a fourth diff helper
routine, used to compare the various versions of an unmerged
file in the index. It is intended for use by merging porcelain.
git-grep.sh
A very simple wrapper that runs git-ls-files and greps the
output looking for a file name. Does nothing fancy except
saves typing.
git-log.sh
Wrapper around git-rev-list --pretty. Shows a history
of changes made to the repository. Takes all of git-rev-list's
options for specifying which revisions to list.
git-name-rev
Find a symbolic name for the commit specified on the
command line, and returns a symbolic name of the form
"maint~404^2~7". Basically, this does a breadth-first search
from all the heads in .git/refs looking for the given commit.
git-shortlog.perl
This is a filter for the output of "git-log --pretty=short"
to generate a one-line-per-change "shortlog" as Linus likes.
git-show-branch
Visually show the merge history of the references given as
arguments. Prints one column per reference and one line per
commit showing whether that commit is an ancestor of each
reference.
git-whatchanged.sh
A simple wrapper around git-rev-list and git-diff-tree,
this shows the change history of a repository. Specify a
directory or file on the command line to limit the
output to changes affecting those files. This isn't
the same as "cvs annotate", but it serves a similar purpose
among git folks.
You can add the -p option to include patches as well as log
comments. You can also add the -M or -C option to follow
history back through file renames.
-S is interesting: it's the "pickaxe" option. Given a string,
this limits the output to changes that make that string appear
or disappear. This is for "digging through history" to see when
a piece of code was introduced. The string may (and often does)
contain embedded newlines. See Documentation/cvs-migration.txt.
+ Making local changes
All of these are examples of "porcelain" scripts. Reading the
scripts themselves can be informative; they're generally not
too confusing.
git-add.sh
A simple wrapper around "git-ls-files | git-update-index --add"
to add new files to the index. You may specify directories.
You need to invoke this for every new file you want git to
track.
git-bisect.sh
Utility to do a binary search to find the change that broke something.
The heart of this is in "git-rev-list --bisect"
A very handy little utility! Kernel developers love it
when you tell them exactly which patch broke something.
NOTE: this uses the head named "bisect", and will blow
away any existing branch by that name. Try not to
create a branch with that name.
There are three steps:
git-bisect start [<files>]
- Reset to start bisecting. If any files are specified,
only they will be checked out as bisection proceeds.
git-bisect good [<revision>]
- Record the revision as "good". The change being sought
must be after this revision.
git-bisect bad [<revision>]
- Record the revision as "bad". The change being sought
must be before or equal to this revision.
As soon as you have specified one good version and one bad version,
git-bisect will find a halfway point and check out that
revision. Build and test it, then report it as good or bad,
and git-bisect will narrow the search. Finally, git-bisect
will tell you exactly which change caused the problem.
git-bisect log
- Show a history of revisions.
git-bisect replay
- Replay (part of) a git-bisect log. Generally used
to recover from a mistake, you can truncate the log
before the mistake and replay it to continue.
If git-bisect chooses a version that cannot build, or you
are otherwise unable to determine whether it is good or bad,
you can change revisions with "git-reset --hard <revision>"
to another checkout between the current good and bad limits, and
continue from there. "git-reset --hard <revision>" is generally
dangerous, but you are on a scratch branch.
This can, of course, be used to look for any change, even
one for the better, if you can avoid being confused by the
terms "good" and "bad".
git-branch.sh
Most commonly used bare, to show the available branches.
Show, create, or delete a branch. The current branches
are simply the contents of .git/refs/heads/.
Note that this does NOT switch to the created branch!
For the common case of creating a branch and immediately
switching to it, "git-checkout -b <branch>" is simpler.
git-checkout.sh
This does two superficially similar but very different things
depending on whether any files or paths are specified on the
command line.
git-checkout [-f] [-b <new-branch>] <branch>
This switches (changes the HEAD symlink to) the specified
branch, updating the index and working directory to
reflect the change. This preserves changes in the
working directory unless -f is specified.
If -b is specified, a new branch is started from the
specified point and switched to. If <branch> is omitted,
it defaults to HEAD. This is the usual way to start a
new branch.
git-checkout [<branch>] [--] <paths>...
This replaces the files specified by the given paths with
the versions from the index or the specified branch.
It does NOT affect the HEAD symlink, just replaces the
specified paths. This form is like a selective form of
"git-reset". Normally, this can guess whether the first
argument is a branch name or a path, but you can use
"--" to force the latter interpretation.
With no branch, this is used to revert a botched edit of a
particular file.
Both forms use git-read-tree internally, but the net effect is
quite different.
git-commit.sh
Commit changes to the revision history. In terms of primitives,
this does three things:
1) Updates the index file with the working directory files
specified on the command line, or -a for all (using
git-diff-files --name-only | git-update_index),
2) Prompts for or generates a commit message, and then
3) Creates a commit object with the current index contents.
The prompt for a commit message includes the output of git-status,
so you can see what changes are being committed.
This also executes the pre-commit, commit-msg, and
post-commit hooks if present.
Files deleted from the working tree will be removed from the
index, but newly added files will not be automatically added,
even if explicitly specified on the command line; you must use
git-add for that.
Note that the default action, with no command line arguments,
is to commit only what's already in the index. The equivalent
of "cvs commit" is "git-commit -a".
git-reset.sh
Explained in detail in "resetting", above. This modifies the
current branch head reference (as pointed to by .git/HEAD)
to refer to the given commit. It does not modify .git/HEAD
Reset the current HEAD to the specified commit, so that future
checkins will be relative to it. There are three
variations:
--soft: Just move the HEAD link. The index is unchanged.
--mixed (default): Move the HEAD link and update the index file.
Any local changes will appear not checked in.
--hard: Move the HEAD links, update the index file, and
check out the index, overwriting the working
directory. Like "cvs update -C".
In case of accidents, this copies the previous head
object ID to ORIG_HEAD (which is NOT a symlink).
git-status.sh
Show all the files in the working directory and index that have
been changed since the current HEAD. The basic categories are:
1) Changed in the index, will be included in the next commit.
2) Changed in the working directory but NOT in the index; will
be committed only if mentioned on the git-commit command line
(or added manually via git-update-index)
3) Not tracked by git, but not explicitly ignored, either.
+ Cherry-picking
Cherry-picking is the process of taking part of the changes
introduced on one tree and applying those changes to another.
This doesn't produce a parent/descendant relationship in the
commit history.
To produce that relationship, there's a special type of merge you
can do if you've taken everything you want off a branch and
want to show it in the merge history without actually importing
any changes from it: ours. "git-merge -s ours" will generate a
commit that shows some branches were merged in, but not
actually alter the current HEAD source code in any way.
One thing cherry-picking is sometimes used for is taking a
development branch and re-organizing the changes into a patch
series for submission to the Linux kernel.
git-cherry.sh
This searches a branch for patches which have not been applied
to another. Basically, it finds the unpicked cherries.
It searches back to the common ancestor of the named branch and
the current head using git-patch-id to identify similarity
in patches.
git-patch-id
Generate a hash of a patch, ignoring whitespace and line numbers
so that "the same" patch, even relative to a different code base,
probably has the same hash, and different patches almost certainly
have different ones. git-cherry looks for patch hashes which
are present on the branch (source branch) that are not present
on the trunk (destination branch).
git-cherry-pick.sh
Given a commit (on a different branch), compute a diff between
it and its immediate parent, and apply it to the current HEAD.
This is actually the same script as "git revert", but works
forward. git-cherry finds the patches, this merges them.
Handles failures gracefully.
git-rebase.sh
Move a branch to a more recent "base" release. This just extracts
all the patches applied on the local head since the last merge
with upstream (using git-format-patch) and re-applies them
relative to the current upstream with git-am (explained under
"accepting changes by e-mail"). Finally, it deletes the old
branch and gives its name to the new one, so your branch now
contains all the same changes, but relative to a different base.
Basically the same as cherry-picking an entire branch.
(This uses git-cherry to find the patches, so is able to cope
with patches that were applied to the base.)
git-revert.sh
Undo a commit. Basically "patch -R" followed by a commit.
This is actually the same script as "git-cherry-pick", just
applies the patch in reverse, undoing a change that you don't
wish to back up to using git-reset. Handles failures gracefully
by telling the user what to do.
This reversion will create a commit in the history; it is
not like git-reset which erases history.
+ Accepting changes by e-mail
git-apply
Apply a (git-style extended) patch to the current index
and working directory.
git-am.sh
The new and improved "apply an mbox" script. Takes an
mbox-style concatenation of e-mails as input and batch-applies
them, generating one commit per message. Can resume after
stopping on a patch problem.
(Invoke it as "git-am --skip" or "git-am --resolved" to
deal with the problematic patch and continue.)
git-mailinfo
Given a single mail message on stdin (in the Linux standard
SubmittingPatches format), extract a commit message and
the patch proper.
git-mailsplit
Split an mbox into separate files.
git-applypatch.sh
Tries simple git-apply, then tries a few other clever merge
strategies to get a patch to apply. Used in the main loop
of git-am and git-applymbox.
git-applymbox.sh
This is Linus's original apply-mbox script. Mostly superseded by
git-am (which is friendlier and has more features), but he still
uses it, so it's maintained. This is so old it was originally
a test of the git core called "dotest", and that name is still
lurking in the temp file names.
+ Publishing changes by e-mail
git-format-patch.sh
Generate a series of patches, in the preferred Linux kernel
(Documentation/SubmittingPatches) format, for posting to lkml
or the like. This formats every commit on a branch as a separate
patch.
git-send-email.perl
Actually e-mail the output of git-format-patch.
(This uses direct SMTP, a matter of some controversy. Others feel
that /bin/mail is the correct local mail-sending interface.)
+ Merging
git-merge.sh
Merge one or more "remote" heads into the current head.
Some changes, when there has been change only on one branch or
the same change has been made to all branches, can be resolved
by the "trivial in-index" merge done by git-read-tree. For more
complex cases, git provides a number of different merge strategies
(with reasonable defaults).
Note that merges are done on a filename basis. While git tries
to detect renames when generating diffs, most merge strategies
don't track them by renaming. (The "recursive" strategy, which
recently became the default, is a notable exception.)
git-merge-base
Finds a common ancestor to use when comparing the changes made
on two branches. The simple case is straightforward, but if
there have been cross-merges between the branches, it gets
somewhat hairy. The algorithm is not 100% final yet.
(There's also --all, which lists all candidates.)
git-merge-index
This is the outer merging loop. It takes the name of a one-file
merge executable as an argument, and runs it for every incomplete
merge.
git-merge-one-file.sh
This is the standard git-merge-index helper, that tries to
resolve a 3-way merge. A helper used by all the merge strategies.
(Except "recursive" which has its own equivalent.)
git-merge-octopus.sh
Many-way merge. Overlaps should be negligible.
git-merge-ours.sh
A "dummy" merge strategy helper. Claims that we did the merge, but
actually takes the current tree unmodified. This is used to
cleanly terminate side branches that heve been cherry-picked in.
git-merge-recursive.py
A somewhat fancier 3-way merge. This handles multiple cross-merges
better by using multiple common ancestors.
git-merge-resolve.sh
git-merge-stupid.sh
Not actually used by git-merge, this is a simple example
merge strategy.
git-read-tree
Read the given tree into the index. This is the difference
between the "--soft" and "--mixed" modes of git-reset, but the
important thing this command does is simple merging.
If -m is specified, this can take up to three trees as arguments.
git-resolve.sh
OBSOLETE. Perform a merge using the "resolve" strategy.
Has been superseded by the "-s resolve" option to git-merge
and git-pull.
git-octopus.sh
OBSOLETE. Perform a merge using the "octopus" strategy.
Has been superseded by the "-s octopus" option to git-merge
and git-pull.
+ Making releases
git-get-tar-commit-id
Reads out the commit ID that git-tar-tree puts in its output.
(Or fails if this isn't a git-generated tar file.)
git-tag.sh
Create a tag in the refs/tags directory. There are two kinds:
"lightweight tags" are just references to commits. More
serious tags are GPG-signed tag objects, and people receiving
the git tree can verify that it is the version that you released.
git-mktag
Creates a tag object. Verifies syntactic correctness of its
input. (If you want to cheat, use git-hash-object.)
git-tar-tree
Generate a tar archive of the named tree. Because git does NOT
track file timestamps, this uses the timestamp of the commit,
or the current time if you specify a tree.
Also stores the commit ID in an extended tar header.
git-verify-tag.sh
Given a tag object, GPG-verify the embedded signature.
+ Accepting changes by network
Pulling consists of two steps: retrieving the remote commit
objects and everything they point to (including ancestors),
then merging that into the desired tree. There are still
separate fetch and merge commands, but it's more commonly done
with a single "git-pull" command. git-fetch leaves the commit
objects, one per line, in .git/FETCH_HEAD. git-merge will
merge those in if that file exists when it is run.
References to remote repositories can be made with long URLs,
or with files in the .git/remotes/ directory. The latter
also specifies the local branches to merge the fetched data into,
making it very easy to track a remote repository.
git-clone.sh
Create a new local clone of a remote repository.
(Can do a couple of space-sharing hacks when "remote" is on
a local machine.)
You only do this once.
git-clone-pack
Runs git-upload-pack remotely and places the resultant pack
into the local repository. Supports a variety of network
protocols, but "remote" can also be a different directory on
the current machine.
git-fetch.sh
Fetch the named refs and all linked objects from a remote repository.
The resultant refs (tags and commits) are stored in .git/FETCH_HEAD,
which is used by a later git-resolve or git octopus.
This is the first half of a "git pull" operation.
git-fetch-pack
Retrieve missing objects from a remote repository.
git-local-fetch
Duplicates a git repository from the local system.
(Er... is this used anywhere???)
git-http-fetch
Do a fetch via http. Http requires some kludgery on the
server (see git-update-server-info), but it works.
git-ssh-fetch
Do a fetch via ssh.
git-ls-remote.sh
Show the contents of the refs/heads/ and/or refs/tags/ directories
of a remote repository. Useful to see what's available.
git-peek-remote
Helper C program for the git-ls-remote script. Implements the
git protocol form of it.
git-parse-remote.sh
Helper script to parse a .git/remotes/ file. Used by a number
of these programs.
git-pull.sh
Fetches specific commits from the given remote repository,
and merges everything into the current branch. If a remote
commit is named as src:dst, this merges the remote head "src"
into the branch "dst" as well as the trunk. Typically, the "dst"
branch is not modified locally, but is kept as a pristine copy
of the remote branch.
One very standard example of this contention is that
a repository that is tracking another specifies "master:origin"
to provide a pristine local copy of the remote "master"
branch in the local branch named "origin".
git-ssh-pull
A helper program that pulls over ssh.
git-shell
A shell that can be used for git-only users. Allows git
push (git-receive-pack) and pull (git-upload-pack) only.
git-receive-pack
Receive a pack from git-send-pack, validate it, and add it to
the repository. Adding just the bare objects has no security
implications, but this can also update branches and tags, which
does have an effect.
Runs pre-update and post-update hooks; the former may do
permissions checking and disallow the upload.
This is the command run remotely via ssh by git-push.
+ Publishing changes by network
git-daemon
A daemon that serves up the git native protocol so anonymous
clients can fetch data. For it to allow export of a directory,
the magic file name "git-daemon-export-ok" must exist in it.
This does not accept (receive) data under any circumstances.
git-push.sh
Git-pull, only backwards. Send local changes to a remote
repository. The same .git/remotes/ short-cuts can be used,
and the same src:dst syntax. (But this time, the src is local
and the dst is remote.)
git-http-push
A helper to git-push to implement the http: protocol.
git-ssh-push
A helper to git-push to push over ssh.
git-ssh-upload
Another helper. This just does the equivalent of "fetch"
("throw"?) and doesn't actually merge the result. Obsolete?
git-request-pull.sh
Generate an e-mail summarizing the changes between two commits,
and request that the recipient pull them from your repository.
Just a little helper to generate a consistent and informative
format.
git-send-pack
Pack together a pile of objects missing at the destination and
send them. This is the sending half that talks to a remote
git-receive-pack.
git-update-server-info
To run git over http, auxiliary info files are required that
describes what objects are in the repository (since git-upload-pack
can't generate this on the fly). If you want to publish a
repository via http, run this after every commit. (Typically
via the hooks/post-update script.)
git-upload-pack
Like git-send-pack, but this is invoked by a remote git-fetch-pack.
^ permalink raw reply [relevance 1%]
* Re: How to clone-pack the HEAD?
@ 2005-12-15 5:29 8% ` Junio C Hamano
0 siblings, 0 replies; 200+ results
From: Junio C Hamano @ 2005-12-15 5:29 UTC (permalink / raw)
To: Petr Baudis; +Cc: git
Junio C Hamano <junkio@cox.net> writes:
> Not really. I take this back. What you want to do I did not
> understand well enough.
>
> HEAD is kinda special. A hack I can think of is to do ls-remote
> first and do the guess clone-pack does for full clone case, and
> then give a specific branch name to clone. That might work.
... and another way would be to do this; I'll put this (with
fixes if there is some needed) in "master" tonight.
Also I might want to give --keep option to fetch-pack as well;
clone-pack has some static functions that we can extract out to
a common file to link to both.
-- >8 --
Subject: [PATCH] clone-pack: make it usable for partial branch cloning.
clone-pack had some logic to accept subset of remote refs from
the command line and clone from there. However, it was never
used in practice and its problems were not found out so far.
This commit changes the command to output the object names of
refs to the standard output instead of making a clone of the
remote repository when explicit <head> parameters are given; the
output format is the same as fetch-pack.
The traditional behaviour of cloning the whole repository by
giving no explicit <head> parameters stays the same.
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
Documentation/git-clone-pack.txt | 6 +++++-
clone-pack.c | 13 +++++++++++--
2 files changed, 16 insertions(+), 3 deletions(-)
31ec6abf887ec95642cbe82fe61076e975494ab0
diff --git a/Documentation/git-clone-pack.txt b/Documentation/git-clone-pack.txt
index cfc7b62..39906fc 100644
--- a/Documentation/git-clone-pack.txt
+++ b/Documentation/git-clone-pack.txt
@@ -43,7 +43,11 @@ OPTIONS
The heads to update. This is relative to $GIT_DIR
(e.g. "HEAD", "refs/heads/master"). When unspecified,
all heads are updated to match the remote repository.
-
++
+Usually all the refs from existing repository are stored
+under the same name in the new repository. Giving explicit
+<head> arguments instead writes the object names and refs to
+the standard output, just like get-fetch-pack does.
Author
------
diff --git a/clone-pack.c b/clone-pack.c
index a99a95c..b5ce5d3 100644
--- a/clone-pack.c
+++ b/clone-pack.c
@@ -259,8 +259,17 @@ static int clone_pack(int fd[2], int nr_
status = clone_without_unpack(fd);
- if (!status)
- write_refs(refs);
+ if (!status) {
+ if (nr_match == 0)
+ write_refs(refs);
+ else
+ while (refs) {
+ printf("%s %s\n",
+ sha1_to_hex(refs->old_sha1),
+ refs->name);
+ refs = refs->next;
+ }
+ }
return status;
}
--
0.99.9n
^ permalink raw reply related [relevance 8%]
* [RFC] shallow clone
@ 2006-01-30 7:18 4% Junio C Hamano
[not found] ` <43DF1F1D.1060704@innova-card.com>
0 siblings, 1 reply; 200+ results
From: Junio C Hamano @ 2006-01-30 7:18 UTC (permalink / raw)
To: git
Shallow History Cloning
=======================
One good thing about git repository is that each clone is a
freestanding and complete entity, and you can keep developing in
it offline, without talking to the outside world, knowing that
you can sync with them later when online.
It is also a bad thing. It gives people working on projects
with long development history stored in CVS a heart attack when
we tell them that their clones need to store the whole history.
There was a suggestion by Linus to allow a partial clone using a
syntax like this:
$ git clone --since=v2.6.14 git://.../linux-2.6/ master
Here is an outline of what changes are needed to the current
core to do this.
Strategy
--------
We have `info/grafts` mechanism to fake parent information for
commit objects. Using this facility, we could roughly do:
. Download the full tree for v2.6.14 commit and store its
objects locally.
. Set up `info/grafts` to lie to the local git that Linux kernel
history began at v2.6.14 version.
. Run `git fetch git://.../linux-2.6 master`, with a local ref
pointing at v2.6.14 commit, to pretend that we have everything
up to v2.6.14 to `upload-pack` running on the other end.
. Update the `origin` branch with the master commit object name
we just fetched from Linus.
There are some issues.
. In the fetch above to obtain everything after v2.6.14, and
future runs of `git fetch origin`, if a blob that is in the
commit being fetched happens to match what used to be in a
commit that is older than v2.6.14 (e.g. a patch was reverted),
`upload-pack` running on the other end is free to omit sending
it, because we are telling it that we are up to date with
respect to v2.6.14. Although I think the current `rev-list
--objects` implementation does not always do such a revert
optimization if the revert is to a blob in a revision that is
sufficiently old, it is free to optimize more aggressively in
the future.
. Later when the user decides to fetch older history, the
operation can become a bit cumbersome.
I think the latter one is cumbersome but is doable -- we could
do the equivalent of:
$ git clone --since=v2.6.13 origin v2.6.14
place all the objects obtained by such a clone/fetch operation
and remember that now we have history beginning at v2.6.13. So
let's worry about that later.
For the first issue, we need to have the other end cooperate
while fetching from it. If the other end also thinks the
development started at v2.6.14, even if we tell that we have the
history up to v2.6.14 (or a commit we obtained since then),
there is no way for `upload-pack` running there to optimize too
agressively and assume we have a blob that appeared in v2.6.13.
More simply, we do not have to tell them we have anything -- if
the other end thinks the epoch is at v2.6.14, only commits that
comes later will be sent to us.
Design
------
First, to bootstrap the process, we would need to add a way to
obtain all objects associated with a commit. We could do a new
program, or we could implement this as a protocol extension to
`upload-pack`. My current inclination is the latter.
When talking with `upload-pack` that supports this extension,
the downloader can give one commit object name and get a pack
that contains all the objects in the tree associated with that
commit, plus the commit object itself. This is a rough
equivalent of running the commit walker with the `-t` flag.
Another functionality we would need is to tell `upload-pack` to
use `info/grafts` of downloader's choice. With this, after
fetching the objects for v2.6.14 commit, the downloader can set
up its own grafts file to cauterize the development history at
v2.6.14, and tell the `upload-pack` to pretend the kernel
history starts at that commit, while sending the tip of Linus'
development track to us.
Using the extended protocol (let's call it 'shallow' extension),
a clone to create a repository that has only recent kernel
history since v2.6.14 goes like this:
The first client is to fetch the v2.6.14 itself.
[NOTE]
Most likely this is not directly run by the user but is run as
the first command invoked by the shallow clone script.
1. The `fetch-pack` command acquires a new option, `--single`:
$ git-fetch-pack --single git://.../linux-2.6/ v2.6.14
This talks with `upload-pack` on the kernel.org server via
`git-daemon`.
2. `upload-pack` tells the fetcher what commits it has,
what their refs are, and what protocol extensions it
supports, as usual.
3. If it does not see `shallow` extension supported, there is no
way to get a single tree, so things fail here. Otherwise, it
sends `single X{40}\0` request, instead of the usual `want`
line. The object name sent here is the desired commit.
4. `upload-pack` notices this is a single commit request, and
sends an ACK if it can satisfy the request (or a NAK if it
can't, e.g. it does not have the asked commit). Instead of
doing the usual `get_common_commits` followed by
`create_pack_file`, it does:
$ git rev-list -n1 --objects $commit | git pack-object
and sends the result out.
5. The fetcher checks the ACK and receives the objects.
After the above exchange, we have downloaded v2.6.14 commit and
its objects but not its history. `git-fetch-pack` would output
the tag object name for `v2.6.14` and we would stash it away in
`$GIT_DIR/FETCH_HEAD` as usual. Then we set up `info/grafts`
with this:
$ git rev-parse FETCH_HEAD^{commit} >"$GIT_DIR/info/grafts"
This cauterizes the history on our end.
The second phase of the shallow clone is to fetch the history
since v2.6.14 to the tip.
1. The `fetch-pack` command is run as usual. Most likely the
command line run by the shallow clone script would be:
$ git fetch-pack git://.../linux-2.6/ master
Notice there is nothing magical about it. It is just the
business as usual.
2. `upload-pack` does its usual greeting to the downloader.
3. We notice `shallow` extension again, and first send out
`graft X{40}\0` request. The syntax of graft request would
be `graft ` followed by one or more commit object names on a
line separated with SP. After sending out all the needed
graft requests (in this example there is only one, to
cauterize the history at v2.6.14), it does the usual `want
X{40}\0multi_ack` and a flush.
4. `upload-pack` notices graft requests, reinitializes its graft
information with what it receives from the other end, and
then records `want`.
5. After the above steps, the usual `upload-pack` vs
`fetch-pack` exchange continues and objects needed to
complete the Linus' tip of development trail for somebody who
has v2.6.14 are sent in a pack. The difference from the
usual operation is that `upload-pack` during this run thinks
v2.6.14 commit does not have any parent.
The exact sequence from the second part of the initial "shallow
clone" can be used for further updates.
There is a small issue about the actual implementation. In the
above description I pretended that `upload-pack` can be told to
use phony grafts information, but in the current implementation
the program that needs to use phony grafts information is
`rev-list` spawned from it. We _could_ point GIT_GRAFT_FILE
environment variable point at a temporary file while we do so,
but I'd like to avoid using a temporary file if possible, given
that `upload-pack` is run from `git-daemon`. Maybe we could
give --read-graft-from-stdin flag to `rev-list` for this
purpose.
Anybody want to try?
^ permalink raw reply [relevance 4%]
* Re: [RFC] shallow clone
[not found] ` <43DF1F1D.1060704@innova-card.com>
@ 2006-01-31 9:00 1% ` Franck
0 siblings, 0 replies; 200+ results
From: Franck @ 2006-01-31 9:00 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Git Mailing List
2006/1/31, Franck Bui-Huu <fbh.work@gmail.com>:
> Junio C Hamano wrote:
> > Shallow History Cloning
> > =======================
> >
> > One good thing about git repository is that each clone is a
> > freestanding and complete entity, and you can keep developing in
> > it offline, without talking to the outside world, knowing that
> > you can sync with them later when online.
> >
could we be able to make a public repository from such repo ?
> > It is also a bad thing. It gives people working on projects
> > with long development history stored in CVS a heart attack when
> > we tell them that their clones need to store the whole history.
> >
yeah and I haven't survive :)
I didn't notice that other people were asking for this feature, that's great !
> > There was a suggestion by Linus to allow a partial clone using a
> > syntax like this:
[snip]
> >
> > There are some issues.
> >
> > . In the fetch above to obtain everything after v2.6.14, and
> > future runs of `git fetch origin`, if a blob that is in the
> > commit being fetched happens to match what used to be in a
> > commit that is older than v2.6.14 (e.g. a patch was reverted),
> > `upload-pack` running on the other end is free to omit sending
> > it, because we are telling it that we are up to date with
> > respect to v2.6.14. Although I think the current `rev-list
> > --objects` implementation does not always do such a revert
> > optimization if the revert is to a blob in a revision that is
> > sufficiently old, it is free to optimize more aggressively in
> > the future.
> >
oops, I wasn't aware of that. I still can resolve this issue by hand, no ?
> > . Later when the user decides to fetch older history, the
> > operation can become a bit cumbersome.
> >
[snip]
> >
> > Design
> > ------
> >
> > First, to bootstrap the process, we would need to add a way to
> > obtain all objects associated with a commit. We could do a new
> > program, or we could implement this as a protocol extension to
> > `upload-pack`. My current inclination is the latter.
is the document in "Documentation/technical/pack-protocol.txt"
uptodate ? I can't find anything on multi_ack for example.
> >
> > When talking with `upload-pack` that supports this extension,
> > the downloader can give one commit object name and get a pack
> > that contains all the objects in the tree associated with that
> > commit, plus the commit object itself. This is a rough
> > equivalent of running the commit walker with the `-t` flag.
[snip]
> >
> >
> > Anybody want to try?
> >
well, you made almost the job with your analysis, but I've never took
a look to git deep internals and with my lack of time, it would take
too much time...
Thanks
--
Franck
^ permalink raw reply [relevance 1%]
* Re: Make "git clone" less of a deathly quiet experience
@ 2006-02-11 7:35 4% ` Craig Schlenter
2006-02-11 8:44 1% ` Radoslaw Szkodzinski
0 siblings, 1 reply; 200+ results
From: Craig Schlenter @ 2006-02-11 7:35 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Git Mailing List
On 11 Feb 2006, at 7:48 AM, Junio C Hamano wrote:
[snip]
> The real improvement, independent of this client-side patch,
> would be to reuse recently generated packs, but that needs
> writable cache directory on the server side.
Speaking of improvements, I've noticed that my attempts to track
the 2.6 kernel via the git protocol result in inefficiencies from time
to time when the connection hangs or is terminated when my
flakey wireless link goes down. When I restart the pull, the data
that has already been downloaded is lost and things start from
scratch which is painful if it's a big update.
It would be nice if the "partial pack" or whatever that has been
downloaded at the time of the breakage could be re-used and
things could start "from that point onwards" or the bits that were
already received could be unpacked. Comments?
Thank you,
--Craig
^ permalink raw reply [relevance 4%]
* Re: Make "git clone" less of a deathly quiet experience
2006-02-11 7:35 4% ` Craig Schlenter
@ 2006-02-11 8:44 1% ` Radoslaw Szkodzinski
2006-02-11 13:05 2% ` Petr Baudis
0 siblings, 1 reply; 200+ results
From: Radoslaw Szkodzinski @ 2006-02-11 8:44 UTC (permalink / raw)
To: Craig Schlenter; +Cc: Junio C Hamano, Git Mailing List
[-- Attachment #1: Type: text/plain, Size: 573 bytes --]
Craig Schlenter wrote:
> On 11 Feb 2006, at 7:48 AM, Junio C Hamano wrote:
> It would be nice if the "partial pack" or whatever that has been
> downloaded at the time of the breakage could be re-used and
> things could start "from that point onwards" or the bits that were
> already received could be unpacked. Comments?
It even already works on plain http repos with git fetch.
(e.g. WineHQ repository)
Why git protocol doesn't support it?
+10
--
GPG Key id: 0xD1F10BA2
Fingerprint: 96E2 304A B9C4 949A 10A0 9105 9543 0453 D1F1 0BA2
AstralStorm
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 252 bytes --]
^ permalink raw reply [relevance 1%]
* Re: Make "git clone" less of a deathly quiet experience
2006-02-11 8:44 1% ` Radoslaw Szkodzinski
@ 2006-02-11 13:05 2% ` Petr Baudis
0 siblings, 0 replies; 200+ results
From: Petr Baudis @ 2006-02-11 13:05 UTC (permalink / raw)
To: Radoslaw Szkodzinski; +Cc: Craig Schlenter, Junio C Hamano, Git Mailing List
Dear diary, on Sat, Feb 11, 2006 at 09:44:00AM CET, I got a letter
where Radoslaw Szkodzinski <astralstorm@gorzow.mm.pl> said that...
> Craig Schlenter wrote:
> > On 11 Feb 2006, at 7:48 AM, Junio C Hamano wrote:
> > It would be nice if the "partial pack" or whatever that has been
> > downloaded at the time of the breakage could be re-used and
> > things could start "from that point onwards" or the bits that were
> > already received could be unpacked. Comments?
>
> It even already works on plain http repos with git fetch.
> (e.g. WineHQ repository)
> Why git protocol doesn't support it?
Because it works totally different. When downloading from plain HTTP
repos, you are just downloading files from the remote repository and it
is easy to pick up wherever you left (and last night, I just added a
possibility to Cogito to resume an interrupted cg-clone by just cd'ing
inside and running cg-fetch, as is; it's pretty neat) - you just resume
downloading of the file you downloaded last, and don't download again
the files you already have.
But the native git protocol works completely differently - you tell the
server "give me all objects you have between object X and head", the
object will generate a completely custom pack just for you and send it
over the network. The next time you fetch, you just ask for a pack
between object X and head again, but the head can be already totally
different. What we would have to do is to check for interrupted
packfiles before fetching, attempt to fix them (cutting out the
incomplete objects and broken delta chains, if applicable), and then
tell the remote side to skip those objects; but that may not be easy
because there can be a lot of "loose fibres". Another way would be to
just tell the server "if head is still Y, start sending the pack only
after N bytes". *shudder*
--
Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
Of the 3 great composers Mozart tells us what it's like to be human,
Beethoven tells us what it's like to be Beethoven and Bach tells us
what it's like to be the universe. -- Douglas Adams
^ permalink raw reply [relevance 2%]
* Re: several quick questions
@ 2006-02-15 8:21 3% ` Carl Worth
0 siblings, 0 replies; 200+ results
From: Carl Worth @ 2006-02-15 8:21 UTC (permalink / raw)
To: Keith Packard
Cc: Martin Langhoff, Linus Torvalds, Nicolas Vilz 'niv', git
[-- Attachment #1.1: Type: text/plain, Size: 2040 bytes --]
On Tue, 14 Feb 2006 21:25:45 -0800, Keith Packard wrote:
> On Wed, 2006-02-15 at 17:11 +1300, Martin Langhoff wrote:
>
> > Did that lead to finding any problems with the import? Can I get my
> > hands on that script you've written to run the comparison?
>
> The only issues we had were with manual changes to the repository;
For anyone interested, here are the problems our script found after
importing cairo with git-cvsimport:
1) Some "future" files existed at old tags since we had copied ,v
files to preserve per-file history. This one was no surprise.
2) We had a couple tags in CVS that didn't tag the current head,
(instead a file had been manually reverted before the tag). In the
git checkout of the same tag name, we got the results as if HEAD
had been tagged.
Those two weren't too surprising. We remembered quite clearly what had
happened as soon as we saw the results. I've fixed these up
post-import by making git commits to fix the problems and then moving
the tags.
3) There are some sub-tree tags in cairo's CVS tree as
well. Obviously, those aren't very interesting for direct
comparison.
Also not surprising. For these, I just modified the script to
whitelist the tags I actually cared about checking.
4) There was a branch that diverged from the main line two commits
"late" in the git history.
I'm not sure what caused this, but it's obviously happening in the
cvsps output. I fixed the problem by capturing the cvsps output into a
file, reordering the branching patchset up two positions in the list,
then feeding the result into git-cvsimport with its -P option.
I've attached the script I used to do the git and cvs comparisons. I
was getting perfect results with a local rsync of cairo's CVS
repository. The version here does a pserver checkout instead. When I
run this I'm apparently getting different substitution of some of
those annoying RCS $Id:...$ strings. Looks like the formatting of the
date is different. So your mileage may vary.
But here it is if its of any interest.
[-- Attachment #1.2: git-cvs-compare --]
[-- Type: application/octet-stream, Size: 1976 bytes --]
#!/bin/sh
set -e
CVSROOT=:pserver:anoncvs@cairographics.org:/cvs/cairo
GITMASTER=git://git.cairographics.org/cairo
if [ ! -e cairo-cvs ]; then
echo -n "Performing CVS checkout to cairo-cvs..."
cvs -d $CVSROOT co -d cairo-cvs cairo > /dev/null
echo "done."
fi
if [ ! -e cairo-git ]; then
echo -n "Cloning git repository to cairo-git..."
git clone $GITMASTER cairo-git
echo "done."
fi
# This is what you probably want to check all tags
#for tag in $(ls cairo-git/.git/refs/tags); do
# Instead, for cairo we whitelist the tags to check since there are
# some bogus partial-tree tags that just aren't interesting.
for tag in SNAPSHOT_0_1_16 SNAPSHOT_0_1_20 SNAPSHOT_0_1_21 SNAPSHOT_0_1_22 SNAPSHOT_0_1_23 LGPL_CHANGE_BEFORE LGPL_CHANGE_AFTER SNAPSHOT_0_2_0 SNAPSHOT_0_3_0 SNAPSHOT_0_4_0 SNAPSHOT_0_5_0 SNAPSHOT_0_5_1 SNAPSHOT_0_5_2 SNAPSHOT_0_6_0 RELEASE_0_9_0 RELEASE_0_9_2 RELEASE_1_0_0 RELEASE_1_0_2; do
echo -n "Performing cvs update to $tag..."
(cd cairo-cvs; cvs -Q update -r $tag > /dev/null)
echo "done."
echo -n "Performing git checkout of $tag..."
# Linus says this is the most efficient way to do this, but it
# seems to leave some empty directories around that shouldn't be
# there.
# (cd cairo-git; git checkout -b cvs-compare >& /dev/null || true; git checkout cvs-compare; git reset --hard $tag)
# This might be slower, but it's plenty fast still and it does the right thing
(cd cairo-git; git checkout master; git branch -D cvs-compare >& /dev/null || true; git checkout -b cvs-compare $tag)
echo "done."
echo -n "Comparing cvs and git trees for $tag..."
if diff -r -x CVS -x .git cairo-cvs cairo-git >& cairo.diff; then
echo "perfect."
rm cairo.diff
else
echo "different. :("
echo " Saving trees to cairo-git-$tag & cairo-cvs-$tag and diff to cairo-$tag.diff"
cp -a cairo-git cairo-git-$tag
cp -a cairo-cvs cairo-cvs-$tag
mv cairo.diff cairo-$tag.diff
fi
done
[-- Attachment #1.3: Type: text/plain, Size: 1 bytes --]
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply [relevance 3%]
* What's in git.git
@ 2006-02-16 6:57 3% Junio C Hamano
0 siblings, 0 replies; 200+ results
From: Junio C Hamano @ 2006-02-16 6:57 UTC (permalink / raw)
To: git
* Master branch has these since 1.2.1 maintenance release.
- documentation fixes:
git-commit: Now --only semantics is the default.
- usability:
- rebase aquired a hook to refuse rebasing.
- commit and add detects misspelled pathspec while making a partial commit.
- git-svnimport: -r adds svn revision number to commit messages
- properly git-bisect reset after bisecting from non-master head
- send-email: Add some options for controlling how addresses
are automatically added to the cc: list.
- send-email: Add --cc
* Next branch has these, that are not in master. If you feel
you would benefit from these, testing and feedback is greatly
appreciated.
- "Assume unchanged git" series (7 commits):
This was done in response to people on filesystems with slow
lstat(2). I do not have such an environment, so I cannot say
I tested it that much.
- "Rebase to different branch" (1 commit):
This was previously discussed on the list. With this command
line:
$ git rebase --onto master~1 master topic
would rebase this ancestry graph to:
A---B---C topic
/
D---E---F---G master
another graph that looks like this:
A'--B'--C' topic
/
D---E---F---G master
Earlier, you couldn't rebase to anywhere other than on top of
"the other branch".
* Proposed updates "pu" branch has these, not in "next". Some
of them are of iffy nature, and without further work will not
go anywhere.
- "merge-tree" series by Linus (2 commits).
I haven't spent enough time looking at and thinking about
this yet.
- "reuse pack data" (1 commit).
I still haven't seen data corruption with this one, which is
a good sign, but would like to keep beating it privately for
a while. Perhaps will graduate to "next" by next week.
- "bind commit" series (6 commits).
I think the core-side is more or less done with this one.
Anybody interested in doing Porcelain side?
- "shallow clone" series (1 commit).
I should drop this one for now and perhaps when enough people
are interested reopen the issue.
^ permalink raw reply [relevance 3%]
* [ANNOUNCE] git-svn - bidirection operations between svn and git
@ 2006-02-16 7:38 1% Eric Wong
0 siblings, 1 reply; 200+ results
From: Eric Wong @ 2006-02-16 7:38 UTC (permalink / raw)
To: git list
[-- Attachment #1: Type: text/plain, Size: 2171 bytes --]
Hello, I've written a simple tool for interoperating between git and
svn. I wrote this so I could use git to work on projects where other
developers use Subversion. I really hate using svn, but some projects I
work on require it, and svk isn't nearly as fast nor simple as git.
git-svn does not replace git-svnimport, git-svnimport handles branches
and tags automatically, but is too inflexible about repository layouts
to be useful for a good number of projects I follow, and of course
git-svnimport can't commit to Subversion repositories :)
git-svn only cares about a single branch/trunk in SVN[1], but you can
use as many branches in git as you want. This makes it much easier to
use and allows it to handle just about any repository layout, not just
those recommended in the SVN book/developers.
Although importing changesets from SVN is mostly a linear affair,
committing to SVN is the opposite. You may commit git tree objects in
any order you want. It simply clobbers the existing svn tree as
'git-checkout -f' would, but tags file renames/copies carefully so users
on the SVN side can see them. You can even do some wacky things with
patch reordering.
Basic day-to-day usage is pretty simple, and is designed to work with
and also work like normal git commands:
# Initialize a tree (like git init-db)::
git-svn init http://svn.foo.org/project/trunk
# Fetch remote revisions::
git-svn fetch
# Create your own branch to hack on::
git checkout -b my-branch git-svn-HEAD
# Commit only the git commits you want to SVN::
git-svn commit <tree-ish> [<tree-ish_2> ...]
# Commit all the git commits from my-branch that don't exist in SVN::
git rev-list --pretty=oneline git-svn-HEAD..my-branch | git-svn commit
# Something is committed to SVN, pull the latest into your branch::
git-svn fetch && git pull . git-svn-HEAD
@ Junio: Is there room for this in the git distribution alongside
git-svnimport?
Thanks for reading,
[1] - there are some a hacks that lets you handle branches and tags, but
it's not automated in any way, requires a bit of imagination to use to
its full potential, and is very much a hack. See the man page :)
--
Eric Wong
[-- Attachment #2: git-svn --]
[-- Type: text/plain, Size: 21108 bytes --]
#!/usr/bin/env perl
use warnings;
use strict;
use vars qw/ $AUTHOR $VERSION
$SVN_URL $SVN_INFO $SVN_WC
$GIT_SVN_INDEX $GIT_SVN
$GIT_DIR $REV_DIR/;
$AUTHOR = 'Eric Wong <normalperson@yhbt.net>';
$VERSION = '0.9.0';
$GIT_DIR = $ENV{GIT_DIR} || "$ENV{PWD}/.git";
$GIT_SVN = $ENV{GIT_SVN_ID} || 'git-svn';
$GIT_SVN_INDEX = "$GIT_DIR/$GIT_SVN/index";
$ENV{GIT_DIR} ||= $GIT_DIR;
$SVN_URL = undef;
$REV_DIR = "$GIT_DIR/$GIT_SVN/revs";
$SVN_WC = "$GIT_DIR/$GIT_SVN/tree";
# make sure the svn binary gives consistent output between locales and TZs:
$ENV{TZ} = 'UTC';
$ENV{LC_ALL} = 'C';
# If SVN:: library support is added, please make the dependencies
# optional and preserve the capability to use the command-line client.
# See what I do with XML::Simple to make the dependency optional.
use Carp qw/croak/;
use IO::File qw//;
use File::Basename qw/dirname basename/;
use File::Path qw/mkpath/;
use Getopt::Long qw/:config gnu_getopt no_ignore_case auto_abbrev/;
use File::Spec qw//;
my $sha1 = qr/[a-f\d]{40}/;
my $sha1_short = qr/[a-f\d]{6,40}/;
my ($_revision,$_stdin,$_no_ignore_ext,$_no_stop_copy,$_help,$_rmdir,$_edit);
GetOptions( 'revision|r=s' => \$_revision,
'no-ignore-externals' => \$_no_ignore_ext,
'stdin|' => \$_stdin,
'edit|e' => \$_edit,
'rmdir' => \$_rmdir,
'help|H|h' => \$_help,
'no-stop-copy' => \$_no_stop_copy );
my %cmd = (
fetch => [ \&fetch, "Download new revisions from SVN" ],
init => [ \&init, "Initialize and fetch (import)"],
commit => [ \&commit, "Commit git revisions to SVN" ],
rebuild => [ \&rebuild, "Rebuild git-svn metadata (after git clone)" ],
help => [ \&usage, "Show help" ],
);
my $cmd;
for (my $i = 0; $i < @ARGV; $i++) {
if (defined $cmd{$ARGV[$i]}) {
$cmd = $ARGV[$i];
splice @ARGV, $i, 1;
last;
}
};
# we may be called as git-svn-(command), or git-svn(command).
foreach (keys %cmd) {
if (/git\-svn\-?($_)(?:\.\w+)?$/) {
$cmd = $1;
last;
}
}
usage(0) if $_help;
usage(1) unless (defined $cmd);
svn_check_ignore_externals();
$cmd{$cmd}->[0]->(@ARGV);
exit 0;
####################### primary functions ######################
sub usage {
my $exit = shift || 0;
my $fd = $exit ? \*STDERR : \*STDOUT;
print $fd <<"";
git-svn - bidirectional operations between a single Subversion tree and git
Usage: $0 <command> [options] [arguments]\n
Available commands:
foreach (sort keys %cmd) {
print $fd ' ',pack('A10',$_),$cmd{$_}->[1],"\n";
}
print $fd <<"";
\nGIT_SVN_ID may be set in the environment to an arbitrary identifier if
you're tracking multiple SVN branches/repositories in one git repository
and want to keep them separate.
exit $exit;
}
sub rebuild {
$SVN_URL = shift or undef;
my $repo_uuid;
my $newest_rev = 0;
my $pid = open(my $rev_list,'-|');
defined $pid or croak $!;
if ($pid == 0) {
exec("git-rev-list","$GIT_SVN-HEAD") or croak $!;
}
my $first;
while (<$rev_list>) {
chomp;
my $c = $_;
croak "Non-SHA1: $c\n" unless $c =~ /^$sha1$/o;
my @commit = grep(/^git-svn-id: /,`git-cat-file commit $c`);
next if (!@commit); # skip merges
my $id = $commit[$#commit];
my ($url, $rev, $uuid) = ($id =~ /^git-svn-id:\s(\S+?)\@(\d+)
\s([a-f\d\-]+)$/x);
if (!$rev || !$uuid || !$url) {
# some of the original repositories I made had
# indentifiers like this:
($rev, $uuid) = ($id =~/^git-svn-id:\s(\d+)
\@([a-f\d\-]+)/x);
if (!$rev || !$uuid) {
croak "Unable to extract revision or UUID from ",
"$c, $id\n";
}
}
print "r$rev = $c\n";
unless (defined $first) {
if (!$SVN_URL && !$url) {
croak "SVN repository location required: $url\n";
}
$SVN_URL ||= $url;
$repo_uuid = setup_git_svn();
$first = $rev;
}
if ($uuid ne $repo_uuid) {
croak "Repository UUIDs do not match!\ngot: $uuid\n",
"expected: $repo_uuid\n";
}
assert_revision_eq_or_unknown($rev, $c);
sys('git-update-ref',"$GIT_SVN/revs/$rev",$c);
$newest_rev = $rev if ($rev > $newest_rev);
}
close $rev_list or croak $?;
if (!chdir $SVN_WC) {
my @svn_co = ('svn','co',"-r$first");
push @svn_co, '--ignore-externals' unless $_no_ignore_ext;
sys(@svn_co, $SVN_URL, $SVN_WC);
chdir $SVN_WC or croak $!;
}
$pid = fork;
defined $pid or croak $!;
if ($pid == 0) {
my @svn_up = qw(svn up);
push @svn_up, '--ignore-externals' unless $_no_ignore_ext;
sys(@svn_up,"-r$newest_rev");
$ENV{GIT_INDEX_FILE} = $GIT_SVN_INDEX;
git_addremove();
exec('git-write-tree');
}
waitpid $pid, 0;
}
sub init {
$SVN_URL = shift or croak "SVN repository location required\n";
unless (-d $GIT_DIR) {
sys('git-init-db');
}
setup_git_svn();
}
sub fetch {
my (@parents) = @_;
$SVN_URL ||= file_to_s("$GIT_DIR/$GIT_SVN/info/url");
my @log_args = -d $SVN_WC ? ($SVN_WC) : ($SVN_URL);
if (-d $SVN_WC && !$_revision) {
$_revision = 'BASE:HEAD';
}
push @log_args, "-r$_revision" if $_revision;
push @log_args, '--stop-on-copy' unless $_no_stop_copy;
eval { require XML::Simple or croak $! };
my $svn_log = $@ ? svn_log_raw(@log_args) : svn_log_xml(@log_args);
my $base = shift @$svn_log or croak "No base revision!\n";
my $last_commit = undef;
unless (-d $SVN_WC) {
my @svn_co = ('svn','co',"-r$base->{revision}");
push @svn_co,'--ignore-externals' unless $_no_ignore_ext;
sys(@svn_co, $SVN_URL, $SVN_WC);
chdir $SVN_WC or croak $!;
$last_commit = git_commit($base, @parents);
unless (-f "$GIT_DIR/refs/heads/master") {
sys(qw(git-update-ref refs/heads/master),$last_commit);
}
assert_svn_wc_clean($base->{revision}, $last_commit);
} else {
chdir $SVN_WC or croak $!;
$last_commit = file_to_s("$REV_DIR/$base->{revision}");
}
my @svn_up = qw(svn up);
push @svn_up, '--ignore-externals' unless $_no_ignore_ext;
my $last_rev = $base->{revision};
foreach my $log_msg (@$svn_log) {
assert_svn_wc_clean($last_rev, $last_commit);
$last_rev = $log_msg->{revision};
sys(@svn_up,"-r$last_rev");
$last_commit = git_commit($log_msg, $last_commit, @parents);
}
assert_svn_wc_clean($last_rev, $last_commit);
return pop @$svn_log;
}
sub commit {
my (@commits) = @_;
if ($_stdin || !@commits) {
print "Reading from stdin...\n";
@commits = ();
while (<STDIN>) {
if (/^([a-f\d]{6,40})\b/) {
unshift @commits, $1;
}
}
}
my @revs;
foreach (@commits) {
push @revs, (safe_qx('git-rev-parse',$_));
}
chomp @revs;
fetch();
chdir $SVN_WC or croak $!;
my $svn_current_rev = svn_info('.')->{'Last Changed Rev'};
foreach my $c (@revs) {
print "Committing $c\n";
svn_checkout_tree($svn_current_rev, $c);
$svn_current_rev = svn_commit_tree($svn_current_rev, $c);
}
print "Done committing ",scalar @revs," revisions to SVN\n";
}
########################### utility functions #########################
sub setup_git_svn {
defined $SVN_URL or croak "SVN repository location required\n";
unless (-d $GIT_DIR) {
croak "GIT_DIR=$GIT_DIR does not exist!\n";
}
mkpath(["$GIT_DIR/$GIT_SVN"]);
mkpath(["$GIT_DIR/$GIT_SVN/info"]);
mkpath([$REV_DIR]);
s_to_file($SVN_URL,"$GIT_DIR/$GIT_SVN/info/url");
my $uuid = svn_info($SVN_URL)->{'Repository UUID'} or
croak "Repository UUID unreadable\n";
s_to_file($uuid,"$GIT_DIR/$GIT_SVN/info/uuid");
open my $fd, '>>', "$GIT_DIR/$GIT_SVN/info/exclude" or croak $!;
print $fd '.svn',"\n";
close $fd or croak $!;
return $uuid;
}
sub assert_svn_wc_clean {
my ($svn_rev, $commit) = @_;
croak "$svn_rev is not an integer!\n" unless ($svn_rev =~ /^\d+$/);
croak "$commit is not a sha1!\n" unless ($commit =~ /^$sha1$/o);
my $svn_info = svn_info('.');
if ($svn_rev != $svn_info->{'Last Changed Rev'}) {
croak "Expected r$svn_rev, got r",
$svn_info->{'Last Changed Rev'},"\n";
}
my @status = grep(!/^Performing status on external/,(`svn status`));
@status = grep(!/^\s*$/,@status);
if (scalar @status) {
print STDERR "Tree ($SVN_WC) is not clean:\n";
print STDERR $_ foreach @status;
croak;
}
my ($tree_a) = grep(/^tree $sha1$/o,`git-cat-file commit $commit`);
$tree_a =~ s/^tree //;
chomp $tree_a;
chomp(my $tree_b = `GIT_INDEX_FILE=$GIT_SVN_INDEX git-write-tree`);
if ($tree_a ne $tree_b) {
croak "$svn_rev != $commit, $tree_a != $tree_b\n";
}
}
sub parse_diff_tree {
my $diff_fh = shift;
local $/ = "\0";
my $state = 'meta';
my @mods;
while (<$diff_fh>) {
chomp $_; # this gets rid of the trailing "\0"
print $_,"\n";
if ($state eq 'meta' && /^:(\d{6})\s(\d{6})\s
$sha1\s($sha1)\s([MTCRAD])\d*$/xo) {
push @mods, { mode_a => $1, mode_b => $2,
sha1_b => $3, chg => $4 };
if ($4 =~ /^(?:C|R)$/) {
$state = 'file_a';
} else {
$state = 'file_b';
}
} elsif ($state eq 'file_a') {
my $x = $mods[$#mods] or croak __LINE__,": Empty array\n";
if ($x->{chg} !~ /^(?:C|R)$/) {
croak __LINE__,": Error parsing $_, $x->{chg}\n";
}
$x->{file_a} = $_;
$state = 'file_b';
} elsif ($state eq 'file_b') {
my $x = $mods[$#mods] or croak __LINE__,": Empty array\n";
if (exists $x->{file_a} && $x->{chg} !~ /^(?:C|R)$/) {
croak __LINE__,": Error parsing $_, $x->{chg}\n";
}
if (!exists $x->{file_a} && $x->{chg} =~ /^(?:C|R)$/) {
croak __LINE__,": Error parsing $_, $x->{chg}\n";
}
$x->{file_b} = $_;
$state = 'meta';
} else {
croak __LINE__,": Error parsing $_\n";
}
}
close $diff_fh or croak $!;
return \@mods;
}
sub svn_check_prop_executable {
my $m = shift;
if ($m->{mode_b} =~ /755$/ && $m->{mode_a} !~ /755$/) {
sys(qw(svn propset svn:executable 1), $m->{file_b});
} elsif ($m->{mode_b} !~ /755$/ && $m->{mode_a} =~ /755$/) {
sys(qw(svn propdel svn:executable), $m->{file_b});
}
}
sub svn_ensure_parent_path {
my $dir_b = dirname(shift);
svn_ensure_parent_path($dir_b) if ($dir_b ne File::Spec->curdir);
mkpath([$dir_b]) unless (-d $dir_b);
sys(qw(svn add -N), $dir_b) unless (-d "$dir_b/.svn");
}
sub svn_checkout_tree {
my ($svn_rev, $commit) = @_;
my $from = file_to_s("$REV_DIR/$svn_rev");
assert_svn_wc_clean($svn_rev,$from);
print "diff-tree '$from' '$commit'\n";
my $pid = open my $diff_fh, '-|';
defined $pid or croak $!;
if ($pid == 0) {
exec(qw(git-diff-tree -z -r -C), $from, $commit) or croak $!;
}
my $mods = parse_diff_tree($diff_fh);
unless (@$mods) {
# git can do empty commits, SVN doesn't allow it...
return $svn_rev;
}
my %rm;
foreach my $m (@$mods) {
if ($m->{chg} eq 'C') {
svn_ensure_parent_path( $m->{file_b} );
sys(qw(svn cp), $m->{file_a}, $m->{file_b});
blob_to_file( $m->{sha1_b}, $m->{file_b});
svn_check_prop_executable($m);
} elsif ($m->{chg} eq 'D') {
$rm{dirname $m->{file_b}}->{basename $m->{file_b}} = 1;
sys(qw(svn rm --force), $m->{file_b});
} elsif ($m->{chg} eq 'R') {
svn_ensure_parent_path( $m->{file_b} );
sys(qw(svn mv --force), $m->{file_a}, $m->{file_b});
blob_to_file( $m->{sha1_b}, $m->{file_b});
svn_check_prop_executable($m);
$rm{dirname $m->{file_a}}->{basename $m->{file_a}} = 1;
} elsif ($m->{chg} eq 'M') {
if ($m->{mode_b} =~ /^120/ && $m->{mode_a} =~ /^120/) {
unlink $m->{file_b} or croak $!;
blob_to_symlink($m->{sha1_b}, $m->{file_b});
} else {
blob_to_file($m->{sha1_b}, $m->{file_b});
}
svn_check_prop_executable($m);
} elsif ($m->{chg} eq 'T') {
sys(qw(svn rm --force),$m->{file_b});
if ($m->{mode_b} =~ /^120/ && $m->{mode_a} =~ /^100/) {
blob_to_symlink($m->{sha1_b}, $m->{file_b});
} else {
blob_to_file($m->{sha1_b}, $m->{file_b});
}
svn_check_prop_executable($m);
sys(qw(svn add --force), $m->{file_b});
} elsif ($m->{chg} eq 'A') {
svn_ensure_parent_path( $m->{file_b} );
blob_to_file( $m->{sha1_b}, $m->{file_b});
if ($m->{mode_b} =~ /755$/) {
chmod 0755, $m->{file_b};
}
sys(qw(svn add --force), $m->{file_b});
} else {
croak "Invalid chg: $m->{chg}\n";
}
}
if ($_rmdir) {
my $old_index = $ENV{GIT_INDEX_FILE};
$ENV{GIT_INDEX_FILE} = $GIT_SVN_INDEX;
foreach my $dir (keys %rm) {
my $files = $rm{$dir};
my @files;
foreach (safe_qx('svn','ls',$dir)) {
chomp;
push @files, $_ unless $files->{$_};
}
sys(qw(svn rm),$dir) unless @files;
}
if ($old_index) {
$ENV{GIT_INDEX_FILE} = $old_index;
} else {
delete $ENV{GIT_INDEX_FILE};
}
}
}
sub svn_commit_tree {
my ($svn_rev, $commit) = @_;
my $commit_msg = "$GIT_DIR/$GIT_SVN/.svn-commit.tmp.$$";
open my $msg, '>', $commit_msg or croak $!;
chomp(my $type = `git-cat-file -t $commit`);
if ($type eq 'commit') {
my $pid = open my $msg_fh, '-|';
defined $pid or croak $!;
if ($pid == 0) {
exec(qw(git-cat-file commit), $commit) or croak $!;
}
my $in_msg = 0;
while (<$msg_fh>) {
if (!$in_msg) {
$in_msg = 1 if (/^\s*$/);
} else {
print $msg $_ or croak $!;
}
}
close $msg_fh or croak $!;
}
close $msg or croak $!;
if ($_edit || ($type eq 'tree')) {
my $editor = $ENV{VISUAL} || $ENV{EDITOR} || 'vi';
system($editor, $commit_msg);
}
my @ci_output = safe_qx(qw(svn commit -F),$commit_msg);
my ($committed) = grep(/^Committed revision \d+\./,@ci_output);
unlink $commit_msg;
defined $committed or croak
"Commit output failed to parse committed revision!\n",
join("\n",@ci_output),"\n";
my ($rev_committed) = ($committed =~ /^Committed revision (\d+)\./);
# resync immediately
my @svn_up = (qw(svn up), "-r$svn_rev");
push @svn_up, '--ignore-externals' unless $_no_ignore_ext;
sys(@svn_up);
return fetch("$rev_committed=$commit")->{revision};
}
sub svn_log_xml {
my (@log_args) = @_;
my $log_fh = IO::File->new_tmpfile or croak $!;
my $pid = fork;
defined $pid or croak $!;
if ($pid == 0) {
open STDOUT, '>&', $log_fh or croak $!;
exec (qw(svn log --xml), @log_args) or croak $!
}
waitpid $pid, 0;
croak $? if $?;
seek $log_fh, 0, 0;
my @svn_log;
my $log = XML::Simple::XMLin( $log_fh,
ForceArray => ['path','revision','logentry'],
KeepRoot => 0,
KeyAttr => { logentry => '+revision',
paths => '+path' },
)->{logentry};
foreach my $r (sort {$a <=> $b} keys %$log) {
my $log_msg = $log->{$r};
my ($Y,$m,$d,$H,$M,$S) = ($log_msg->{date} =~
/(\d{4})\-(\d\d)\-(\d\d)T
(\d\d)\:(\d\d)\:(\d\d)\.\d+Z$/x)
or croak "Failed to parse date: ",
$log->{$r}->{date};
$log_msg->{date} = "+0000 $Y-$m-$d $H:$M:$S";
# XML::Simple can't handle <msg></msg> as a string:
if (ref $log_msg->{msg} eq 'HASH') {
$log_msg->{msg} = "\n";
} else {
$log_msg->{msg} .= "\n";
}
push @svn_log, $log->{$r};
}
return \@svn_log;
}
sub svn_log_raw {
my (@log_args) = @_;
my $pid = open my $log_fh,'-|';
defined $pid or croak $!;
if ($pid == 0) {
exec (qw(svn log), @log_args) or croak $!
}
my @svn_log;
my $state;
while (<$log_fh>) {
chomp;
if (/^\-{72}$/) {
$state = 'rev';
# if we have an empty log message, put something there:
if (@svn_log) {
$svn_log[0]->{msg} ||= "\n";
}
next;
}
if ($state eq 'rev' && s/^r(\d+)\s*\|\s*//) {
my $rev = $1;
my ($author, $date) = split(/\s*\|\s*/, $_, 2);
my ($Y,$m,$d,$H,$M,$S,$tz) = ($date =~
/(\d{4})\-(\d\d)\-(\d\d)\s
(\d\d)\:(\d\d)\:(\d\d)\s([\-\+]\d+)/x)
or croak "Failed to parse date: $date\n";
my %log_msg = ( revision => $rev,
date => "$tz $Y-$m-$d $H:$M:$S",
author => $author,
msg => '' );
unshift @svn_log, \%log_msg;
$state = 'msg_start';
next;
}
# skip the first blank line of the message:
if ($state eq 'msg_start' && /^$/) {
$state = 'msg';
} elsif ($state eq 'msg') {
$svn_log[0]->{msg} .= $_."\n";
}
}
close $log_fh or croak $?;
return \@svn_log;
}
sub svn_info {
my $url = shift || $SVN_URL;
my $pid = open my $info_fh, '-|';
defined $pid or croak $!;
if ($pid == 0) {
exec(qw(svn info),$url) or croak $!;
}
my $ret = {};
# only single-lines seem to exist in svn info output
while (<$info_fh>) {
chomp $_;
if (m#^([^:]+)\s*:\s*(\S*)$#) {
$ret->{$1} = $2;
push @{$ret->{-order}}, $1;
}
}
close $info_fh or croak $!;
return $ret;
}
sub sys { system(@_) == 0 or croak $? }
sub git_addremove {
system( "git-ls-files -z --others ".
"'--exclude-from=$GIT_DIR/$GIT_SVN/info/exclude'".
"| git-update-index --add -z --stdin; ".
"git-ls-files -z --deleted ".
"| git-update-index --remove -z --stdin; ".
"git-ls-files -z --modified".
"| git-update-index -z --stdin") == 0 or croak $?
}
sub s_to_file {
my ($str, $file, $mode) = @_;
open my $fd,'>',$file or croak $!;
print $fd $str,"\n" or croak $!;
close $fd or croak $!;
chmod ($mode &~ umask, $file) if (defined $mode);
}
sub file_to_s {
my $file = shift;
open my $fd,'<',$file or croak "$!: file: $file\n";
local $/;
my $ret = <$fd>;
close $fd or croak $!;
$ret =~ s/\s*$//s;
return $ret;
}
sub assert_revision_unknown {
my $revno = shift;
if (-f "$REV_DIR/$revno") {
croak "$REV_DIR/$revno already exists! ",
"Why are we refetching it?";
}
}
sub assert_revision_eq_or_unknown {
my ($revno, $commit) = @_;
if (-f "$REV_DIR/$revno") {
my $current = file_to_s("$REV_DIR/$revno");
if ($commit ne $current) {
croak "$REV_DIR/$revno already exists!\n",
"current: $current\nexpected: $commit\n";
}
return;
}
}
sub git_commit {
my ($log_msg, @parents) = @_;
assert_revision_unknown($log_msg->{revision});
my $out_fh = IO::File->new_tmpfile or croak $!;
my $info = svn_info('.');
my $uuid = $info->{'Repository UUID'};
defined $uuid or croak "Unable to get Repository UUID\n";
# commit parents can be conditionally bound to a particular
# svn revision via: "svn_revno=commit_sha1", filter them out here:
my @exec_parents;
foreach my $p (@parents) {
next unless defined $p;
if ($p =~ /^(\d+)=($sha1_short)$/o) {
if ($1 == $log_msg->{revision}) {
push @exec_parents, $2;
}
} else {
push @exec_parents, $p if $p =~ /$sha1_short/o;
}
}
my $pid = fork;
defined $pid or croak $!;
if ($pid == 0) {
$ENV{GIT_INDEX_FILE} = $GIT_SVN_INDEX;
git_addremove();
chomp(my $tree = `git-write-tree`);
croak if $?;
my $msg_fh = IO::File->new_tmpfile or croak $!;
print $msg_fh $log_msg->{msg}, "\ngit-svn-id: ",
"$SVN_URL\@$log_msg->{revision}",
" $uuid\n" or croak $!;
$msg_fh->flush == 0 or croak $!;
seek $msg_fh, 0, 0 or croak $!;
$ENV{GIT_AUTHOR_NAME} = $ENV{GIT_COMMITTER_NAME} =
$log_msg->{author};
$ENV{GIT_AUTHOR_EMAIL} = $ENV{GIT_COMMITTER_EMAIL} =
$log_msg->{author}."\@$uuid";
$ENV{GIT_AUTHOR_DATE} = $ENV{GIT_COMMITTER_DATE} =
$log_msg->{date};
my @exec = ('git-commit-tree',$tree);
push @exec, '-p', $_ foreach @exec_parents;
open STDIN, '<&', $msg_fh or croak $!;
open STDOUT, '>&', $out_fh or croak $!;
exec @exec or croak $!;
}
waitpid($pid,0);
croak if $?;
$out_fh->flush == 0 or croak $!;
seek $out_fh, 0, 0 or croak $!;
chomp(my $commit = do { local $/; <$out_fh> });
if ($commit !~ /^$sha1$/o) {
croak "Failed to commit, invalid sha1: $commit\n";
}
my @update_ref = ('git-update-ref',"refs/heads/$GIT_SVN-HEAD",$commit);
if (my $primary_parent = shift @exec_parents) {
push @update_ref, $primary_parent;
}
sys(@update_ref);
sys('git-update-ref',"$GIT_SVN/revs/$log_msg->{revision}",$commit);
print "r$log_msg->{revision} = $commit\n";
return $commit;
}
sub blob_to_symlink {
my ($blob, $link) = @_;
defined $link or croak "\$link not defined!\n";
croak "Not a sha1: $blob\n" unless $blob =~ /^$sha1$/o;
my $dest = `git-cat-file blob $blob`; # no newline, so no chomp
symlink $dest, $link or croak $!;
}
sub blob_to_file {
my ($blob, $file) = @_;
defined $file or croak "\$file not defined!\n";
croak "Not a sha1: $blob\n" unless $blob =~ /^$sha1$/o;
open my $blob_fh, '>', $file or croak "$!: $file\n";
my $pid = fork;
defined $pid or croak $!;
if ($pid == 0) {
open STDOUT, '>&', $blob_fh or croak $!;
exec('git-cat-file','blob',$blob);
}
waitpid $pid, 0;
croak $? if $?;
close $blob_fh or croak $!;
}
sub safe_qx {
my $pid = open my $child, '-|';
defined $pid or croak $!;
if ($pid == 0) {
exec(@_) or croak $?;
}
my @ret = (<$child>);
close $child or croak $?;
die $? if $?; # just in case close didn't error out
return wantarray ? @ret : join('',@ret);
}
sub svn_check_ignore_externals {
return if $_no_ignore_ext;
unless (grep /ignore-externals/,(safe_qx(qw(svn co -h)))) {
print STDERR "W: Installed svn version does not support ",
"--ignore-externals\n";
$_no_ignore_ext = 1;
}
}
__END__
Data structures:
@svn_log = array of log_msg hashes
$log_msg hash
{
msg => 'whitespace-formatted log entry
', # trailing newline is preserved
revision => '8', # integer
date => '2004-02-24T17:01:44.108345Z', # commit date
author => 'committer name'
};
@mods = array of diff-index line hashes, each element represents one line
of diff-index output
diff-index line ($m hash)
{
mode_a => first column of diff-index output, no leading ':',
mode_b => second column of diff-index output,
sha1_b => sha1sum of the final blob,
chg => change type [MCRAD],
file_a => original file name of a file (iff chg is 'C' or 'R')
file_b => new/current file name of a file (any chg)
}
;
[-- Attachment #3: git-svn.txt --]
[-- Type: text/plain, Size: 7405 bytes --]
git-svn(1)
==========
NAME
----
git-svn - bidirectional operation between a single Subversion branch and git
SYNOPSIS
--------
'git-svn' <command> [options] [arguments]
DESCRIPTION
-----------
git-svn is a simple conduit for changesets between a single Subversion
branch and git.
git-svn is not to be confused with git-svnimport. The were designed
with very different goals in mind.
git-svn is designed for an individual developer who wants a
bidirectional flow of changesets between a single branch in Subversion
and an arbitrary number of branches in git. git-svnimport is designed
for read-only operation on repositories that match a particular layout
(albeit the recommended one by SVN developers).
For importing svn, git-svnimport is potentially more powerful when
operating on repositories organized under the recommended
trunk/branch/tags structure, and should be faster, too.
git-svn completely ignores the very limited view of branching that
Subversion has. This allows git-svn to be much easier to use,
especially on repositories that are not organized in a manner that
git-svnimport is designed for.
COMMANDS
--------
init::
Creates an empty git repository with additional metadata
directories for git-svn. The SVN_URL must be specified
at this point.
fetch::
Fetch unfetched revisions from the SVN_URL we are tracking.
refs/heads/git-svn-HEAD will be updated to the latest revision.
commit::
Commit specified commit or tree objects to SVN. This relies on
your imported fetch data being up-to-date. This makes
absolutely no attempts to do patching when committing to SVN, it
simply overwrites files with those specified in the tree or
commit. All merging is assumed to have taken place
independently of git-svn functions.
rebuild::
Not a part of daily usage, but this is a useful command if
you've just cloned a repository (using git-clone) that was
tracked with git-svn. Unfortunately, git-clone does not clone
git-svn metadata and the svn working tree that git-svn uses for
its operations. This rebuilds the metadata so git-svn can
resume fetch operations. SVN_URL may be optionally specified if
the directory/repository you're tracking has moved or changed
protocols.
OPTIONS
-------
-r <ARG>::
--revision <ARG>::
Only used with the 'fetch' command.
Takes any valid -r<argument> svn would accept and passes it
directly to svn. -r<ARG1>:<ARG2> ranges and "{" DATE "}" syntax
is also supported. This is passed directly to svn, see svn
documentation for more details.
This can allow you to make partial mirrors when running fetch.
-::
--stdin::
Only used with the 'commit' command.
Read a list of commits from stdin and commit them in reverse
order. Only the leading sha1 is read from each line, so
git-rev-list --pretty=oneline output can be used.
--rmdir::
Only used with the 'commit' command.
Remove directories from the SVN tree if there are no files left
behind. SVN can version empty directories, and they are not
removed by default if there are no files left in them. git
cannot version empty directories. Enabling this flag will make
the commit to SVN act like git.
-e::
--edit::
Only used with the 'commit' command.
Edit the commit message before committing to SVN. This is off by
default for objects that are commits, and forced on when committing
tree objects.
COMPATIBILITY OPTIONS
---------------------
--no-ignore-externals::
Only used with the 'fetch' and 'rebuild' command.
By default, git-svn passes --ignore-externals to svn to avoid
fetching svn:external trees into git. Pass this flag to enable
externals tracking directly via git.
Versions of svn that do not support --ignore-externals are
automatically detected and this flag will be automatically
enabled for them.
Otherwise, do not enable this flag unless you know what you're
doing.
--no-stop-on-copy::
Only used with the 'fetch' command.
By default, git-svn passes --stop-on-copy to avoid dealing with
the copied/renamed branch directory problem entirely. A
copied/renamed branch is the result of a <SVN_URL> being created
in the past from a different source. These are problematic to
deal with even when working purely with svn if you work inside
subdirectories.
Do not use this flag unless you know exactly what you're getting
yourself into. You have been warned.
Examples
~~~~~~~~
Tracking and contributing to an Subversion managed-project:
# Initialize a tree (like git init-db)::
git-svn init http://svn.foo.org/project/trunk
# Fetch remote revisions::
git-svn fetch
# Create your own branch to hack on::
git checkout -b my-branch git-svn-HEAD
# Commit only the git commits you want to SVN::
git-svn commit <tree-ish> [<tree-ish_2> ...]
# Commit all the git commits from my-branch that don't exist in SVN::
git rev-list --pretty=oneline git-svn-HEAD..my-branch | git-svn commit
# Something is committed to SVN, pull the latest into your branch::
git-svn fetch && git pull . git-svn-HEAD
DESIGN PHILOSOPHY
-----------------
Merge tracking in Subversion is lacking and doing branched development
with Subversion is cumbersome as a result. git-svn completely forgoes
any automated merge/branch tracking on the Subversion side and leaves it
entirely up to the user on the git side. It's simply not worth it to do
a useful translation when the the original signal is weak.
TRACKING MULTIPLE REPOSITORIES OR BRANCHES
------------------------------------------
This is for advanced users, most users should ignore this section.
Because git-svn does not care about relationships between different
branches or directories in a Subversion repository, git-svn has a simple
hack to allow it to track an arbitrary number of related _or_ unrelated
SVN repositories via one git repository. Simply set the GIT_SVN_ID
environment variable to a name other other than "git-svn" (the default)
and git-svn will ignore the contents of the $GIT_DIR/git-svn directory
and instead do all of its work in $GIT_DIR/$GIT_SVN_ID for that
invocation.
ADDITIONAL FETCH ARGUMENTS
--------------------------
This is for advanced users, most users should ignore this section.
Unfetched SVN revisions may be imported as children of existing commits
by specifying additional arguments to 'fetch'. Additional parents may
optionally be specified in the form of sha1 hex sums at the
command-line. Unfetched SVN revisions may also be tied to particular
git commits with the following syntax:
svn_revision_number=git_commit_sha1
This allows you to tie unfetched SVN revision 375 to your current HEAD::
git-svn fetch 375=$(git-rev-parse HEAD)
BUGS
----
If somebody commits a conflicting changeset to SVN at a bad moment
(right before you commit) causing a conflict and your commit to fail,
your svn working tree ($GIT_DIR/git-svn/tree) may be dirtied. The
easiest thing to do is probably just to rm -rf $GIT_DIR/git-svn/tree and
run 'rebuild'.
We ignore all SVN properties except svn:executable. Too difficult to
map them since we rely heavily on git write-tree being _exactly_ the
same on both the SVN and git working trees and I prefer not to clutter
working trees with metadata files.
svn:keywords can't be ignored in Subversion (at least I don't know of
a way to ignore them).
Author
------
Written by Eric Wong <normalperson@yhbt.net>.
Documentation
-------------
Written by Eric Wong <normalperson@yhbt.net>.
^ permalink raw reply [relevance 1%]
* Re: [ANNOUNCE] git-svn - bidirection operations between svn and git
@ 2006-02-16 19:25 2% ` Eric Wong
0 siblings, 0 replies; 200+ results
From: Eric Wong @ 2006-02-16 19:25 UTC (permalink / raw)
To: Eduardo Pereira Habkost; +Cc: git list
Eduardo Pereira Habkost <ehabkost@mandriva.com> wrote:
> On Wed, Feb 15, 2006 at 11:38:26PM -0800, Eric Wong wrote:
> > Hello, I've written a simple tool for interoperating between git and
> > svn. I wrote this so I could use git to work on projects where other
> > developers use Subversion. I really hate using svn, but some projects I
> > work on require it, and svk isn't nearly as fast nor simple as git.
>
> Great, I was doing some testing with git-svnimport for this, but I missed
> a tool to automatically commit to svn what I have in my GIT tree.
>
> >
> > git-svn does not replace git-svnimport, git-svnimport handles branches
> > and tags automatically, but is too inflexible about repository layouts
> > to be useful for a good number of projects I follow, and of course
> > git-svnimport can't commit to Subversion repositories :)
>
> I am already using git-svnimport to keep a "mirror" of some subversion
> repositories, here (automatically udpated on crontab). Do you plan to
> allow "integration" with repositories that are just clones of
> git-svnimport'ed repositories?
It's possible, just not very obvious at the moment. git-svn was written
as quickly as possible without regard to svnimport compatibility since I
had some repos that didn't work with svnimport to begin with.
The 'ADDITIONAL FETCH ARGUMENTS' part of the manpage is worth reading
for you. Basically, you can define equalities
"(svn revision number)=(git commit)" as arguments to git-svn fetch to
add parents for all the revisions it imports.
If I were you, I'd only want git-svn to care about partial history,
since you already have the rest of it from git-svnimport. You can do
this:
svn_revno=<last svn revision number you imported from git-svnimport>
git_commit=<equivalent commit sha1 name of svn_revno above>
git-svn fetch --revision $svn_revno:HEAD $svn_revno=$git_commit
> I plan to keep using git-svnimport and the standard git tools to work
> using the "svn mirror on git" as the main repository, but I plan to use
> "git-svn commit" to commit to the SVN repositories. I want this "commit
> tool" to not affect the current repository in any way, just like git-push:
> only send the commits to the remote repository and don't change anything
> in the local repository.
> However, it seems that "git-svn commit" does some tasks assuming we
> are on a "git-svn aware" repository (e.g. the "resyncing" just after
> the commit). Would you accept patches to allow using "git-svn commit"
> to commit changes from any GIT repository (i.e. not "svn-git aware"
> repositories) to any SVN repository, just like "git-push" would work
> for a GIT repository?
>
> However, I am not sure if the easier way would be changing git-svn to
> do this for me or writing a different script just for this task.
You should be 95% there just by exporting the svn_checkout_tree()
function to the command-line. Perhaps automating reading of the
$svn_rev variable can be in order.
--
Eric Wong
^ permalink raw reply [relevance 2%]
* [PATCH] First cut at libifying revlist generation
@ 2006-02-26 0:19 1% Linus Torvalds
0 siblings, 0 replies; 200+ results
From: Linus Torvalds @ 2006-02-26 0:19 UTC (permalink / raw)
To: Junio C Hamano, Git Mailing List
This really just splits things up partially, and creates the
interface to set things up by parsign the command line.
No real code changes so far, although the parsing of filenames is a bit
stricter. In particular, if there is a "--", then we do not accept any
filenames before it, and if there isn't any "--", then we check that _all_
paths listed are valid, not just the first one.
The new argument parsing automatically also gives us "--default" and
"--not" handling as in git-rev-parse.
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
---
The path checking just makes sense.
This also makes git-rev-list handle "--all" and "--not" correctly (before,
it wouldn't handle "--not"), and teaches it to handle "--default". I
didn't do "--since" and "--before", but I will eventually. The final end
result is that we won't need git-rev-parse for most things.
But basically there should be no code changes, and this is just a mid-way
point where a _partial_ set of routines from "git-rev-list" has been moved
into a library files - revision.c. The half-way point has some ugly
interfaces, but I don't want to do it all in one go.
The _plan_ is to:
- move the actual history traversal into revision.c too
- leave all the git-rev-list -specific stuff (the "--bisect" logic,
the print-out logic etc) in rev-list.c
- make it trivial to make a small C version of "git diff" that just uses
the same "setup_revisions()" interface and then looks at
"revs->commits" to see what revisions were passed in (the library
interface is already at the point where that should work)
- when the actual history _traversal_ is moved into "revision.c" too, it
should then be possible to make an equally small "git log" and friends
(whatchanged etc) into C using the revision.c code.
Comments? I think this is safe to apply, because I've done a diff of the
old non-split rev-list.c against both the new rev-list.c and revision.c,
and all the changes _look_ like just moving things around and taking the
new "struct rev_info" into account.
It also passes all the tests, and in general seems straightforward enough.
HOEVER, I'd still like to point out that I could have screwed something
up, and this is just about the most core program in all of git, so it
would make a lot of sense if more people double-checked my "trivial"
split-up.
Linus
diff --git a/Makefile b/Makefile
index 6c59cee..3575489 100644
--- a/Makefile
+++ b/Makefile
@@ -192,7 +192,7 @@ LIB_FILE=libgit.a
LIB_H = \
blob.h cache.h commit.h count-delta.h csum-file.h delta.h \
diff.h epoch.h object.h pack.h pkt-line.h quote.h refs.h \
- run-command.h strbuf.h tag.h tree.h git-compat-util.h
+ run-command.h strbuf.h tag.h tree.h git-compat-util.h revision.h
DIFF_OBJS = \
diff.o diffcore-break.o diffcore-order.o diffcore-pathspec.o \
@@ -205,7 +205,7 @@ LIB_OBJS = \
quote.o read-cache.o refs.o run-command.o \
server-info.o setup.o sha1_file.o sha1_name.o strbuf.o \
tag.o tree.o usage.o config.o environment.o ctype.o copy.o \
- fetch-clone.o \
+ fetch-clone.o revision.o \
$(DIFF_OBJS)
LIBS = $(LIB_FILE)
diff --git a/epoch.c b/epoch.c
index 3a76748..0f37492 100644
--- a/epoch.c
+++ b/epoch.c
@@ -15,6 +15,7 @@
#include "cache.h"
#include "commit.h"
+#include "revision.h"
#include "epoch.h"
struct fraction {
diff --git a/epoch.h b/epoch.h
index 7493d5a..3756009 100644
--- a/epoch.h
+++ b/epoch.h
@@ -11,7 +11,6 @@ typedef int (*emitter_func) (struct comm
int sort_list_in_merge_order(struct commit_list *list, emitter_func emitter);
/* Low bits are used by rev-list */
-#define UNINTERESTING (1u<<10)
#define BOUNDARY (1u<<11)
#define VISITED (1u<<12)
#define DISCONTINUITY (1u<<13)
diff --git a/rev-list.c b/rev-list.c
index 67d2a48..d1c52a6 100644
--- a/rev-list.c
+++ b/rev-list.c
@@ -6,9 +6,10 @@
#include "blob.h"
#include "epoch.h"
#include "diff.h"
+#include "revision.h"
+
+/* bits #0 and #1 in revision.h */
-#define SEEN (1u << 0)
-#define INTERESTING (1u << 1)
#define COUNTED (1u << 2)
#define SHOWN (1u << 3)
#define TREECHANGE (1u << 4)
@@ -38,60 +39,20 @@ static const char rev_list_usage[] =
" --bisect"
;
-static int dense = 1;
+struct rev_info revs;
+
static int unpacked = 0;
static int bisect_list = 0;
-static int tag_objects = 0;
-static int tree_objects = 0;
-static int blob_objects = 0;
-static int edge_hint = 0;
static int verbose_header = 0;
static int abbrev = DEFAULT_ABBREV;
static int show_parents = 0;
static int hdr_termination = 0;
static const char *commit_prefix = "";
-static unsigned long max_age = -1;
-static unsigned long min_age = -1;
-static int max_count = -1;
static enum cmit_fmt commit_format = CMIT_FMT_RAW;
static int merge_order = 0;
static int show_breaks = 0;
static int stop_traversal = 0;
-static int topo_order = 0;
-static int lifo = 1;
static int no_merges = 0;
-static const char **paths = NULL;
-static int remove_empty_trees = 0;
-
-struct name_path {
- struct name_path *up;
- int elem_len;
- const char *elem;
-};
-
-static char *path_name(struct name_path *path, const char *name)
-{
- struct name_path *p;
- char *n, *m;
- int nlen = strlen(name);
- int len = nlen + 1;
-
- for (p = path; p; p = p->up) {
- if (p->elem_len)
- len += p->elem_len + 1;
- }
- n = xmalloc(len);
- m = n + len - (nlen + 1);
- strcpy(m, name);
- for (p = path; p; p = p->up) {
- if (p->elem_len) {
- m -= p->elem_len + 1;
- memcpy(m, p->elem, p->elem_len);
- m[p->elem_len] = '/';
- }
- }
- return n;
-}
static void show_commit(struct commit *commit)
{
@@ -168,15 +129,15 @@ static int filter_commit(struct commit *
return STOP;
if (commit->object.flags & (UNINTERESTING|SHOWN))
return CONTINUE;
- if (min_age != -1 && (commit->date > min_age))
+ if (revs.min_age != -1 && (commit->date > revs.min_age))
return CONTINUE;
- if (max_age != -1 && (commit->date < max_age)) {
+ if (revs.max_age != -1 && (commit->date < revs.max_age)) {
stop_traversal=1;
return CONTINUE;
}
if (no_merges && (commit->parents && commit->parents->next))
return CONTINUE;
- if (paths && dense) {
+ if (revs.paths && revs.dense) {
if (!(commit->object.flags & TREECHANGE))
return CONTINUE;
rewrite_parents(commit);
@@ -196,7 +157,7 @@ static int process_commit(struct commit
return CONTINUE;
}
- if (max_count != -1 && !max_count--)
+ if (revs.max_count != -1 && !revs.max_count--)
return STOP;
show_commit(commit);
@@ -204,19 +165,6 @@ static int process_commit(struct commit
return CONTINUE;
}
-static struct object_list **add_object(struct object *obj,
- struct object_list **p,
- struct name_path *path,
- const char *name)
-{
- struct object_list *entry = xmalloc(sizeof(*entry));
- entry->item = obj;
- entry->next = *p;
- entry->name = path_name(path, name);
- *p = entry;
- return &entry->next;
-}
-
static struct object_list **process_blob(struct blob *blob,
struct object_list **p,
struct name_path *path,
@@ -224,7 +172,7 @@ static struct object_list **process_blob
{
struct object *obj = &blob->object;
- if (!blob_objects)
+ if (!revs.blob_objects)
return p;
if (obj->flags & (UNINTERESTING | SEEN))
return p;
@@ -241,7 +189,7 @@ static struct object_list **process_tree
struct tree_entry_list *entry;
struct name_path me;
- if (!tree_objects)
+ if (!revs.tree_objects)
return p;
if (obj->flags & (UNINTERESTING | SEEN))
return p;
@@ -314,75 +262,6 @@ static void show_commit_list(struct comm
}
}
-static void mark_blob_uninteresting(struct blob *blob)
-{
- if (!blob_objects)
- return;
- if (blob->object.flags & UNINTERESTING)
- return;
- blob->object.flags |= UNINTERESTING;
-}
-
-static void mark_tree_uninteresting(struct tree *tree)
-{
- struct object *obj = &tree->object;
- struct tree_entry_list *entry;
-
- if (!tree_objects)
- return;
- if (obj->flags & UNINTERESTING)
- return;
- obj->flags |= UNINTERESTING;
- if (!has_sha1_file(obj->sha1))
- return;
- if (parse_tree(tree) < 0)
- die("bad tree %s", sha1_to_hex(obj->sha1));
- entry = tree->entries;
- tree->entries = NULL;
- while (entry) {
- struct tree_entry_list *next = entry->next;
- if (entry->directory)
- mark_tree_uninteresting(entry->item.tree);
- else
- mark_blob_uninteresting(entry->item.blob);
- free(entry);
- entry = next;
- }
-}
-
-static void mark_parents_uninteresting(struct commit *commit)
-{
- struct commit_list *parents = commit->parents;
-
- while (parents) {
- struct commit *commit = parents->item;
- commit->object.flags |= UNINTERESTING;
-
- /*
- * Normally we haven't parsed the parent
- * yet, so we won't have a parent of a parent
- * here. However, it may turn out that we've
- * reached this commit some other way (where it
- * wasn't uninteresting), in which case we need
- * to mark its parents recursively too..
- */
- if (commit->parents)
- mark_parents_uninteresting(commit);
-
- /*
- * A missing commit is ok iff its parent is marked
- * uninteresting.
- *
- * We just mark such a thing parsed, so that when
- * it is popped next time around, we won't be trying
- * to parse it and get an error.
- */
- if (!has_sha1_file(commit->object.sha1))
- commit->object.parsed = 1;
- parents = parents->next;
- }
-}
-
static int everybody_uninteresting(struct commit_list *orig)
{
struct commit_list *list = orig;
@@ -413,7 +292,7 @@ static int count_distance(struct commit_
if (commit->object.flags & (UNINTERESTING | COUNTED))
break;
- if (!paths || (commit->object.flags & TREECHANGE))
+ if (!revs.paths || (commit->object.flags & TREECHANGE))
nr++;
commit->object.flags |= COUNTED;
p = commit->parents;
@@ -447,7 +326,7 @@ static struct commit_list *find_bisectio
nr = 0;
p = list;
while (p) {
- if (!paths || (p->item->object.flags & TREECHANGE))
+ if (!revs.paths || (p->item->object.flags & TREECHANGE))
nr++;
p = p->next;
}
@@ -457,7 +336,7 @@ static struct commit_list *find_bisectio
for (p = list; p; p = p->next) {
int distance;
- if (paths && !(p->item->object.flags & TREECHANGE))
+ if (revs.paths && !(p->item->object.flags & TREECHANGE))
continue;
distance = count_distance(p);
@@ -483,7 +362,7 @@ static void mark_edge_parents_uninterest
if (!(parent->object.flags & UNINTERESTING))
continue;
mark_tree_uninteresting(parent->tree);
- if (edge_hint && !(parent->object.flags & SHOWN)) {
+ if (revs.edge_hint && !(parent->object.flags & SHOWN)) {
parent->object.flags |= SHOWN;
printf("-%s\n", sha1_to_hex(parent->object.sha1));
}
@@ -613,7 +492,7 @@ static void try_to_simplify_commit(struc
return;
case TREE_NEW:
- if (remove_empty_trees && same_tree_as_empty(p->tree)) {
+ if (revs.remove_empty_trees && same_tree_as_empty(p->tree)) {
*pp = parent->next;
continue;
}
@@ -664,7 +543,7 @@ static void add_parents_to_list(struct c
* simplify the commit history and find the parent
* that has no differences in the path set if one exists.
*/
- if (paths)
+ if (revs.paths)
try_to_simplify_commit(commit);
parent = commit->parents;
@@ -693,7 +572,7 @@ static struct commit_list *limit_list(st
list = list->next;
free(entry);
- if (max_age != -1 && (commit->date < max_age))
+ if (revs.max_age != -1 && (commit->date < revs.max_age))
obj->flags |= UNINTERESTING;
if (unpacked && has_sha1_pack(obj->sha1))
obj->flags |= UNINTERESTING;
@@ -704,155 +583,40 @@ static struct commit_list *limit_list(st
break;
continue;
}
- if (min_age != -1 && (commit->date > min_age))
+ if (revs.min_age != -1 && (commit->date > revs.min_age))
continue;
p = &commit_list_insert(commit, p)->next;
}
- if (tree_objects)
+ if (revs.tree_objects)
mark_edges_uninteresting(newlist);
if (bisect_list)
newlist = find_bisection(newlist);
return newlist;
}
-static void add_pending_object(struct object *obj, const char *name)
-{
- add_object(obj, &pending_objects, NULL, name);
-}
-
-static struct commit *get_commit_reference(const char *name, const unsigned char *sha1, unsigned int flags)
-{
- struct object *object;
-
- object = parse_object(sha1);
- if (!object)
- die("bad object %s", name);
-
- /*
- * Tag object? Look what it points to..
- */
- while (object->type == tag_type) {
- struct tag *tag = (struct tag *) object;
- object->flags |= flags;
- if (tag_objects && !(object->flags & UNINTERESTING))
- add_pending_object(object, tag->tag);
- object = parse_object(tag->tagged->sha1);
- if (!object)
- die("bad object %s", sha1_to_hex(tag->tagged->sha1));
- }
-
- /*
- * Commit object? Just return it, we'll do all the complex
- * reachability crud.
- */
- if (object->type == commit_type) {
- struct commit *commit = (struct commit *)object;
- object->flags |= flags;
- if (parse_commit(commit) < 0)
- die("unable to parse commit %s", name);
- if (flags & UNINTERESTING)
- mark_parents_uninteresting(commit);
- return commit;
- }
-
- /*
- * Tree object? Either mark it uniniteresting, or add it
- * to the list of objects to look at later..
- */
- if (object->type == tree_type) {
- struct tree *tree = (struct tree *)object;
- if (!tree_objects)
- return NULL;
- if (flags & UNINTERESTING) {
- mark_tree_uninteresting(tree);
- return NULL;
- }
- add_pending_object(object, "");
- return NULL;
- }
-
- /*
- * Blob object? You know the drill by now..
- */
- if (object->type == blob_type) {
- struct blob *blob = (struct blob *)object;
- if (!blob_objects)
- return NULL;
- if (flags & UNINTERESTING) {
- mark_blob_uninteresting(blob);
- return NULL;
- }
- add_pending_object(object, "");
- return NULL;
- }
- die("%s is unknown object", name);
-}
-
-static void handle_one_commit(struct commit *com, struct commit_list **lst)
-{
- if (!com || com->object.flags & SEEN)
- return;
- com->object.flags |= SEEN;
- commit_list_insert(com, lst);
-}
-
-/* for_each_ref() callback does not allow user data -- Yuck. */
-static struct commit_list **global_lst;
-
-static int include_one_commit(const char *path, const unsigned char *sha1)
-{
- struct commit *com = get_commit_reference(path, sha1, 0);
- handle_one_commit(com, global_lst);
- return 0;
-}
-
-static void handle_all(struct commit_list **lst)
-{
- global_lst = lst;
- for_each_ref(include_one_commit);
- global_lst = NULL;
-}
-
int main(int argc, const char **argv)
{
- const char *prefix = setup_git_directory();
- struct commit_list *list = NULL;
+ struct commit_list *list;
int i, limited = 0;
+ argc = setup_revisions(argc, argv, &revs);
+
for (i = 1 ; i < argc; i++) {
- int flags;
const char *arg = argv[i];
- char *dotdot;
- struct commit *commit;
- unsigned char sha1[20];
/* accept -<digit>, like traditilnal "head" */
if ((*arg == '-') && isdigit(arg[1])) {
- max_count = atoi(arg + 1);
+ revs.max_count = atoi(arg + 1);
continue;
}
if (!strcmp(arg, "-n")) {
if (++i >= argc)
die("-n requires an argument");
- max_count = atoi(argv[i]);
+ revs.max_count = atoi(argv[i]);
continue;
}
if (!strncmp(arg,"-n",2)) {
- max_count = atoi(arg + 2);
- continue;
- }
- if (!strncmp(arg, "--max-count=", 12)) {
- max_count = atoi(arg + 12);
- continue;
- }
- if (!strncmp(arg, "--max-age=", 10)) {
- max_age = atoi(arg + 10);
- limited = 1;
- continue;
- }
- if (!strncmp(arg, "--min-age=", 10)) {
- min_age = atoi(arg + 10);
- limited = 1;
+ revs.max_count = atoi(arg + 2);
continue;
}
if (!strcmp(arg, "--header")) {
@@ -893,23 +657,6 @@ int main(int argc, const char **argv)
bisect_list = 1;
continue;
}
- if (!strcmp(arg, "--all")) {
- handle_all(&list);
- continue;
- }
- if (!strcmp(arg, "--objects")) {
- tag_objects = 1;
- tree_objects = 1;
- blob_objects = 1;
- continue;
- }
- if (!strcmp(arg, "--objects-edge")) {
- tag_objects = 1;
- tree_objects = 1;
- blob_objects = 1;
- edge_hint = 1;
- continue;
- }
if (!strcmp(arg, "--unpacked")) {
unpacked = 1;
limited = 1;
@@ -923,100 +670,42 @@ int main(int argc, const char **argv)
show_breaks = 1;
continue;
}
- if (!strcmp(arg, "--topo-order")) {
- topo_order = 1;
- lifo = 1;
- limited = 1;
- continue;
- }
- if (!strcmp(arg, "--date-order")) {
- topo_order = 1;
- lifo = 0;
- limited = 1;
- continue;
- }
- if (!strcmp(arg, "--dense")) {
- dense = 1;
- continue;
- }
- if (!strcmp(arg, "--sparse")) {
- dense = 0;
- continue;
- }
- if (!strcmp(arg, "--remove-empty")) {
- remove_empty_trees = 1;
- continue;
- }
- if (!strcmp(arg, "--")) {
- i++;
- break;
- }
-
- if (show_breaks && !merge_order)
- usage(rev_list_usage);
+ usage(rev_list_usage);
- flags = 0;
- dotdot = strstr(arg, "..");
- if (dotdot) {
- unsigned char from_sha1[20];
- char *next = dotdot + 2;
- *dotdot = 0;
- if (!*next)
- next = "HEAD";
- if (!get_sha1(arg, from_sha1) && !get_sha1(next, sha1)) {
- struct commit *exclude;
- struct commit *include;
-
- exclude = get_commit_reference(arg, from_sha1, UNINTERESTING);
- include = get_commit_reference(next, sha1, 0);
- if (!exclude || !include)
- die("Invalid revision range %s..%s", arg, next);
- limited = 1;
- handle_one_commit(exclude, &list);
- handle_one_commit(include, &list);
- continue;
- }
- *dotdot = '.';
- }
- if (*arg == '^') {
- flags = UNINTERESTING;
- arg++;
- limited = 1;
- }
- if (get_sha1(arg, sha1) < 0) {
- struct stat st;
- if (lstat(arg, &st) < 0)
- die("'%s': %s", arg, strerror(errno));
- break;
- }
- commit = get_commit_reference(arg, sha1, flags);
- handle_one_commit(commit, &list);
}
+ list = revs.commits;
+ if (list && list->next)
+ limited = 1;
+
+ if (revs.topo_order)
+ limited = 1;
+
if (!list &&
- (!(tag_objects||tree_objects||blob_objects) && !pending_objects))
+ (!(revs.tag_objects||revs.tree_objects||revs.blob_objects) && !revs.pending_objects))
usage(rev_list_usage);
- paths = get_pathspec(prefix, argv + i);
- if (paths) {
+ if (revs.paths) {
limited = 1;
- diff_tree_setup_paths(paths);
+ diff_tree_setup_paths(revs.paths);
}
+ if (revs.max_age || revs.min_age)
+ limited = 1;
save_commit_buffer = verbose_header;
track_object_refs = 0;
if (!merge_order) {
sort_by_date(&list);
- if (list && !limited && max_count == 1 &&
- !tag_objects && !tree_objects && !blob_objects) {
+ if (list && !limited && revs.max_count == 1 &&
+ !revs.tag_objects && !revs.tree_objects && !revs.blob_objects) {
show_commit(list->item);
return 0;
}
if (limited)
list = limit_list(list);
- if (topo_order)
- sort_in_topological_order(&list, lifo);
+ if (revs.topo_order)
+ sort_in_topological_order(&list, revs.lifo);
show_commit_list(list);
} else {
#ifndef NO_OPENSSL
diff --git a/revision.c b/revision.c
new file mode 100644
index 0000000..17dbf9a
--- /dev/null
+++ b/revision.c
@@ -0,0 +1,370 @@
+#include "cache.h"
+#include "tag.h"
+#include "blob.h"
+#include "tree.h"
+#include "commit.h"
+#include "refs.h"
+#include "revision.h"
+
+static char *path_name(struct name_path *path, const char *name)
+{
+ struct name_path *p;
+ char *n, *m;
+ int nlen = strlen(name);
+ int len = nlen + 1;
+
+ for (p = path; p; p = p->up) {
+ if (p->elem_len)
+ len += p->elem_len + 1;
+ }
+ n = xmalloc(len);
+ m = n + len - (nlen + 1);
+ strcpy(m, name);
+ for (p = path; p; p = p->up) {
+ if (p->elem_len) {
+ m -= p->elem_len + 1;
+ memcpy(m, p->elem, p->elem_len);
+ m[p->elem_len] = '/';
+ }
+ }
+ return n;
+}
+
+struct object_list **add_object(struct object *obj,
+ struct object_list **p,
+ struct name_path *path,
+ const char *name)
+{
+ struct object_list *entry = xmalloc(sizeof(*entry));
+ entry->item = obj;
+ entry->next = *p;
+ entry->name = path_name(path, name);
+ *p = entry;
+ return &entry->next;
+}
+
+static void mark_blob_uninteresting(struct blob *blob)
+{
+ if (blob->object.flags & UNINTERESTING)
+ return;
+ blob->object.flags |= UNINTERESTING;
+}
+
+void mark_tree_uninteresting(struct tree *tree)
+{
+ struct object *obj = &tree->object;
+ struct tree_entry_list *entry;
+
+ if (obj->flags & UNINTERESTING)
+ return;
+ obj->flags |= UNINTERESTING;
+ if (!has_sha1_file(obj->sha1))
+ return;
+ if (parse_tree(tree) < 0)
+ die("bad tree %s", sha1_to_hex(obj->sha1));
+ entry = tree->entries;
+ tree->entries = NULL;
+ while (entry) {
+ struct tree_entry_list *next = entry->next;
+ if (entry->directory)
+ mark_tree_uninteresting(entry->item.tree);
+ else
+ mark_blob_uninteresting(entry->item.blob);
+ free(entry);
+ entry = next;
+ }
+}
+
+void mark_parents_uninteresting(struct commit *commit)
+{
+ struct commit_list *parents = commit->parents;
+
+ while (parents) {
+ struct commit *commit = parents->item;
+ commit->object.flags |= UNINTERESTING;
+
+ /*
+ * Normally we haven't parsed the parent
+ * yet, so we won't have a parent of a parent
+ * here. However, it may turn out that we've
+ * reached this commit some other way (where it
+ * wasn't uninteresting), in which case we need
+ * to mark its parents recursively too..
+ */
+ if (commit->parents)
+ mark_parents_uninteresting(commit);
+
+ /*
+ * A missing commit is ok iff its parent is marked
+ * uninteresting.
+ *
+ * We just mark such a thing parsed, so that when
+ * it is popped next time around, we won't be trying
+ * to parse it and get an error.
+ */
+ if (!has_sha1_file(commit->object.sha1))
+ commit->object.parsed = 1;
+ parents = parents->next;
+ }
+}
+
+static void add_pending_object(struct rev_info *revs, struct object *obj, const char *name)
+{
+ add_object(obj, &revs->pending_objects, NULL, name);
+}
+
+static struct commit *get_commit_reference(struct rev_info *revs, const char *name, const unsigned char *sha1, unsigned int flags)
+{
+ struct object *object;
+
+ object = parse_object(sha1);
+ if (!object)
+ die("bad object %s", name);
+
+ /*
+ * Tag object? Look what it points to..
+ */
+ while (object->type == tag_type) {
+ struct tag *tag = (struct tag *) object;
+ object->flags |= flags;
+ if (revs->tag_objects && !(object->flags & UNINTERESTING))
+ add_pending_object(revs, object, tag->tag);
+ object = parse_object(tag->tagged->sha1);
+ if (!object)
+ die("bad object %s", sha1_to_hex(tag->tagged->sha1));
+ }
+
+ /*
+ * Commit object? Just return it, we'll do all the complex
+ * reachability crud.
+ */
+ if (object->type == commit_type) {
+ struct commit *commit = (struct commit *)object;
+ object->flags |= flags;
+ if (parse_commit(commit) < 0)
+ die("unable to parse commit %s", name);
+ if (flags & UNINTERESTING)
+ mark_parents_uninteresting(commit);
+ return commit;
+ }
+
+ /*
+ * Tree object? Either mark it uniniteresting, or add it
+ * to the list of objects to look at later..
+ */
+ if (object->type == tree_type) {
+ struct tree *tree = (struct tree *)object;
+ if (!revs->tree_objects)
+ return NULL;
+ if (flags & UNINTERESTING) {
+ mark_tree_uninteresting(tree);
+ return NULL;
+ }
+ add_pending_object(revs, object, "");
+ return NULL;
+ }
+
+ /*
+ * Blob object? You know the drill by now..
+ */
+ if (object->type == blob_type) {
+ struct blob *blob = (struct blob *)object;
+ if (!revs->blob_objects)
+ return NULL;
+ if (flags & UNINTERESTING) {
+ mark_blob_uninteresting(blob);
+ return NULL;
+ }
+ add_pending_object(revs, object, "");
+ return NULL;
+ }
+ die("%s is unknown object", name);
+}
+
+static void add_one_commit(struct commit *commit, struct rev_info *revs)
+{
+ if (!commit || (commit->object.flags & SEEN))
+ return;
+ commit->object.flags |= SEEN;
+ commit_list_insert(commit, &revs->commits);
+}
+
+static int all_flags;
+static struct rev_info *all_revs;
+
+static int handle_one_ref(const char *path, const unsigned char *sha1)
+{
+ struct commit *commit = get_commit_reference(all_revs, path, sha1, all_flags);
+ add_one_commit(commit, all_revs);
+ return 0;
+}
+
+static void handle_all(struct rev_info *revs, unsigned flags)
+{
+ all_revs = revs;
+ all_flags = flags;
+ for_each_ref(handle_one_ref);
+}
+
+/*
+ * Parse revision information, filling in the "rev_info" structure,
+ * and removing the used arguments from the argument list.
+ *
+ * Returns the number of arguments left ("new argc").
+ */
+int setup_revisions(int argc, const char **argv, struct rev_info *revs)
+{
+ int i, flags, seen_dashdash;
+ const char *def = NULL;
+ const char **unrecognized = argv+1;
+ int left = 1;
+
+ memset(revs, 0, sizeof(*revs));
+ revs->lifo = 1;
+ revs->dense = 1;
+ revs->prefix = setup_git_directory();
+ revs->max_age = -1;
+ revs->min_age = -1;
+ revs->max_count = -1;
+
+ /* First, search for "--" */
+ seen_dashdash = 0;
+ for (i = 1; i < argc; i++) {
+ const char *arg = argv[i];
+ if (strcmp(arg, "--"))
+ continue;
+ argv[i] = NULL;
+ argc = i;
+ revs->paths = get_pathspec(revs->prefix, argv + i + 1);
+ seen_dashdash = 1;
+ break;
+ }
+
+ flags = 0;
+ for (i = 1; i < argc; i++) {
+ struct commit *commit;
+ const char *arg = argv[i];
+ unsigned char sha1[20];
+ char *dotdot;
+ int local_flags;
+
+ if (*arg == '-') {
+ if (!strncmp(arg, "--max-count=", 12)) {
+ revs->max_count = atoi(arg + 12);
+ continue;
+ }
+ if (!strncmp(arg, "--max-age=", 10)) {
+ revs->max_age = atoi(arg + 10);
+ continue;
+ }
+ if (!strncmp(arg, "--min-age=", 10)) {
+ revs->min_age = atoi(arg + 10);
+ continue;
+ }
+ if (!strcmp(arg, "--all")) {
+ handle_all(revs, flags);
+ continue;
+ }
+ if (!strcmp(arg, "--not")) {
+ flags ^= UNINTERESTING;
+ continue;
+ }
+ if (!strcmp(arg, "--default")) {
+ if (++i >= argc)
+ die("bad --default argument");
+ def = argv[i];
+ continue;
+ }
+ if (!strcmp(arg, "--topo-order")) {
+ revs->topo_order = 1;
+ continue;
+ }
+ if (!strcmp(arg, "--date-order")) {
+ revs->lifo = 0;
+ revs->topo_order = 1;
+ continue;
+ }
+ if (!strcmp(arg, "--dense")) {
+ revs->dense = 1;
+ continue;
+ }
+ if (!strcmp(arg, "--sparse")) {
+ revs->dense = 0;
+ continue;
+ }
+ if (!strcmp(arg, "--remove-empty")) {
+ revs->remove_empty_trees = 1;
+ continue;
+ }
+ if (!strcmp(arg, "--objects")) {
+ revs->tag_objects = 1;
+ revs->tree_objects = 1;
+ revs->blob_objects = 1;
+ continue;
+ }
+ if (!strcmp(arg, "--objects-edge")) {
+ revs->tag_objects = 1;
+ revs->tree_objects = 1;
+ revs->blob_objects = 1;
+ revs->edge_hint = 1;
+ continue;
+ }
+ *unrecognized++ = arg;
+ left++;
+ continue;
+ }
+ dotdot = strstr(arg, "..");
+ if (dotdot) {
+ unsigned char from_sha1[20];
+ char *next = dotdot + 2;
+ *dotdot = 0;
+ if (!*next)
+ next = "HEAD";
+ if (!get_sha1(arg, from_sha1) && !get_sha1(next, sha1)) {
+ struct commit *exclude;
+ struct commit *include;
+
+ exclude = get_commit_reference(revs, arg, from_sha1, flags ^ UNINTERESTING);
+ include = get_commit_reference(revs, next, sha1, flags);
+ if (!exclude || !include)
+ die("Invalid revision range %s..%s", arg, next);
+ add_one_commit(exclude, revs);
+ add_one_commit(include, revs);
+ continue;
+ }
+ *dotdot = '.';
+ }
+ local_flags = 0;
+ if (*arg == '^') {
+ local_flags = UNINTERESTING;
+ arg++;
+ }
+ if (get_sha1(arg, sha1) < 0) {
+ struct stat st;
+ int j;
+
+ if (seen_dashdash || local_flags)
+ die("bad revision '%s'", arg);
+
+ /* If we didn't have a "--", all filenames must exist */
+ for (j = i; j < argc; j++) {
+ if (lstat(argv[j], &st) < 0)
+ die("'%s': %s", arg, strerror(errno));
+ }
+ revs->paths = get_pathspec(revs->prefix, argv + i);
+ break;
+ }
+ commit = get_commit_reference(revs, arg, sha1, flags ^ local_flags);
+ add_one_commit(commit, revs);
+ }
+ if (def && !revs->commits) {
+ unsigned char sha1[20];
+ struct commit *commit;
+ if (get_sha1(def, sha1) < 0)
+ die("bad default revision '%s'", def);
+ commit = get_commit_reference(revs, def, sha1, 0);
+ add_one_commit(commit, revs);
+ }
+ *unrecognized = NULL;
+ return left;
+}
diff --git a/revision.h b/revision.h
new file mode 100644
index 0000000..5170ac4
--- /dev/null
+++ b/revision.h
@@ -0,0 +1,48 @@
+#ifndef REVISION_H
+#define REVISION_H
+
+#define SEEN (1u<<0)
+#define UNINTERESTING (1u<<1)
+
+struct rev_info {
+ /* Starting list */
+ struct commit_list *commits;
+ struct object_list *pending_objects;
+
+ /* Basic information */
+ const char *prefix;
+ const char **paths;
+
+ /* Traversal flags */
+ unsigned int dense:1,
+ remove_empty_trees:1,
+ lifo:1,
+ topo_order:1,
+ tag_objects:1,
+ tree_objects:1,
+ blob_objects:1,
+ edge_hint:1;
+
+ /* special limits */
+ int max_count;
+ unsigned long max_age;
+ unsigned long min_age;
+};
+
+/* revision.c */
+extern int setup_revisions(int argc, const char **argv, struct rev_info *revs);
+extern void mark_parents_uninteresting(struct commit *commit);
+extern void mark_tree_uninteresting(struct tree *tree);
+
+struct name_path {
+ struct name_path *up;
+ int elem_len;
+ const char *elem;
+};
+
+extern struct object_list **add_object(struct object *obj,
+ struct object_list **p,
+ struct name_path *path,
+ const char *name);
+
+#endif
^ permalink raw reply related [relevance 1%]
* Re: Solaris cloning woes partly diagnosed
@ 2006-04-02 18:33 4% ` Linus Torvalds
2006-04-02 19:18 1% ` Linus Torvalds
2006-04-04 18:21 1% ` H. Peter Anvin
0 siblings, 2 replies; 200+ results
From: Linus Torvalds @ 2006-04-02 18:33 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
On Sun, 2 Apr 2006, Junio C Hamano wrote:
>
> We do two funky things when we have progress bar. We play games
> with timer signal (setitimer(ITIMER_REAL) and signal(SIGALRM)),
> and we spit out messages to stderr.
I'd be willing to bet that it's the fact that we take signals.
Suddenly, some system calls will either return -1/EINTR, or they'll return
partial reads or writes.
We should be pretty good at handling that, but maybe some place forgets.
One thing to do might be to make the itimer use a much higher frequency,
to trigger the problem more easily.
We do, for example, expect that regular file writing not do that. At least
"write_sha1_from_fd()" will just do a "write()" without testing the error
return, which is bad (it would silently create a truncated object if the
/tmp filesystem filled up). If somebody has their filesystem over NFS
mounted interruptible, partial writes could also happen.
Ho humm.
Linus
^ permalink raw reply [relevance 4%]
* Re: Solaris cloning woes partly diagnosed
2006-04-02 18:33 4% ` Linus Torvalds
@ 2006-04-02 19:18 1% ` Linus Torvalds
2006-04-04 18:21 1% ` H. Peter Anvin
1 sibling, 0 replies; 200+ results
From: Linus Torvalds @ 2006-04-02 19:18 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
On Sun, 2 Apr 2006, Linus Torvalds wrote:
>
> Suddenly, some system calls will either return -1/EINTR, or they'll return
> partial reads or writes.
Hmm. If I read the IRC logs right, the bad pack is still a _valid_ pack,
and passes git-verify-pack with flying colors.
That certainly implies that we had no problems with write-out: not only
must the SHA1 of the resulting file match itself, but it must match the
index too, and the number of objects there must match the index.
So the only way I see the pack being bad (if it does indeed pass
git-verify-pack) is if the object list we generated was bad.
However, "-q" only affects git-pack-file itself, not the generation of the
list. Which would imply that we have trouble _reading_ the list as it
comes in through a pipe. Which is just insane, because we use just a
bog-standard "fgets(... stdin)" for that. And no _way_ can stdio have
problems with a few SIGALRM's, that would break a lot of other problems.
But Oeje1 seems to be saying (in http://pastebin.com/635566):
git rev-list --objects --all | git pack-objects pack
Generating pack...
Done counting 15 objects.
Deltifying 15 objects.
100% (15/15) done
Writing 15 objects.
100% (15/15) done
806439fdfa5e9990b03f9301bd68e243795fff50
where the result _should_ be 16385 objects, not 15.
And the thing is, the _only_ thing we do there is that
while (fgets(line, sizeof(line), stdin) != NULL) {
...
add_object_entry(sha1, name_hash(NULL, line+41), 0);
so it really really looks like fgets() would have problems with a SIGALRM
coming in and doesn't just re-try on EINTR. Can Solaris stdio _really_ be
that broken? (Yeah, yeah, it may be "conforming". It's also so incredibly
programmer-unfriendly that it's not even funny)
That would be truly insane. Can somebody with Solaris check what the
following patch results in...
Linus
----
diff --git a/pack-objects.c b/pack-objects.c
index ccfaa5f..daba5de 100644
--- a/pack-objects.c
+++ b/pack-objects.c
@@ -1099,8 +1099,18 @@ int main(int argc, char **argv)
fprintf(stderr, "Generating pack...\n");
}
- while (fgets(line, sizeof(line), stdin) != NULL) {
+ for (;;) {
unsigned char sha1[20];
+
+ if (!fgets(line, sizeof(line), stdin)) {
+ if (feof(stdin))
+ break;
+ if (!ferror(stdin))
+ die("fgets returned NULL, not EOF, not error!");
+ if (errno == EINTR)
+ continue;
+ die("fgets: %s", strerror(errno));
+ }
if (line[0] == '-') {
if (get_sha1_hex(line+1, sha1))
^ permalink raw reply related [relevance 1%]
* Re: Solaris cloning woes partly diagnosed
@ 2006-04-02 19:22 4% ` Linus Torvalds
0 siblings, 0 replies; 200+ results
From: Linus Torvalds @ 2006-04-02 19:22 UTC (permalink / raw)
To: Jason Riedy; +Cc: git
On Sun, 2 Apr 2006, Jason Riedy wrote:
> And Linus Torvalds writes:
> -
> - I'd be willing to bet that it's the fact that we take signals.
>
> Unfortunately, I'm too busy to check into this, but I've
> run into similar problems in the past. Just takes a busy
> file server.
>
> - We do, for example, expect that regular file writing not do that. At least
> - "write_sha1_from_fd()" will just do a "write()" without testing the error
> - return, [...]
>
> There is an xwrite in git-compat-util.h...
Well, git itself is actually fairly good about these things. Right now I'm
seriously suspecting Solaris stdio as being just horribly impolite.
git tends to not just use xwrite() in most places, but check the return
value for partial sizes etc. I tried to grep for places where we were
lazy, and there really seems to be just a very small handful, and they
shouldn't impact this case at all (you have to have a seriously broken
setup for them to matter, but we should fix them nonetheless.
Linus
^ permalink raw reply [relevance 4%]
* Re: Solaris cloning woes partly diagnosed
2006-04-02 18:33 4% ` Linus Torvalds
2006-04-02 19:18 1% ` Linus Torvalds
@ 2006-04-04 18:21 1% ` H. Peter Anvin
1 sibling, 0 replies; 200+ results
From: H. Peter Anvin @ 2006-04-04 18:21 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Junio C Hamano, git
Linus Torvalds wrote:
>
> One thing to do might be to make the itimer use a much higher frequency,
> to trigger the problem more easily.
>
> We do, for example, expect that regular file writing not do that. At least
> "write_sha1_from_fd()" will just do a "write()" without testing the error
> return, which is bad (it would silently create a truncated object if the
> /tmp filesystem filled up). If somebody has their filesystem over NFS
> mounted interruptible, partial writes could also happen.
>
There seems to be a whole bunch of places where we use naked write()s
where xwrite or fwrite would be a lot more appropriate. The ssh-* files
seem to be particularly offensive in that way.
There are also a number of places which call xwrite with the apparent
belief that returning short is an error (e.g. blame.c). This as far as
I know the more common definition of xwrite(), but is *not* the one used
in git -- the one in git only guarantees that at least one character is
written.
-hpa
^ permalink raw reply [relevance 1%]
* [PATCH] Shell utilities: Guard against expr' magic tokens.
@ 2006-04-13 22:01 6% Mark Wooding
0 siblings, 0 replies; 200+ results
From: Mark Wooding @ 2006-04-13 22:01 UTC (permalink / raw)
To: git
From: Mark Wooding <mdw@distorted.org.uk>
Some words, e.g., `match', are special to expr(1), and cause strange
parsing effects. Track down all uses of expr and mangle the arguments
so that this isn't a problem.
Signed-off-by: Mark Wooding <mdw@distorted.org.uk>
---
Amusing one, this. I hacked on one of my projects, messing with a
simple glob matching function. Being uncreative, I called my topic
branch `match'. When I was ready, I switched back to my master branch
and said
$ git pull . match
Already up-to-date.
Oh. I checked. Nope, not up-to-date. I tried
$ git merge fast HEAD match, and that
and that did the right thing. But I was puzzled. I fired up the
git-bisect machinery and tried to find a good version to no avail. And
then, comparing `sh -x' traces of git-fetch, I noticed what had gone
wrong.
There's a line in git-parse-remote.sh, in canon_refs_list_for_fetch,
which says
expr "$ref" : '.*:' >/dev/null || ref="${ref}:"
In my case, $ref is `match', so this expands to
expr match : '.*:' >...
Unfortunately, GNU expr has a magic keyword `match'. So what this does
is compare `:' to the regexp `.*:', which /succeeds/, even though POSIX
expr without the `match' keyword would do the right thing and fail. So
$ref never has a `:' appended, which makes the later parsing fail, and
all sorts of strange things happen.
This patch puts magical extra characters in expr regexp calls
throughout the shell bits of GIT, to robustify them against this kind of
crapness.
There's a small chance I got something wrong while making this fix. I
was fairly careful, though, and ran the test suite without any
problems. I also checked Cogito, though that has no truck with expr.
---
git-cherry.sh | 2 +-
git-clone.sh | 6 +++---
git-commit.sh | 4 ++--
git-fetch.sh | 18 +++++++++---------
git-format-patch.sh | 4 ++--
git-merge-one-file.sh | 2 +-
git-parse-remote.sh | 20 ++++++++++----------
git-rebase.sh | 2 +-
git-tag.sh | 2 +-
9 files changed, 30 insertions(+), 30 deletions(-)
diff --git a/git-cherry.sh b/git-cherry.sh
index 1a62320..f0e8831 100755
--- a/git-cherry.sh
+++ b/git-cherry.sh
@@ -20,7 +20,7 @@ case "$1" in -v) verbose=t; shift ;; esa
case "$#,$1" in
1,*..*)
- upstream=$(expr "$1" : '\(.*\)\.\.') ours=$(expr "$1" : '.*\.\.\(.*\)$')
+ upstream=$(expr "z$1" : 'z\(.*\)\.\.') ours=$(expr "z$1" : '.*\.\.\(.*\)$')
set x "$upstream" "$ours"
shift ;;
esac
diff --git a/git-clone.sh b/git-clone.sh
index c013e48..0805168 100755
--- a/git-clone.sh
+++ b/git-clone.sh
@@ -38,12 +38,12 @@ Perhaps git-update-server-info needs to
}
while read sha1 refname
do
- name=`expr "$refname" : 'refs/\(.*\)'` &&
+ name=`expr "z$refname" : 'zrefs/\(.*\)'` &&
case "$name" in
*^*) continue;;
esac
if test -n "$use_separate_remote" &&
- branch_name=`expr "$name" : 'heads/\(.*\)'`
+ branch_name=`expr "z$name" : 'zheads/\(.*\)'`
then
tname="remotes/$origin/$branch_name"
else
@@ -346,7 +346,7 @@ then
# new style repository with a symref HEAD).
# Ideally we should skip the guesswork but for now
# opt for minimum change.
- head_sha1=`expr "$head_sha1" : 'ref: refs/heads/\(.*\)'`
+ head_sha1=`expr "z$head_sha1" : 'zref: refs/heads/\(.*\)'`
head_sha1=`cat "$GIT_DIR/$remote_top/$head_sha1"`
;;
esac
diff --git a/git-commit.sh b/git-commit.sh
index bd3dc71..01c73bd 100755
--- a/git-commit.sh
+++ b/git-commit.sh
@@ -549,8 +549,8 @@ fi >>"$GIT_DIR"/COMMIT_EDITMSG
# Author
if test '' != "$force_author"
then
- GIT_AUTHOR_NAME=`expr "$force_author" : '\(.*[^ ]\) *<.*'` &&
- GIT_AUTHOR_EMAIL=`expr "$force_author" : '.*\(<.*\)'` &&
+ GIT_AUTHOR_NAME=`expr "z$force_author" : 'z\(.*[^ ]\) *<.*'` &&
+ GIT_AUTHOR_EMAIL=`expr "z$force_author" : '.*\(<.*\)'` &&
test '' != "$GIT_AUTHOR_NAME" &&
test '' != "$GIT_AUTHOR_EMAIL" ||
die "malformatted --author parameter"
diff --git a/git-fetch.sh b/git-fetch.sh
index 954901d..711650f 100755
--- a/git-fetch.sh
+++ b/git-fetch.sh
@@ -112,7 +112,7 @@ append_fetch_head () {
*)
note_="$remote_name of " ;;
esac
- remote_1_=$(expr "$remote_" : '\(.*\)\.git/*$') &&
+ remote_1_=$(expr "z$remote_" : 'z\(.*\)\.git/*$') &&
remote_="$remote_1_"
note_="$note_$remote_"
@@ -245,22 +245,22 @@ fetch_main () {
# These are relative path from $GIT_DIR, typically starting at refs/
# but may be HEAD
- if expr "$ref" : '\.' >/dev/null
+ if expr "z$ref" : 'z\.' >/dev/null
then
not_for_merge=t
- ref=$(expr "$ref" : '\.\(.*\)')
+ ref=$(expr "z$ref" : 'z\.\(.*\)')
else
not_for_merge=
fi
- if expr "$ref" : '\+' >/dev/null
+ if expr "z$ref" : 'z\+' >/dev/null
then
single_force=t
- ref=$(expr "$ref" : '\+\(.*\)')
+ ref=$(expr "z$ref" : 'z\+\(.*\)')
else
single_force=
fi
- remote_name=$(expr "$ref" : '\([^:]*\):')
- local_name=$(expr "$ref" : '[^:]*:\(.*\)')
+ remote_name=$(expr "z$ref" : 'z\([^:]*\):')
+ local_name=$(expr "z$ref" : 'z[^:]*:\(.*\)')
rref="$rref$LF$remote_name"
@@ -276,7 +276,7 @@ fetch_main () {
print "$u";
' "$remote_name")
head=$(curl -nsfL $curl_extra_args "$remote/$remote_name_quoted") &&
- expr "$head" : "$_x40\$" >/dev/null ||
+ expr "z$head" : "z$_x40\$" >/dev/null ||
die "Failed to fetch $remote_name from $remote"
echo >&2 Fetching "$remote_name from $remote" using http
git-http-fetch -v -a "$head" "$remote/" || exit
@@ -362,7 +362,7 @@ fetch_main () {
break ;;
esac
done
- local_name=$(expr "$found" : '[^:]*:\(.*\)')
+ local_name=$(expr "z$found" : 'z[^:]*:\(.*\)')
append_fetch_head "$sha1" "$remote" \
"$remote_name" "$remote_nick" "$local_name" "$not_for_merge"
done
diff --git a/git-format-patch.sh b/git-format-patch.sh
index 2ebf7e8..c7133bc 100755
--- a/git-format-patch.sh
+++ b/git-format-patch.sh
@@ -126,8 +126,8 @@ for revpair
do
case "$revpair" in
?*..?*)
- rev1=`expr "$revpair" : '\(.*\)\.\.'`
- rev2=`expr "$revpair" : '.*\.\.\(.*\)'`
+ rev1=`expr "z$revpair" : 'z\(.*\)\.\.'`
+ rev2=`expr "z$revpair" : 'z.*\.\.\(.*\)'`
;;
*)
rev1="$revpair^"
diff --git a/git-merge-one-file.sh b/git-merge-one-file.sh
index 5349a1c..5619409 100755
--- a/git-merge-one-file.sh
+++ b/git-merge-one-file.sh
@@ -26,7 +26,7 @@ #
fi
if test -f "$4"; then
rm -f -- "$4" &&
- rmdir -p "$(expr "$4" : '\(.*\)/')" 2>/dev/null || :
+ rmdir -p "$(expr "z$4" : 'z\(.*\)/')" 2>/dev/null || :
fi &&
exec git-update-index --remove -- "$4"
;;
diff --git a/git-parse-remote.sh b/git-parse-remote.sh
index 63f2281..65c66d5 100755
--- a/git-parse-remote.sh
+++ b/git-parse-remote.sh
@@ -8,8 +8,8 @@ get_data_source () {
case "$1" in
*/*)
# Not so fast. This could be the partial URL shorthand...
- token=$(expr "$1" : '\([^/]*\)/')
- remainder=$(expr "$1" : '[^/]*/\(.*\)')
+ token=$(expr "z$1" : 'z\([^/]*\)/')
+ remainder=$(expr "z$1" : 'z[^/]*/\(.*\)')
if test -f "$GIT_DIR/branches/$token"
then
echo branches-partial
@@ -43,8 +43,8 @@ get_remote_url () {
branches)
sed -e 's/#.*//' "$GIT_DIR/branches/$1" ;;
branches-partial)
- token=$(expr "$1" : '\([^/]*\)/')
- remainder=$(expr "$1" : '[^/]*/\(.*\)')
+ token=$(expr "z$1" : 'z\([^/]*\)/')
+ remainder=$(expr "z$1" : 'z[^/]*/\(.*\)')
url=$(sed -e 's/#.*//' "$GIT_DIR/branches/$token")
echo "$url/$remainder"
;;
@@ -77,13 +77,13 @@ canon_refs_list_for_fetch () {
force=
case "$ref" in
+*)
- ref=$(expr "$ref" : '\+\(.*\)')
+ ref=$(expr "z$ref" : 'z\+\(.*\)')
force=+
;;
esac
- expr "$ref" : '.*:' >/dev/null || ref="${ref}:"
- remote=$(expr "$ref" : '\([^:]*\):')
- local=$(expr "$ref" : '[^:]*:\(.*\)')
+ expr "z$ref" : 'z.*:' >/dev/null || ref="${ref}:"
+ remote=$(expr "z$ref" : 'z\([^:]*\):')
+ local=$(expr "z$ref" : 'z[^:]*:\(.*\)')
case "$remote" in
'') remote=HEAD ;;
refs/heads/* | refs/tags/* | refs/remotes/*) ;;
@@ -97,7 +97,7 @@ canon_refs_list_for_fetch () {
*) local="refs/heads/$local" ;;
esac
- if local_ref_name=$(expr "$local" : 'refs/\(.*\)')
+ if local_ref_name=$(expr "z$local" : 'zrefs/\(.*\)')
then
git-check-ref-format "$local_ref_name" ||
die "* refusing to create funny ref '$local_ref_name' locally"
@@ -171,7 +171,7 @@ get_remote_refs_for_fetch () {
resolve_alternates () {
# original URL (xxx.git)
- top_=`expr "$1" : '\([^:]*:/*[^/]*\)/'`
+ top_=`expr "z$1" : 'z\([^:]*:/*[^/]*\)/'`
while read path
do
case "$path" in
diff --git a/git-rebase.sh b/git-rebase.sh
index 5956f06..86dfe9c 100755
--- a/git-rebase.sh
+++ b/git-rebase.sh
@@ -94,7 +94,7 @@ case "$#" in
;;
*)
branch_name=`git symbolic-ref HEAD` || die "No current branch"
- branch_name=`expr "$branch_name" : 'refs/heads/\(.*\)'`
+ branch_name=`expr "z$branch_name" : 'zrefs/heads/\(.*\)'`
;;
esac
branch=$(git-rev-parse --verify "${branch_name}^0") || exit
diff --git a/git-tag.sh b/git-tag.sh
index 76e51ed..dc6aa95 100755
--- a/git-tag.sh
+++ b/git-tag.sh
@@ -75,7 +75,7 @@ git-check-ref-format "tags/$name" ||
object=$(git-rev-parse --verify --default HEAD "$@") || exit 1
type=$(git-cat-file -t $object) || exit 1
tagger=$(git-var GIT_COMMITTER_IDENT) || exit 1
-: ${username:=$(expr "$tagger" : '\(.*>\)')}
+: ${username:=$(expr "z$tagger" : 'z\(.*>\)')}
trap 'rm -f "$GIT_DIR"/TAG_TMP* "$GIT_DIR"/TAG_FINALMSG "$GIT_DIR"/TAG_EDITMSG' 0
-- [mdw]
^ permalink raw reply related [relevance 6%]
* [Announce] GIT 1.3.0
@ 2006-04-18 21:55 1% Junio C Hamano
0 siblings, 0 replies; 200+ results
From: Junio C Hamano @ 2006-04-18 21:55 UTC (permalink / raw)
To: git; +Cc: linux-kernel
The latest feature release GIT 1.3.0 is available at the usual places:
http://www.kernel.org/pub/software/scm/git/
git-1.3.0.tar.{gz,bz2} (tarball)
RPMS/$arch/git-*-1.3.0-1.$arch.rpm (RPM)
There are many fixes and enhancements all over the place, and here is
only a list of notable user-visible changes in 1.3.0 since 1.2.6:
- git-cvsserver (Martin Langhoff).
This allows you to make your git repo accessible from CVS clients.
- Annotate/blame (Ryan Anderson and Fredrik Kuivinen).
These are alternate implementations of cvs annotate
equivalent. One of them probably needs to be eventually
retired, but for now they are kept while both of them
still have room for improvements.
- builtin diff generation is now truly built-in. We do not
rely on GNU diff anymore (Linus and Davide Libenzi).
This unfortunately makes GIT_DIFF_OPTS less useful; it can
only take -u<n> or --unified=<n> and nothing else.
- diff family acquired --stat, --patch-with-stat and --patch-with-raw
output formats (Johannes Schindelin, Petr Baudis).
- git-log command now takes diff options to act as a
replacement for git-whatchanged.
- rename detector was simplified and got faster (Linus and me).
- clone --use-separate-remote; a repository cloned with this
flag will copy the upstream branch heads under .git/remotes/origin/,
not .git/heads/. You will get the default "master" branch
that starts out as a copy of the upstream HEAD.
- A lot lower start-up latency for git-log, even when limiting
by paths (Linus).
- "git-commit --amend" can be used to amend the tip commit of the
current branch.
- Human date parsing is a bit friendlier to our European friends by
preferring dd.mm.yy format over mm.dd.yy.
- contrib/ hierarchy. Things that are not purely git proper
but are "around git" are shipped with git. Current
piggybackers are:
- Two Emacs interfaces (Alexandre Julliard)
- Alternative SVN interface (Eric Wong)
- Alternative repository viewer (Aneesh Kumar)
----------------------------------------------------------------
(Shortlog since v1.2.6)
A Large Angry SCM:
Makefile fixups.
Alex Riesen:
PATCH: simplify calls to git programs in git-fmt-merge-msg
workaround fat/ntfs deficiencies for t3600-rm.sh (git-rm)
Alexandre Julliard:
Add an Emacs interface in contrib.
git-format-patch: Always add a blank line between headers and body.
contrib/emacs: Add an Emacs VC backend.
git.el: Portability fixes for XEmacs and Emacs CVS.
git.el: Set default directory before running the status mode setup hooks.
git.el: Automatically update .gitignore status.
git.el: Added support for Signed-off-by.
git.el: Added customize support for all parameters.
ls-files: Don't require exclude files to end with a newline.
git.el: More robust handling of subprocess errors when returning strings.
git.el: Get the default user name and email from the repository config.
git.el: Added a function to diff against the other heads in a merge.
Anand Kumria:
git-svnimport: if a limit is specified, respect it
Aneesh Kumar K.V:
Add contrib/gitview from Aneesh.
Add a README for gitview
gitview: typofix
gitview: Read tag and branch information using git ls-remote
gitview: Use monospace font to draw the branch and tag name
gitview: Display the lines joining commit nodes clearly.
gitview: Fix DeprecationWarning
gitview: Bump the rev
gitview: Code cleanup
gitview: Fix the graph display .
gitview: Fix the encoding related bug
gitview: Remove trailing white space
gitview: Some window layout changes.
gitview: Set the default width of graph cell
gitview: Use horizontal scroll bar in the tree view
gitview: pass the missing argument _show_clicked_cb.
Carl Worth:
git-rebase: Clarify usage statement and copy it into the actual documentation.
New test to verify that when git-clone fails it cleans up the new directory.
git-ls-files: Fix, document, and add test for --error-unmatch option.
Add new git-rm command with documentation
git-rm: Fix to properly handle files with spaces, tabs, newlines, etc.
Davide Libenzi:
Clean-up trivially redundant diff.
xdiff: post-process hunks to make them consistent.
Dennis Stosberg:
Solaris 9 also wants our own unsetenv/setenv.
Replace index() with strchr().
Dmitry V. Levin:
git/Documentation: fix SYNOPSIS style bugs
Eric W. Biederman:
Implement limited context matching in git-apply.
Eric Wong:
Introducing contrib/git-svn.
git-svn: fix revision order when XML::Simple is not loaded
git-svn: ensure fetch always works chronologically.
git-svn: remove files from the index before adding/updating
git-svn: fix a typo in defining the --no-stop-on-copy option
git-svn: allow --find-copies-harder and -l<num> to be passed on commit
git-svn: Allow for more argument types for commit (from..to)
git-svn: remove any need for the XML::Simple dependency
git-svn: change ; to && in addremove()
contrib/git-svn.txt: add a note about renamed/copied directory support
git-svn: fix several corner-case and rare bugs with 'commit'
contrib/git-svn: add Makefile, test, and associated ignores
git-svn: 0.9.1: add --version and copyright/license (GPL v2+) information
contrib/git-svn: add show-ignore command
contrib/git-svn: optimize sequential commits to svn
contrib/git-svn: version 0.10.0
contrib/git-svn: tell the user to not modify git-svn-HEAD directly
contrib/git-svn: correct commit example in manpage
contrib/git-svn: use refs/remotes/git-svn instead of git-svn-HEAD
git-branch: add -r switch to list refs/remotes/*
contrib/git-svn: add -b/--branch switch for branch detection
contrib/git-svn: several small bug fixes and changes
contrib/git-svn: strip 'git-svn-id:' when commiting to SVN
contrib/git-svn: allow --authors-file to be specified
contrib/git-svn: cleanup option parsing
contrib/git-svn: create a more recent master if one does not exist
contrib/git-svn: avoid re-reading the repository uuid, it never changes
contrib/git-svn: add --id/-i=$GIT_SVN_ID command-line switch
contrib/git-svn: better documenting of CLI switches
send-email: accept --no-signed-off-by-cc as the documentation states
contrib/git-svn: fix a copied-tree bug in an overzealous assertion
contrib/git-svn: fix svn compat and fetch args
contrib/git-svn: remove the --no-stop-on-copy flag
contrib/git-svn: fix a harmless warning on rebuild (with old repos)
fetch,parse-remote,fmt-merge-msg: refs/remotes/* support
ls-tree: add --abbrev[=<n>] option
ls-files: add --abbrev[=<n>] option
contrib/git-svn: allow rebuild to work on non-linear remote heads
send-email: use built-in time() instead of /bin/date '+%s'
send-email: Change from Mail::Sendmail to Net::SMTP
send-email: try to order messages in email clients more correctly
send-email: lazy-load Email::Valid and make it optional
contrib/git-svn: stabilize memory usage for big fetches
contrib/git-svn: force GIT_DIR to an absolute path
contrib/git-svn: accept configuration via repo-config
contrib/git-svn: documentation updates
contrib/git-svn: ensure repo-config returns a value before using it
contrib/git-svn: make sure our git-svn is up-to-date for test
contrib/git-svn: handle array values correctly
Fernando J. Pereda:
Allow building Git in systems without iconv
Francis Daly:
AsciiDoc fix for tutorial
Tweak asciidoc output to work with broken docbook-xsl
Fix multi-paragraph list items in OPTIONS section
Format tweaks for asciidoc.
Tweaks to make asciidoc play nice.
Fredrik Kuivinen:
Add git-blame, a tool for assigning blame.
git-blame, take 2
git-blame: Make the output human readable
git-blame: Use the same tests for git-blame as for git-annotate
Fix some inconsistencies in the docs
Remove trailing dot after short description
Nicer output from 'git'
Make it possible to not clobber object.util in sort_in_topological_order (take 2)
rev-lib: Make it easy to do rename tracking (take 2)
blame: Rename detection (take 2)
blame: Nicer output
blame: Fix git-blame <directory>
Makefile: Add TAGS and tags targets
Herbert Valerio Riedel:
git-svnimport symlink support
J. Bruce Fields:
Document git-rebase behavior on conflicts.
Documentation: revise top of git man page
Jason Riedy:
Fix typo in git-rebase.sh.
Add ALL_LDFLAGS to the git target.
Jeff Muizelaar:
cosmetics: change from 'See-Also' to 'See Also'
documentation: add 'see also' sections to git-rm and git-add
Jim Radford:
fix repacking with lots of tags
Johannes Schindelin:
Fix cpio call
Optionally support old diffs
Support Irix
Optionally work without python
Fixes for ancient versions of GNU make
avoid makefile override warning
Really honour NO_PYTHON
Fix "gmake -j"
Use Ryan's git-annotate instead of jsannotate
Warn about invalid refs
Fix test case for some sed
imap-send: Add missing #include for macosx
Remove dependency on a file named "-lz"
cvsimport: use git-update-ref when updating
On some platforms, certain headers need to be included before regex.h
Fix compile with expat, but an old curl version
diff-options: add --stat (take 2)
diff-options: add --stat (take 2)
diff-options: add --patch-with-stat
pager: do not fork a pager if PAGER is set to empty.
Jon Loeliger:
Add git-show reference
Call out the two different uses of git-branch and fix a typo.
Document the default source of template files.
Clarify git-rebase example commands.
Reference git-commit-tree for env vars.
Fix minor typo.
Rewrite synopsis to clarify the two primary uses of git-checkout.
Clarify and expand some hook documentation.
Removed bogus "<snap>" identifier.
Added Packing Heursitics IRC writeup.
Jonas Fonseca:
manpages: insert two missing [verse] markers for multi-line SYNOPSIS
repo-config: give value_ a sane default so regexec won't segfault
Add git-annotate(1) and git-blame(1)
Josef Weidendorfer:
git-mv: fix moves into a subdir from outside
Junio C Hamano:
"Assume unchanged" git
"Assume unchanged" git: do not set CE_VALID with --refresh
ls-files: debugging aid for CE_VALID changes.
"Assume unchanged" git: --really-refresh fix.
ls-files: split "show-valid-bit" into a different option.
"assume unchanged" git: documentation.
cache_name_compare() compares name and stage, nothing else.
git-commit: Now --only semantics is the default.
rebase: allow a hook to refuse rebasing.
commit: detect misspelled pathspec while making a partial commit.
rebase: allow rebasing onto different base.
ls-files --error-unmatch pathspec error reporting fix.
Detect misspelled pathspec to git-add
packed objects: minor cleanup
topo-order: make --date-order optional.
pack-objects: reuse data from existing packs.
pack-objects: finishing touches.
git-repack: allow passing a couple of flags to pack-objects.
git-tag: -l to list tags (usability).
Add contrib/README.
SubmittingPatches: note on whitespaces
pack-objects: avoid delta chains that are too long.
Make "empty ident" error message a bit more helpful.
Delay "empty ident" errors until they really matter.
Keep Porcelainish from failing by broken ident after making changes.
fmt-merge-msg: say which branch things were merged into unless 'master'
Allow git-mv to accept ./ in paths.
Documentation: fix typo in rev-parse --short option description.
fmt-merge-msg: do not add excess newline at the end.
rev-list --objects-edge
Thin pack - create packfile with missing delta base.
send-pack --thin: use "thin pack" delta transfer.
Add git-push --thin.
Use thin pack transfer in "git fetch".
fmt-merge-msg: avoid open "-|" list form for Perl 5.6
rerere: avoid open "-|" list form for Perl 5.6
send-email: avoid open "-|" list form for Perl 5.6
svnimport: avoid open "-|" list form for Perl 5.6
cvsimport: avoid open "-|" list form for Perl 5.6
Fix fmt-merge-msg counting.
cherry-pick/revert: error-help message rewording.
git-mktree: reverse of git-ls-tree.
rev-list.c: fix non-grammatical comments.
send-pack: do not give up when remote has insanely large number of refs.
gitview: ls-remote invocation shellquote safety.
pack-objects: thin pack micro-optimization.
pack-objects: use full pathname to help hashing with "thin" pack.
count-delta: tweak counting of copied source material.
count-delta: fix counting of copied source.
Tweak break/merge score to adjust to the new delta generation code.
pack-objects: allow "thin" packs to exceed depth limits
rev-list --objects-edge: remove duplicated edge commit output.
rev-list --objects: use full pathname to help hashing.
pack-objects: hash basename and direname a bit differently.
Revert "diff-delta: produce optimal pack data"
Build and install git-mailinfo.
rev-list split: minimum fixup.
apply --whitespace fixes and enhancements.
apply: squelch excessive errors and --whitespace=error-all
apply --whitespace: configuration option.
git-apply --whitespace=nowarn
Revert "Revert "diff-delta: produce optimal pack data""
git-apply: war on whitespace -- finishing touches.
diffcore-break: micro-optimize by avoiding delta between identical files.
diffcore-rename: split out the delta counting code.
diffcore-delta: stop using deltifier for packing.
git-am: --whitespace=x option.
diff-delta: cull collided hash bucket more aggressively.
git-log (internal): add approxidate.
git-log (internal): more options.
Pretty-print tagger dates.
war on whitespaces: documentation.
Documentation: read-tree --aggressive
Documentation: rev-list --objects-edge
annotate: resurrect raw timestamps.
setup_revisions(): handle -n<n> and -<n> internally.
GIT-VERSION-GEN: squelch unneeded error from "cat version"
show-branch --topics
git-commit --amend
git-commit: make sure we protect against races.
diffcore-rename: similarity estimator fix.
show-branch --topics: omit more uninteresting commits.
count-delta: no need for this anymore.
diffcore-break: similarity estimator fix.
diffcore-delta: make change counter to byte oriented again.
git-commit --amend: allow empty commit.
Const tightening.
verify-pack -v: show delta-chain histogram.
blame: avoid -lm by not using log().
blame and annotate: show localtime with timezone.
blame: avoid "diff -u0".
annotate/blame tests updates.
annotate-blame test: don't "source", but say "."
annotate-blame test: add evil merge.
blame: unbreak "diff -U 0".
annotate-blame: tests incomplete lines.
pack-objects: simplify "thin" pack.
Use #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
refs.c::do_for_each_ref(): Finish error message lines with "\n"
fsck-objects: Remove --standalone
Fix t1200 test for breakage caused by removal of full-stop at the end of fast-forward message.
try_to_simplify_commit(): do not skip inspecting tree change at boundary.
repack: prune loose objects when -d is given
git-diff: -p disables rename detection.
diffcore-rename: somewhat optimized.
revision traversal: --remove-empty fix.
revision traversal: --remove-empty fix (take #2).
diffcore-delta: make the hash a bit denser.
diffcore-delta: tweak hashbase value.
cvsimport: honor -i and non -i upon subsequent imports
fetch: exit non-zero when fast-forward check fails.
cvsimport: fix reading from rev-parse
git-pull: run repo-config with dash form.
unpack_delta_entry(): reduce memory footprint.
generate-cmdlist: style cleanups.
revamp git-clone.
git-merge knows some strategies want to skip trivial merges
http-fetch: nicer warning for a server with unreliable 404 status
core.warnambiguousrefs: warns when "name" is used and both "name" branch and tag exists.
revamp git-clone (take #2).
get_sha1_basic(): try refs/... and finally refs/remotes/$foo/HEAD
clone: record the remote primary branch with remotes/$origin/HEAD
http-push.c: squelch C90 warnings.
git-apply: do not barf when updating an originally empty file.
rev-list --timestamp
git-clone: typofix.
git-pull: further safety while on tracking branch.
git-pull: reword "impossible to fast-forward" message.
sha1_name: warning ambiguous refs.
sha1_name: make core.warnambiguousrefs the default.
send-email: Identify author at the top when sending e-mail
commit-tree: check return value from write_sha1_file()
built-in diff: minimum tweaks
true built-in diff: run everything in-core.
git-push: make --thin pack transfer the default.
add clean and ignore rules for xdiff/
GIT 1.3.0 rc1
rev-list --no-merges: argument parsing fix.
rev-list: memory usage reduction.
rev-list --boundary
revision arguments: ..B means HEAD..B, just like A.. means A..HEAD
revision.c "..B" syntax: constness fix
assume unchanged git: diff-index fix.
tree/diff header cleanup.
rev-list --boundary: fix re-injecting boundary commits.
Makefile: many programs now depend on xdiff/lib.a having been built.
revision: --topo-order and --unpacked
revision: simplify argument parsing.
revision: --max-age alone does not need limit_list() anymore.
git-clone: fix handling of upsteram whose HEAD does not point at master.
GIT 1.3.0-rc2
combine-diff: use built-in xdiff.
combine-diff: refactor built-in xdiff interface.
combine-diff: move the code to parse hunk-header into common library.
blame: use built-in xdiff
date parsing: be friendlier to our European friends.
blame.c: fix completely broken ancestry traversal.
Match ofs/cnt types in diff interface.
blame -S <ancestry-file>
Add Documentation/technical/pack-format.txt
Thin pack generation: optimization.
rev-list --abbrev-commit
count-delta: match get_delta_hdr_size() changes.
GIT 1.3.0-rc3
git-log: match rev-list --abbrev and --abbrev-commit
diff: fix output of total-rewrite diff.
diffcore-rename: fix merging back a broken pair.
log-tree: separate major part of diff-tree.
git log [diff-tree options]...
Retire diffcore-pathspec.
tree-diff: do not assume we use only one pathspec
git log --full-diff
Retire git-log.sh
blame and friends: adjust to multiple pathspec change.
Retire git-log.sh (take#2)
diff-* --patch-with-raw
Retire git-log.sh (take #3)
combine-diff: do not lose hunks with only deletion at end.
combine-diff: fix hunks at the end (take #2).
Retire t5501-old-fetch-and-upload test.
git-commit: do not muck with commit message when no_edit is set.
stripspace: make sure not to leave an incomplete line.
combine-diff: type fix.
Documentation: add a couple of missing docs.
Makefile: $(MAKE) check-docs
git-log: do not output excess blank line between commits
t3600-rm: skip failed-remove test when we cannot make an unremovable file.
Fix-up previous expr changes.
diff --stat: no need to ask funcnames nor context.
t5500: test fix
stripspace: incomplete line fix (take #2)
Retire git-log.sh (take #4)
git-log <diff-options> <paths> documentation
"git cmd -h" for shell scripts.
rev-list --bisect: limit list before bisecting.
GIT v1.3.0-rc4
diff-tree: typefix.
diff --stat: do not do its own three-dashes.
diff-files --stat: do not dump core with unmerged index.
reading $GIT_DIR/info/graft - skip comments correctly.
rev-list --boundary: show boundary commits even when limited otherwise.
packed_object_info_detail(): check for corrupt packfile.
diff --stat: make sure to set recursive.
GIT 1.3.0
Karl Hasselström:
git-svnimport: -r adds svn revision number to commit messages
svnimport: Mention -r in usage summary
svnimport: Convert executable flag
svnimport: Convert the svn:ignore property
svnimport: Read author names and emails from a file
Let git-svnimport's author file use same syntax as git-cvsimport's
Save username -> Full Name <email@addr.es> map file
git-svnimport: Don't assume that copied files haven't changed
Keith Packard:
Provide configurable UI font for gitk
Linus Torvalds:
Handling large files with GIT
Handling large files with GIT
git-merge-tree: generalize the "traverse <n> trees in sync" functionality
Teach the "git" command to handle some commands internally
First cut at libifying revlist generation
Make git diff-generation use a simpler spawn-like interface
The war on trailing whitespace
Splitting rev-list into revisions lib, end of beginning.
git-rev-list libification: rev-list walking
Introduce trivial new pager.c helper infrastructure
Tie it all together: "git log"
Rip out merge-order and make "git log <paths>..." work again.
get_revision(): do not dig deeper when we know we are at the end.
git-fmt-merge-msg cleanup
Fix up diffcore-rename scoring
diffcore-delta: 64-byte-or-EOL ultrafast replacement.
diffcore-delta: 64-byte-or-EOL ultrafast replacement (hash fix).
git-apply: safety fixes
Use a *real* built-in diff generator
builtin-diff: \No newline at end of file.
Fix error handling for nonexistent names
Move "--parent" parsing into generic revision.c library code
Make path-limiting be incremental when possible.
revision: Fix --topo-order and --max-age with reachability limiting.
Make "--parents" logs also be incremental
When showing a commit message, do not lose an incomplete line.
Use less memory in "git log"
Clean up trailing whitespace when pretty-printing commits
Support "git cmd --help" syntax
Lukas Sandström:
git-fetch: print the new and old ref when fast-forwarding
Marco Costalba:
Add a Documentation/git-tools.txt
Marco Roeland:
imap-send: cleanup execl() call to use NULL sentinel instead of 0
git-commit: document --amend
xdiff/xdiffi.c: fix warnings about possibly uninitialized variables
Mark Hollomon:
Let merge set the default strategy.
Mark Wooding:
combine-diff: Honour --full-index.
combine-diff: Honour -z option correctly.
Documentation/Makefile: Some `git-*.txt' files aren't manpages.
gitignore: Ignore some more boring things.
contrib/emacs/Makefile: Provide tool for byte-compiling files.
annotate-tests: override VISUAL when running tests.
xdiff: Show function names in hunk headers.
gitk: Use git wrapper to run git-ls-remote.
Shell utilities: Guard against expr' magic tokens.
Martin Langhoff:
Introducing git-cvsserver -- a CVS emulator for git.
cvsserver: add notes on how to get a checkout under Eclipse
cvsserver: Eclipse compat fixes - implement Questionable, alias rlog, add a space after the U
cvsserver: Eclipse compat - browsing 'modules' (heads in our case) works
cvsserver: add notes on how to get a checkout under Eclipse
cvsserver: Eclipse compat fixes - implement Questionable, alias rlog, add a space after the U
cvsserver: Eclipse compat - browsing 'modules' (heads in our case) works
cvsserver: Checkout correctly on Eclipse
annotate: fix -S parameter to take a string
cvsserver: Eclipse compat -- now "compare with latest from HEAD" works
cvsserver: checkout faster by sending files in a sensible order
cvsserver: fix checkouts with -d <somedir>
cvsserver: checkout faster by sending files in a sensible order
cvsserver: fix checkouts with -d <somedir>
cvsserver: nested directory creation fixups for Eclipse clients
cvsserver: better error messages
cvsserver: anonymous cvs via pserver support
cvsserver: updated documentation
Martin Mares:
gitk: Make error_popup react to Return
Matthias Urlichs:
cvsimport: Remove master-updating code
Don't recurse into parents marked uninteresting.
Mike McCormack:
Allow adding arbitary lines in the mail header generated by format-patch.
Allow format-patch to attach patches
Document the --attach flag.
Describe how to add extra mail header lines in mail generated by git-format-patch.
Add git-imap-send, derived from isync 1.0.1.
Avoid a divide by zero if there's no messages to send.
Avoid a crash if realloc returns a different pointer.
Add documentation for git-imap-send.
Nick Hengeveld:
Update http-push functionality
http-push: fix revision walk
HTTP slot reuse fixes
http-push: refactor remote file/directory processing
http-push: improve remote lock management
http-push: support for updating remote info/refs
http-push: cleanup
Fix broken slot reuse when fetching alternates
http-push: add support for deleting remote branches
http-push: don't assume char is signed
git-ls-remote: send no-cache header when fetching info/refs
Set HTTP user agent to git/GIT_VERSION
http-fetch: add optional DAV-based pack list
Nicolas Pitre:
relax delta selection filtering in pack-objects
diff-delta: fold two special tests into one plus cleanups
diff-delta: produce optimal pack data
diff-delta: big code simplification
diff-delta: bound hash list length to avoid O(m*n) behavior
diff-delta: produce optimal pack data
diff-delta: bound hash list length to avoid O(m*n) behavior
diff-delta: allow reusing of the reference buffer index
test-delta needs zlib to compile
diff-delta: bound hash list length to avoid O(m*n) behavior
3% tighter packs for free
Olaf Hering:
allow double click on current HEAD id after git-pull
Paul Jakma:
Makefile tweaks: Solaris 9+ dont need iconv / move up uname variables
Paul Mackerras:
gitk: Make "find" on "Files" work again.
gitk: New improved gitk
gitk: Fix clicks on arrows on line ends
gitk: Fix Update menu item
gitk: Various speed improvements
gitk: Further speedups
gitk: Fix a bug in drawing the selected line as a thick line
gitk: Fix display of diff lines beginning with --- or +++
gitk: Make commitdata an array rather than a list
gitk: Don't change cursor at end of layout if find in progress
gitk: Make downward-pointing arrows end in vertical line segment
gitk: Improve appearance of first child links
gitk: Fix two bugs reported by users
gitk: Use the new --boundary flag to git-rev-list
gitk: Show diffs for boundary commits
gitk: Prevent parent link from overwriting commit headline
gitk: Allow top panes to scroll horizontally with mouse button 2
gitk: Better workaround for arrows on diagonal line segments
gitk: replace parent and children arrays with lists
gitk: Add a help menu item to display key bindings
gitk: Fix incorrect invocation of getmergediffline
gitk: Fix bug caused by missing commitlisted elements
Pavel Roskin:
gitview: Select the text color based on whether the entry in highlighted. Use standard font.
Add git-clean command
gitk: Fix searching for filenames in gitk
Peter Eriksen:
Use blob_, commit_, tag_, and tree_type throughout.
Replace xmalloc+memset(0) with xcalloc.
Petr Baudis:
Properly git-bisect reset after bisecting from non-master head
Optionally do not list empty directories in git-ls-files --others
Support for pickaxe matching regular expressions
Improve the git-diff-tree -c/-cc documentation
Document --patch-with-raw
Separate the raw diff and patch with a newline
Randal L. Schwartz:
fix imap-send for OSX
Rene Scharfe:
tar-tree: Use SHA1 of root tree for the basedir
tar-tree: Introduce write_entry()
tar-tree: Use write_entry() to write the archive contents
tar-tree: Remove obsolete code
tar-tree: Use the prefix field of a tar header
Remove useless pointer update
Fix sparse warnings about usage of 0 instead of NULL
Fix sparse warnings about non-ANSI function prototypes
Rutger Nijlunsing:
gitk: add key bindings for selecting first and last commit
Ryan Anderson:
send-email: Add some options for controlling how addresses are automatically added to the cc: list.
send-email: Add --cc
Add git-annotate, a tool for assigning blame.
annotate: Handle dirty state and arbitrary revisions.
annotate: Convert all -| calls to use a helper open_pipe().
annotate: Use qx{} for pipes on activestate.
annotate: handle \No newline at end of file.
annotate: Add a basic set of test cases.
annotate: Support annotation of files on other revisions.
Sean Estabrooks:
annotate.perl triggers rpm bug
Serge E. Hallyn:
cleanups: Fix potential bugs in connect.c
cleanups: Remove unused vars from combine-diff.c
cleanups: Remove impossible case in quote.c
cleanups: prevent leak of two strduped strings in config.c
cleanups: remove unused variable from exec_cmd.c
Shawn Pearce:
git ls files recursively show ignored files
Add missing programs to ignore list
Darwin: Ignore missing /sw/lib
Teach git-checkout-index to read filenames from stdin.
Prevent --index-info from ignoring -z.
Add --temp and --stage=all options to checkout-index.
Add missing semicolon to sed command.
Stephen Rothwell:
gitk: allow goto heads
Timo Hirvonen:
Use setenv(), fix warnings
Tony Luck:
fix warning from pack-objects.c
Re-fix compilation warnings.
annotate should number lines starting with 1
fix field width/precision warnings in blame.c
Yann Dirson:
Allow empty lines in info/grafts
Yasushi SHOJI:
Be verbose when !initial commit
Make git-clone to take long double-dashed origin option (--origin)
git-clone: exit early if repo isn't specified
^ permalink raw reply [relevance 1%]
* PATCH: New diff-delta.c implementation (updated)
@ 2006-04-28 1:59 1% Geert Bosch
0 siblings, 0 replies; 200+ results
From: Geert Bosch @ 2006-04-28 1:59 UTC (permalink / raw)
To: git
Even though the previous version did really well on large files
with many changes, performance was lacking for the many small
files with very few changes that are so common for a VCS.
For example, it turns out that, for packing the 17005 objects in
my git.git repository, diff_delta processes 240 MB worth of target
data in about 12s on my powerbook. (There's even a little more
source data, and the 12s includes compression/decompression time.)
So the fancy fingerprint calculations really take too much time.
Fortunately, it turns out that of the 240M, 120M matches directly
at the start or the end of the source data. After this trivial
matching, most remaining matches are quite small. The overhead
of setting up buffers, computing longest runs of the same character
and computing 64-bit fingerprints becomes very noticeable and
can't be regained later.
As a result I implemented special indexing and matching routines
for "small" files. Here a fixed hash table size and index step
are used. The fingerprint window has been reduced to be equal to
the step size, which essentially gets rid of computation for
characters leaving the window. Finally, the fingerprint size
has been reduced to 32 bits with polynome of 31st degree.
The result has been only a slight increase in delta size for
very large test cases (but with better performance), and
both smaller deltas and faster execution speed for repacking
git.git. I had trouble cloning the Linux kernel repository,
but am now reasonably confident this will outperform the
existing algorithm pretty consistently.
On PPC, the trivial matching in head and tail, and for long
matching runs now shows up high in the profile. On x86,
byte operations are very fast, so I think things should
be at least equally good there.
Please play around with this and let me know of any results.
-Geert
Signed-off-by: Geert Bosch <bosch@gnat.com>
#include <unistd.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <sys/types.h>
#undef assert
#define assert(x) do { } while (0)
/*
* MIN_HTAB_SIZE is fixed amount to be added to the size of the hash table
* used for indexing and must be a power of two. This allows for small files
* to have a sparse hash table, since in that case it's cheap.
* Hash table sizes are rounded up to a power of two to avoid integer division.
*/
#define MIN_HTAB_SIZE 8192
#define MAX_HTAB_SIZE (1024*1024*1024)
#define SMALL_HTAB_SIZE 8192
#define SMALL_INDEX_STEP 16
/*
* Diffing files of gigabyte range is impractical with the current
* algorithm, so we're assuming 32-bit sizes everywhere.
* Size leaves some room for expansion when diffing random files.
*/
#define MAX_SIZE (0x7eff0000)
/* For small files, indices are represented in 16 bits.
* Since indices are always a multiple of the index_step, they
* can be shifted right a few bits to accommodate files larger than 64K
*/
#define SMALL_SHIFT 4
#define MAX_SMALL_SIZE (0xff00<<SMALL_SHIFT)
/* Initial size of copies table, dynamically extended as needed. */
#define MAX_COPIES 512
/*
* Matching is done using a sliding window for which a Rabin
* polynomial is computed. The advantage of such polynomials is
* that they can efficiently be updated at every position.
* The tables needed for this are precomputed, as it is desirable
* to use the same polynomial all the time for repeatable results.
* The 16 byte window is convenient for indexing with index_step 16.
* In that special case, the U table is not needed during indexing.
* The 32-bit hash helps on register-starved 32-bit architectures.
*/
#define RABIN_POLY 0xf3a03ce5
#define RABIN_DEGREE 31
#define RABIN_SHIFT 23
#define RABIN_WINDOW_SIZE 16
unsigned T[256] =
{ 0x00000000, 0xf3a03ce5, 0x14e0452f,
0xe74079ca, 0x29c08a5e, 0xda60b6bb, 0x3d20cf71, 0xce80f394, 0x538114bc,
0xa0212859, 0x47615193, 0xb4c16d76, 0x7a419ee2, 0x89e1a207, 0x6ea1dbcd,
0x9d01e728, 0x54a2159d, 0xa7022978, 0x404250b2, 0xb3e26c57, 0x7d629fc3,
0x8ec2a326, 0x6982daec, 0x9a22e609, 0x07230121, 0xf4833dc4, 0x13c3440e,
0xe06378eb, 0x2ee38b7f, 0xdd43b79a, 0x3a03ce50, 0xc9a3f2b5, 0x5ae417df,
0xa9442b3a, 0x4e0452f0, 0xbda46e15, 0x73249d81, 0x8084a164, 0x67c4d8ae,
0x9464e44b, 0x09650363, 0xfac53f86, 0x1d85464c, 0xee257aa9, 0x20a5893d,
0xd305b5d8, 0x3445cc12, 0xc7e5f0f7, 0x0e460242, 0xfde63ea7, 0x1aa6476d,
0xe9067b88, 0x2786881c, 0xd426b4f9, 0x3366cd33, 0xc0c6f1d6, 0x5dc716fe,
0xae672a1b, 0x492753d1, 0xba876f34, 0x74079ca0, 0x87a7a045, 0x60e7d98f,
0x9347e56a, 0x4668135b, 0xb5c82fbe, 0x52885674, 0xa1286a91, 0x6fa89905,
0x9c08a5e0, 0x7b48dc2a, 0x88e8e0cf, 0x15e907e7, 0xe6493b02, 0x010942c8,
0xf2a97e2d, 0x3c298db9, 0xcf89b15c, 0x28c9c896, 0xdb69f473, 0x12ca06c6,
0xe16a3a23, 0x062a43e9, 0xf58a7f0c, 0x3b0a8c98, 0xc8aab07d, 0x2feac9b7,
0xdc4af552, 0x414b127a, 0xb2eb2e9f, 0x55ab5755, 0xa60b6bb0, 0x688b9824,
0x9b2ba4c1, 0x7c6bdd0b, 0x8fcbe1ee, 0x1c8c0484, 0xef2c3861, 0x086c41ab,
0xfbcc7d4e, 0x354c8eda, 0xc6ecb23f, 0x21accbf5, 0xd20cf710, 0x4f0d1038,
0xbcad2cdd, 0x5bed5517, 0xa84d69f2, 0x66cd9a66, 0x956da683, 0x722ddf49,
0x818de3ac, 0x482e1119, 0xbb8e2dfc, 0x5cce5436, 0xaf6e68d3, 0x61ee9b47,
0x924ea7a2, 0x750ede68, 0x86aee28d, 0x1baf05a5, 0xe80f3940, 0x0f4f408a,
0xfcef7c6f, 0x326f8ffb, 0xc1cfb31e, 0x268fcad4, 0xd52ff631, 0x7f701a53,
0x8cd026b6, 0x6b905f7c, 0x98306399, 0x56b0900d, 0xa510ace8, 0x4250d522,
0xb1f0e9c7, 0x2cf10eef, 0xdf51320a, 0x38114bc0, 0xcbb17725, 0x053184b1,
0xf691b854, 0x11d1c19e, 0xe271fd7b, 0x2bd20fce, 0xd872332b, 0x3f324ae1,
0xcc927604, 0x02128590, 0xf1b2b975, 0x16f2c0bf, 0xe552fc5a, 0x78531b72,
0x8bf32797, 0x6cb35e5d, 0x9f1362b8, 0x5193912c, 0xa233adc9, 0x4573d403,
0xb6d3e8e6, 0x25940d8c, 0xd6343169, 0x317448a3, 0xc2d47446, 0x0c5487d2,
0xfff4bb37, 0x18b4c2fd, 0xeb14fe18, 0x76151930, 0x85b525d5, 0x62f55c1f,
0x915560fa, 0x5fd5936e, 0xac75af8b, 0x4b35d641, 0xb895eaa4, 0x71361811,
0x829624f4, 0x65d65d3e, 0x967661db, 0x58f6924f, 0xab56aeaa, 0x4c16d760,
0xbfb6eb85, 0x22b70cad, 0xd1173048, 0x36574982, 0xc5f77567, 0x0b7786f3,
0xf8d7ba16, 0x1f97c3dc, 0xec37ff39, 0x39180908, 0xcab835ed, 0x2df84c27,
0xde5870c2, 0x10d88356, 0xe378bfb3, 0x0438c679, 0xf798fa9c, 0x6a991db4,
0x99392151, 0x7e79589b, 0x8dd9647e, 0x435997ea, 0xb0f9ab0f, 0x57b9d2c5,
0xa419ee20, 0x6dba1c95, 0x9e1a2070, 0x795a59ba, 0x8afa655f, 0x447a96cb,
0xb7daaa2e, 0x509ad3e4, 0xa33aef01, 0x3e3b0829, 0xcd9b34cc, 0x2adb4d06,
0xd97b71e3, 0x17fb8277, 0xe45bbe92, 0x031bc758, 0xf0bbfbbd, 0x63fc1ed7,
0x905c2232, 0x771c5bf8, 0x84bc671d, 0x4a3c9489, 0xb99ca86c, 0x5edcd1a6,
0xad7ced43, 0x307d0a6b, 0xc3dd368e, 0x249d4f44, 0xd73d73a1, 0x19bd8035,
0xea1dbcd0, 0x0d5dc51a, 0xfefdf9ff, 0x375e0b4a, 0xc4fe37af, 0x23be4e65,
0xd01e7280, 0x1e9e8114, 0xed3ebdf1, 0x0a7ec43b, 0xf9def8de, 0x64df1ff6,
0x977f2313, 0x703f5ad9, 0x839f663c, 0x4d1f95a8, 0xbebfa94d, 0x59ffd087,
0xaa5fec62
};
unsigned U[256] =
{ 0x00000000, 0x302a7c89, 0x6054f912,
0x507e859b, 0x3309cec1, 0x0323b248, 0x535d37d3, 0x63774b5a, 0x66139d82,
0x5639e10b, 0x06476490, 0x366d1819, 0x551a5343, 0x65302fca, 0x354eaa51,
0x0564d6d8, 0x3f8707e1, 0x0fad7b68, 0x5fd3fef3, 0x6ff9827a, 0x0c8ec920,
0x3ca4b5a9, 0x6cda3032, 0x5cf04cbb, 0x59949a63, 0x69bee6ea, 0x39c06371,
0x09ea1ff8, 0x6a9d54a2, 0x5ab7282b, 0x0ac9adb0, 0x3ae3d139, 0x7f0e0fc2,
0x4f24734b, 0x1f5af6d0, 0x2f708a59, 0x4c07c103, 0x7c2dbd8a, 0x2c533811,
0x1c794498, 0x191d9240, 0x2937eec9, 0x79496b52, 0x496317db, 0x2a145c81,
0x1a3e2008, 0x4a40a593, 0x7a6ad91a, 0x40890823, 0x70a374aa, 0x20ddf131,
0x10f78db8, 0x7380c6e2, 0x43aaba6b, 0x13d43ff0, 0x23fe4379, 0x269a95a1,
0x16b0e928, 0x46ce6cb3, 0x76e4103a, 0x15935b60, 0x25b927e9, 0x75c7a272,
0x45eddefb, 0x0dbc2361, 0x3d965fe8, 0x6de8da73, 0x5dc2a6fa, 0x3eb5eda0,
0x0e9f9129, 0x5ee114b2, 0x6ecb683b, 0x6bafbee3, 0x5b85c26a, 0x0bfb47f1,
0x3bd13b78, 0x58a67022, 0x688c0cab, 0x38f28930, 0x08d8f5b9, 0x323b2480,
0x02115809, 0x526fdd92, 0x6245a11b, 0x0132ea41, 0x311896c8, 0x61661353,
0x514c6fda, 0x5428b902, 0x6402c58b, 0x347c4010, 0x04563c99, 0x672177c3,
0x570b0b4a, 0x07758ed1, 0x375ff258, 0x72b22ca3, 0x4298502a, 0x12e6d5b1,
0x22cca938, 0x41bbe262, 0x71919eeb, 0x21ef1b70, 0x11c567f9, 0x14a1b121,
0x248bcda8, 0x74f54833, 0x44df34ba, 0x27a87fe0, 0x17820369, 0x47fc86f2,
0x77d6fa7b, 0x4d352b42, 0x7d1f57cb, 0x2d61d250, 0x1d4baed9, 0x7e3ce583,
0x4e16990a, 0x1e681c91, 0x2e426018, 0x2b26b6c0, 0x1b0cca49, 0x4b724fd2,
0x7b58335b, 0x182f7801, 0x28050488, 0x787b8113, 0x4851fd9a, 0x1b7846c2,
0x2b523a4b, 0x7b2cbfd0, 0x4b06c359, 0x28718803, 0x185bf48a, 0x48257111,
0x780f0d98, 0x7d6bdb40, 0x4d41a7c9, 0x1d3f2252, 0x2d155edb, 0x4e621581,
0x7e486908, 0x2e36ec93, 0x1e1c901a, 0x24ff4123, 0x14d53daa, 0x44abb831,
0x7481c4b8, 0x17f68fe2, 0x27dcf36b, 0x77a276f0, 0x47880a79, 0x42ecdca1,
0x72c6a028, 0x22b825b3, 0x1292593a, 0x71e51260, 0x41cf6ee9, 0x11b1eb72,
0x219b97fb, 0x64764900, 0x545c3589, 0x0422b012, 0x3408cc9b, 0x577f87c1,
0x6755fb48, 0x372b7ed3, 0x0701025a, 0x0265d482, 0x324fa80b, 0x62312d90,
0x521b5119, 0x316c1a43, 0x014666ca, 0x5138e351, 0x61129fd8, 0x5bf14ee1,
0x6bdb3268, 0x3ba5b7f3, 0x0b8fcb7a, 0x68f88020, 0x58d2fca9, 0x08ac7932,
0x388605bb, 0x3de2d363, 0x0dc8afea, 0x5db62a71, 0x6d9c56f8, 0x0eeb1da2,
0x3ec1612b, 0x6ebfe4b0, 0x5e959839, 0x16c465a3, 0x26ee192a, 0x76909cb1,
0x46bae038, 0x25cdab62, 0x15e7d7eb, 0x45995270, 0x75b32ef9, 0x70d7f821,
0x40fd84a8, 0x10830133, 0x20a97dba, 0x43de36e0, 0x73f44a69, 0x238acff2,
0x13a0b37b, 0x29436242, 0x19691ecb, 0x49179b50, 0x793de7d9, 0x1a4aac83,
0x2a60d00a, 0x7a1e5591, 0x4a342918, 0x4f50ffc0, 0x7f7a8349, 0x2f0406d2,
0x1f2e7a5b, 0x7c593101, 0x4c734d88, 0x1c0dc813, 0x2c27b49a, 0x69ca6a61,
0x59e016e8, 0x099e9373, 0x39b4effa, 0x5ac3a4a0, 0x6ae9d829, 0x3a975db2,
0x0abd213b, 0x0fd9f7e3, 0x3ff38b6a, 0x6f8d0ef1, 0x5fa77278, 0x3cd03922,
0x0cfa45ab, 0x5c84c030, 0x6caebcb9, 0x564d6d80, 0x66671109, 0x36199492,
0x0633e81b, 0x6544a341, 0x556edfc8, 0x05105a53, 0x353a26da, 0x305ef002,
0x00748c8b, 0x500a0910, 0x60207599, 0x03573ec3, 0x337d424a, 0x6303c7d1,
0x5329bb58
};
static unsigned char rabin_window[RABIN_WINDOW_SIZE];
static unsigned rabin_pos = 0;
#ifndef MIN
#define MIN(x,y) ((y)<(x) ? (y) : (x))
#endif
#ifndef MAX
#define MAX(x,y) ((y)>(x) ? (y) : (x))
#endif
/*
* The copies array is the central data structure for diff generation.
* Data statements are implicit, for ranges not covered by any copy command.
*
* The sum of tgt and length for each entry must be monotonically increasing,
* and data ranges must be non-overlapping. This is accomplished by not
* extending matches backwards during initial matching.
*
* Copies may have zero length, to make it quick to delete copies during
* optimization. However, the last copy in the list must always be a
* non-trivial copy.
*
* Before committing copies, an important optimization is performed: during
* a backward pass through the copies array, each entry is extended backwards,
* and redundant copies are eliminated.
*
* If each match were extended backwards on insertion, the same data may be
* matched an arbitrary number of times, resulting in potentially quadratic
* time behavior.
*/
typedef struct copyinfo {
unsigned src;
unsigned tgt;
unsigned length;
} CopyInfo;
static CopyInfo *copies;
static int copy_count = 0;
static unsigned max_copies = 0; /* Dynamically increased */
static unsigned *idx;
static unsigned idx_size;
static unsigned char *idx_data;
static unsigned idx_data_len;
typedef unsigned poly_t;
static void rabin_reset(void)
{
memset(rabin_window, 0, sizeof(rabin_window));
}
static poly_t rabin_slide (poly_t fp, unsigned char m)
{
unsigned char om;
if (++rabin_pos == RABIN_WINDOW_SIZE) rabin_pos = 0;
om = rabin_window[rabin_pos];
fp ^= U[om];
rabin_window[rabin_pos] = m;
fp = ((fp << 8) | m) ^ T[fp >> RABIN_SHIFT];
return fp;
}
static int add_copy (unsigned src, unsigned tgt, unsigned length)
{
if (copy_count == max_copies) {
max_copies *= 2;
if (!max_copies) {
max_copies = MAX_COPIES;
copies = malloc (max_copies * sizeof (CopyInfo));
} else
copies = realloc(copies,
max_copies * sizeof (CopyInfo));
if (!copies)
return 0;
}
copies[copy_count].src = src;
copies[copy_count].tgt = tgt;
copies[copy_count].length = length;
return ++copy_count;
}
static unsigned maxofs[256];
static unsigned maxlen[256];
static unsigned maxfp[256];
static const unsigned small_idx_size = SMALL_HTAB_SIZE;
static short unsigned small_idx[SMALL_HTAB_SIZE];
static void small_init_idx (unsigned char * data, unsigned len,
unsigned head, unsigned tail)
{
const unsigned index_step = SMALL_INDEX_STEP;
unsigned j = head - head % index_step;
unsigned k;
if (len < index_step) return;
idx_data = data;
idx_data_len = len;
len -= MIN (len, tail + (index_step - 1));
memset (small_idx, 0, sizeof(small_idx));
while (j < len) {
poly_t fp = 0;
do
fp = ((fp << 8) | data[j++]) ^ T[fp >> RABIN_SHIFT];
while (j % index_step);
small_idx[fp % small_idx_size] = j >> SMALL_SHIFT;
}
}
static void init_idx (unsigned char *data, unsigned len, int level,
unsigned head, unsigned tail)
{
unsigned index_step
= RABIN_WINDOW_SIZE / sizeof(unsigned) * sizeof(unsigned);
unsigned j, k;
unsigned char ch = 0;
unsigned runlen = 0;
poly_t fp = 0;
/* Special case small files at low optimization levels */
if (level <= 1 && len < MAX_SMALL_SIZE
&& len - head - tail < (SMALL_HTAB_SIZE * SMALL_INDEX_STEP)) {
small_init_idx(data, len, head, tail);
return;
}
assert (len <= MAX_SIZE);
assert (head < len);
assert (level >= 0 && level <= 9);
memset(maxofs, 0, sizeof(maxofs));
memset(maxlen, 0, sizeof(maxlen));
memset(maxfp, 0, sizeof(maxfp));
/* Smaller step size for higher optimization levels.
The index_step must be a multiple of the word size */
if (level >= 1)
index_step = MIN(index_step, 4 * sizeof (unsigned));
if (level >= 3)
index_step = MIN (index_step, 3 * sizeof (unsigned));
if (level >= 4)
index_step = MIN (index_step, 2 * sizeof (unsigned));
if (level >= 6)
index_step = MIN (index_step, 1 * sizeof (unsigned));
assert (index_step && !(index_step % sizeof (unsigned)));
/* Add fixed amount to hash table size, as small files will benefit
a lot without using significantly more memory or time. */
idx_size = (level + 1) * ((len - head - tail) / index_step) / 2;
idx_size = MIN (idx_size + MIN_HTAB_SIZE, MAX_HTAB_SIZE - 1);
/* Round up to next power of two, but limit to MAX_HTAB_SIZE. */
{
unsigned s = MIN_HTAB_SIZE;
while (s < idx_size) s += s;
idx_size = s;
}
idx_data = data;
idx_data_len = len;
idx = calloc(idx_size, sizeof(unsigned));
/* It is tempting to first index higher addresses, so hashes of lower
addresses will get preference in the hash table. However, for
repetitive patterns with a period that is a divisor of the
fingerprint window, this may mean the match is not anchored at
the end. Furthermore, even when using a window length that is
prime, the benefits are small and the irregularity of the first
matches being more important is not worth it. */
rabin_reset();
ch = 0;
runlen = 0;
if (head < RABIN_WINDOW_SIZE + index_step)
head = 0;
else {
head -= head % index_step;
for (j = head - RABIN_WINDOW_SIZE + 1; j < head; j++)
fp = rabin_slide (fp, data[j]);
}
for (j = head; j + index_step < len - tail; j += index_step) {
unsigned char pch = 0;
unsigned hash;
for (k = 0; k < index_step; k++) {
pch = ch;
ch = data[j + k];
if (ch != pch)
runlen = 0;
runlen++;
fp = rabin_slide(fp, ch);
}
/* See if there is a word-aligned window-sized run of
equal characters */
if (runlen >= RABIN_WINDOW_SIZE + sizeof(unsigned) - 1) {
/* Skip ahead to end of run */
while (j + k < len && data[j + k] == ch) {
k++;
runlen++;
}
/* Although matches are usually anchored at the end,
in the case of extended runs of equal characters
it is better to anchor after the first
RABIN_WINDOW_SIZE bytes. This allows for quick
skip ahead while matching such runs, avoiding
unneeded fingerprint calculations.
Also, when anchoring at the end, matches will be
generated after every word, because the fingerprint
stays constant. Even though all matches would get
combined during match optimization, it wastes time
and space. */
if (runlen > maxlen[pch] + 4) {
unsigned ofs;
/* ofs points RABIN_WINDOW_SIZE bytes after
the start of the run, rounded up to the
next word */
ofs = j + k - runlen + RABIN_WINDOW_SIZE
+ (sizeof (unsigned) - 1);
ofs -= ofs % sizeof(unsigned);
maxofs[pch] = ofs;
maxlen [pch] = runlen;
assert(maxfp[pch] == 0
|| maxfp[pch] == (unsigned)fp);
maxfp[pch] = (unsigned)fp;
}
/* Keep input aligned as if no special run
processing had taken place */
j += k - (k % index_step) - index_step;
k = index_step;
}
/* Testing showed that avoiding collisions using secondary
hashing, or hash chaining had little effect and is not
worth the time. */
hash = ((unsigned)fp) & (idx_size - 1);
idx[hash] = j + k;
}
/* Lastly, index the longest runs of equal characters found before.
This ensures we always match the longerst such runs available. */
for (j = 0; j < 256; j++)
if (maxlen[j])
idx[maxfp[j] % idx_size] = maxofs[j];
}
/* Match data against the current index and record all possible copies */
static int small_find_copies(unsigned char *data, unsigned len, unsigned head)
{
unsigned j = head < RABIN_WINDOW_SIZE ? 0 : head - RABIN_WINDOW_SIZE;
poly_t fp = 0;
while (j < MAX (head, RABIN_WINDOW_SIZE) && j < len)
fp = ((fp << 8) | data[j++]) ^ T[fp >> RABIN_SHIFT];
while (j < len) {
unsigned ofs, src, tgt, runlen, maxrun;
fp ^= U[data[j - RABIN_WINDOW_SIZE]];
fp = ((fp << 8) | data[j++]) ^ T[fp >> RABIN_SHIFT];
ofs = small_idx[fp & (small_idx_size - 1)] << SMALL_SHIFT;
/* Invariant:
data[0] .. data[j-1] has been processed
fp is fingerprint of sliding window ending at j-1
ofs is zero or points just past tentative match
ofs is a multiple of index_step */
if (!ofs)
continue;
runlen = 0;
tgt = j - 4;
src = ofs - 4;
maxrun = MIN(idx_data_len - src, len - tgt);
/* Hot loop */
while (runlen < maxrun &&
data[tgt + runlen] == idx_data[src + runlen])
runlen++;
if (runlen < 4)
continue;
if (!add_copy(src, tgt, runlen)) return 0;
/* For runs extending more than RABIN_WINDOW_SIZE bytes past j,
skip ahead to prevent useless fingerprint computations. */
if (tgt + runlen > j + RABIN_WINDOW_SIZE)
{
fp = 0;
j = tgt + runlen - RABIN_WINDOW_SIZE;
while (j < tgt + runlen)
fp = ((fp << 8) | data[j++])
^ T[fp >> RABIN_SHIFT];
}
/* Quickly scan ahead without looking for matches
until the end of this run */
while (j < tgt + runlen) {
fp ^= U[data[j - RABIN_WINDOW_SIZE]];
fp = ((fp << 8) | data[j++]) ^ T[fp >> RABIN_SHIFT];
}
}
return 1;
}
/* Match data against the current index and record all possible copies */
static int find_copies(unsigned char *data, unsigned len, unsigned head)
{
unsigned j = head < RABIN_WINDOW_SIZE ? 0 : head - RABIN_WINDOW_SIZE;
poly_t fp = 0;
assert (idx_data);
if (!idx) return small_find_copies (data, len, head);
rabin_reset();
while (j < head + RABIN_WINDOW_SIZE && j < len)
fp = rabin_slide(fp, data[j++]);
while (j < len) {
unsigned ofs, src, tgt, runlen, maxrun;
fp = rabin_slide(fp, data[j++]);
ofs = idx[fp & (idx_size - 1)];
/* Invariant:
data[0] .. data[j-1] has been processed
fp is fingerprint of sliding window ending at j-1
ofs is zero or points just past tentative match
ofs is a multiple of index_step */
if (!ofs)
continue;
runlen = 0;
tgt = j - 4;
src = ofs - 4;
maxrun = MIN(idx_data_len - src, len - tgt);
/* Hot loop */
while (runlen < maxrun &&
data[tgt + runlen] == idx_data[src + runlen])
runlen++;
if (runlen < 4)
continue;
if (!add_copy(src, tgt, runlen)) return 0;
/* For runs extending more than RABIN_WINDOW_SIZE bytes past j,
skip ahead to prevent useless fingerprint computations. */
if (tgt + runlen > j + RABIN_WINDOW_SIZE)
j = tgt + runlen - RABIN_WINDOW_SIZE;
/* Quickly scan ahead without looking for matches
until the end of this run */
while (j < tgt + runlen)
fp = rabin_slide(fp, data[j++]);
}
return 1;
}
static unsigned header_length(unsigned srclen, unsigned tgtlen)
{
unsigned len = 0;
assert (srclen <= MAX_SIZE && tgtlen <= MAX_SIZE);
/* GIT headers start with the length of the source and target,
with 7 bits per byte, least significant byte first, and
the high bit indicating continuation. */
do { len++; srclen >>= 7; } while (srclen);
do { len++; tgtlen >>= 7; } while (tgtlen);
return len;
}
static unsigned char *
write_header(unsigned char *patch, unsigned srclen, unsigned tgtlen)
{
assert (srclen <= MAX_SIZE && tgtlen <= MAX_SIZE);
while (srclen >= 0x80) {
*patch++ = srclen | 0x80;
srclen >>= 7;
}
*patch++ = srclen;
while (tgtlen >= 0x80) {
*patch++ = tgtlen | 0x80;
tgtlen >>= 7;
}
*patch++ = tgtlen;
return patch;
}
static unsigned data_length(unsigned length)
{
/* Can only include 0x7f data bytes per command */
unsigned partial = length % 0x7f;
assert (length > 0 && length <= MAX_SIZE);
if (partial) partial++;
return partial + (length / 0x7f) * 0x80;
}
static unsigned char *
write_data(unsigned char *patch, unsigned char *data, unsigned size)
{
assert (size > 0 && size < MAX_SIZE);
/* The return value must be equal to patch + data_length (patch, size).
This correspondence is essential for calculating the patch size. */
/* GIT has no data commands for large data, rest is same as GDIFF */
do {
unsigned s = size;
if (s > 0x7f)
s = 0x7f;
*patch++ = s;
memcpy(patch, data, s);
data += s;
patch += s;
size -= s;
} while (size);
return patch;
}
static unsigned copy_length (unsigned offset, unsigned length)
{
unsigned size = 0;
assert (offset < MAX_SIZE && length < MAX_SIZE);
/* For now we only copy a maximum of 0x10000 bytes per command.
Longer copies are broken into pieces of that size. */
do {
signed s = length;
if (s > 0x10000)
s = 0x10000;
size += !!(s & 0xff) + !!(s & 0xff00);
size += !!(offset & 0xff) + !!(offset & 0xff00) +
!!(offset & 0xff0000) + !!(offset & 0xff000000);
size += 1;
offset += s;
length -= s;
} while (length);
return size;
}
static unsigned char *
write_copy(unsigned char *patch, unsigned offset, unsigned size)
{
/* The return value must be equal to patch + copy_length
(patch, offset, size). This correspondence is essential
for calculating the patch size. */
do {
unsigned char c = 0x80, *cmd = patch++;
unsigned v, s = size;
if (s > 0x10000)
s = 0x10000;
v = offset;
if (v & 0xff) c |= 0x01, *patch++ = v;
v >>= 8;
if (v & 0xff) c |= 0x02, *patch++ = v;
v >>= 8;
if (v & 0xff) c |= 0x04, *patch++ = v;
v >>= 8;
if (v & 0xff) c |= 0x08, *patch++ = v;
v = s;
if (v & 0xff) c |= 0x10, *patch++ = v;
v >>= 8;
if (v & 0xff) c |= 0x20, *patch++ = v;
*cmd = c;
offset += s;
size -= s;
} while (size);
return patch;
}
static unsigned
process_copies (unsigned char *data, unsigned length, unsigned maxlen)
{
int j;
unsigned ptr = length;
unsigned patch_bytes = header_length(idx_data_len, length);
/* Work through the copies backwards, extending each one backwards. */
for (j = copy_count - 1; j >= 0; j--) {
CopyInfo *copy = copies+j;
unsigned src = copy->src;
unsigned tgt = copy->tgt;
unsigned len = copy->length;
int data_follows;
if (tgt + len > ptr) {
/* Part of copy already covered by later one,
so shorten copy. */
if (ptr < tgt) {
/* Copy completely disappeared, but guess
that a backward extension might still be
useful. This extension is non-contiguous,
as it is irrelevant whether the skipped
data would have matched or not. Be careful
to not extend past the beginning of
the source. */
unsigned adjust = tgt - ptr;
tgt = ptr;
src = (src < adjust) ? 0 : src - adjust;
copy->tgt = tgt;
copy->src = src;
}
len = ptr - tgt;
}
while (src && tgt && idx_data[src - 1] == data[tgt - 1]) {
src--;
tgt--;
}
len += copy->tgt - tgt;
data_follows = (tgt + len < ptr);
/* A short copy may cost as much as 6 bytes for the copy and
5 as result of an extra data command. It's not worth
having extra copies in order to just save a byte or two.
Being too smart here may hurt later compression as well. */
if (len < (data_follows ? 16 : 10))
len = 0;
/* Some target data is not covered by the copies, account for
the DATA command that will follow the copy. */
if (len && data_follows)
patch_bytes += data_length(ptr - (tgt + len));
/* Everything about the copy is known and will not change.
Write back the new information and update the patch size
with the size of the copy instruction. */
copy->length = len;
copy->src = src;
copy->tgt = tgt;
if (len) {
/* update patch size for copy command */
patch_bytes += copy_length (src, len);
ptr = tgt;
} else if (j == copy_count - 1) {
/* Remove empty copies at end of list. */
copy_count--;
}
if (patch_bytes > maxlen)
return 0;
}
/* Account for data before first copy */
if (ptr != 0)
patch_bytes += data_length(ptr);
if (patch_bytes > maxlen)
return 0;
return patch_bytes;
}
static void *
create_delta (unsigned char *data, unsigned len,
unsigned char *delta, unsigned delta_size)
{
unsigned char *ptr = delta;
unsigned offset = 0;
int j;
ptr = write_header(ptr, idx_data_len, len);
for (j = 0; j < copy_count; j++) {
CopyInfo *copy = copies + j;
unsigned copylen = copy->length;
if (!copylen)
continue;
if (copy->tgt > offset) {
ptr = write_data(ptr, data + offset,
copy->tgt - offset);
}
ptr = write_copy(ptr, copy->src, copylen);
offset = copy->tgt + copylen;
}
if (offset < len)
ptr = write_data(ptr, data + offset, len - offset);
assert(ptr - delta == delta_size);
return delta;
}
static void finalize_idx()
{
if (max_copies > 8 * MAX_COPIES) {
free(copies);
copies = 0;
max_copies = 0;
}
copy_count = 0;
if (idx) free(idx);
idx = 0;
idx_size = 0;
idx_data = 0;
idx_data_len = 0;
}
static unsigned
match_head (unsigned char *from, unsigned char *to, unsigned size)
{
unsigned head = 0;
while (head < size && from[head] == to[head]) head++;
return head;
}
static unsigned
match_tail (unsigned char *from, unsigned char *to, unsigned size)
{
unsigned tail = 0;
while (tail < size && *(from - tail) == *(to - tail)) tail++;
return tail;
}
void *diff_delta(void *from_buf, unsigned long from_size,
void *to_buf, unsigned long to_size,
unsigned long *delta_size, unsigned long max_size)
{
unsigned char *delta = 0;
unsigned dsize;
unsigned head = 0;
unsigned tail = 0;
assert (from_size <= MAX_SIZE && to_size <= MAX_SIZE);
/* The following actually takes care of about half of all target
data. This is performance critical, and may need some work. */
head = match_head(from_buf, to_buf, MIN(from_size, to_size));
tail = match_tail(from_buf + (from_size - 1), to_buf + (to_size - 1),
MIN(from_size, to_size - head));
if (head <= RABIN_WINDOW_SIZE) head = 0;
if (tail <= RABIN_WINDOW_SIZE) tail = 0;
if (!max_size)
max_size = from_size;
init_idx (from_buf, from_size, 1, head, tail);
if (head) add_copy (0, 0, head);
if (head + tail + RABIN_WINDOW_SIZE < from_size) {
if (!find_copies(to_buf, to_size - tail, head))
return 0;
}
if (tail) add_copy (from_size - tail, to_size - tail, tail);
dsize = process_copies(to_buf, to_size, max_size);
if (dsize)
{
delta = malloc (dsize);
delta = create_delta (to_buf, to_size, delta, dsize);
}
finalize_idx ();
if (delta)
*delta_size = dsize;
return delta;
}
^ permalink raw reply [relevance 1%]
* [REGRESSION] Interrupted clone/fetch leaves .lock files around
@ 2006-06-06 18:51 5% Jonas Fonseca
0 siblings, 0 replies; 200+ results
From: Jonas Fonseca @ 2006-06-06 18:51 UTC (permalink / raw)
To: git
Hi,
It used to be possible to continue an interrupted clone when using
cg-clone, by cding into the partial repo and run cg-fetch. However, it
seems that the recent changes in the ref locking code ends up leaving
.lock files around when interrupted.
$ cg clone http://elinks.cz/elinks.git
defaulting to local storage area
Fetching head...
Fetching objects...
...
Getting pack c0e265dab40fa34912c3ee6e02ba29686ab84a7b
which contains 16f85ec5043966c69e2142198c52e12494dcfc76
progress: 22 objects, 939754 bytes, now fetching c0e265dab40f... (657678 bytes)
cg-clone: interrupted
$ cd elinks
$ cg fetch
Recovering from a previously interrupted initial clone...
Fetching head...
Fetching objects...
error: Couldn't open lock file .git/refs/heads/origin.lock: File exists
error: Can't lock ref heads/origin
progress: 0 objects, 0 bytes
cg-fetch: objects fetch failed
Below is my feeble attempt at a (tested) fix.
diff --git a/fetch.c b/fetch.c
index e040ef9..861dc60 100644
--- a/fetch.c
+++ b/fetch.c
@@ -1,3 +1,5 @@
+#include <signal.h>
+
#include "fetch.h"
#include "cache.h"
@@ -214,9 +216,19 @@ static int mark_complete(const char *pat
return 0;
}
+static struct ref_lock *lock = NULL;
+
+static void remove_lockfile_on_signal(int signo)
+{
+ if (lock)
+ unlock_ref(lock);
+ lock = NULL;
+ signal(SIGINT, SIG_DFL);
+ raise(signo);
+}
+
int pull(char *target)
{
- struct ref_lock *lock = NULL;
unsigned char sha1[20];
char *msg;
int ret;
@@ -229,6 +241,7 @@ int pull(char *target)
error("Can't lock ref %s", write_ref);
return -1;
}
+ signal(SIGINT, remove_lockfile_on_signal);
}
if (!get_recover)
@@ -236,22 +249,11 @@ int pull(char *target)
if (interpret_target(target, sha1)) {
error("Could not interpret %s as something to pull", target);
- if (lock)
- unlock_ref(lock);
- return -1;
- }
- if (process(lookup_unknown_object(sha1))) {
- if (lock)
- unlock_ref(lock);
- return -1;
- }
- if (loop()) {
- if (lock)
- unlock_ref(lock);
- return -1;
- }
- if (write_ref) {
+ } else if (process(lookup_unknown_object(sha1)) || loop()) {
+ ; /* unlock */
+
+ } else if (write_ref) {
if (write_ref_log_details) {
msg = xmalloc(strlen(write_ref_log_details) + 12);
sprintf(msg, "fetch from %s", write_ref_log_details);
@@ -261,6 +263,10 @@ int pull(char *target)
if (msg)
free(msg);
return ret;
+ } else {
+ return 0;
}
- return 0;
+
+ remove_lockfile_on_signal(0);
+ return -1;
}
--
Jonas Fonseca
^ permalink raw reply related [relevance 5%]
* Re: Figured out how to get Mozilla into git
@ 2006-06-09 15:01 3% ` Linus Torvalds
0 siblings, 0 replies; 200+ results
From: Linus Torvalds @ 2006-06-09 15:01 UTC (permalink / raw)
To: Jakub Narebski; +Cc: git
On Fri, 9 Jun 2006, Jakub Narebski wrote:
> Jon Smirl wrote:
>
> >> git-repack -a -d but it OOMs on my 2GB+2GBswap machine :(
> >
> > We are all having problems getting this to run on 32 bit machines with
> > the 3-4GB process size limitations.
>
> Is that expected (for 10GB repository if I remember correctly), or is there
> some way to avoid this OOM?
Well, to some degree, the VM limitations are inevitable with huge packs.
The original idea for packs was to avoid making one huge pack, partly
because it was expected to be really really slow to generate (so
incremental repacking was a much better strategy), but partly simply
because trying to map one huge pack is really hard to do.
For various reasons, we ended up mostly using a single pack most of the
time: it's the most efficient model when the project is reasonably sized,
and it turns out that with the delta re-use, repacking even moderately
large projects like the kernel doesn't actually take all that long.
But the fact that we ended up mostly using a single pack for the kernel,
for example, doesn't mean that the fundamental reasons that git supports
multiple packs would somehow have gone away. At some point, the project
gets large enough that one single pack simply isn't reasonable.
So a single 2GB pack is already very much pushing it. It's really really
hard to map in a 2GB file on a 32-bit platform: your VM is usually
fragmented enough that it simply isn't practical. In fact, I think the
limit for _practical_ usage of single packs is probably somewhere in the
half-gig region, unless you just have 64-bit machines.
And yes, I realize that the "single pack" thing actually ends up having
become a fact for cloning, for example. Originally, cloning would unpack
on the receiving end, and leave the repacking to happen there, but that
obviously sucked. So now when we clone, we always get a single pack. That
can absolutely be a problem.
I don't know what the right solution is. Single packs _are_ very useful,
especially after a clone. So it's possible that we should just make the
pack-reading code be able to map partial packs. But the point is that
there are certainly ways we can fix this - it's not _really_ fundamental.
It's going to complicate it a bit (damn, how I hate 32-bit VM
limitations), but the good news is that the whole git model of "everything
is an individual object" means that it's a very _local_ decision: it will
probably be painful to re-do some of the pack reading code and have a LRU
of pack _fragments_ instead of a LRU of packs, but it's only going to
affect a small part of git, and everything else will never even see it.
So large packs are not really a fundamental problem, but right now we have
some practical issues with them.
(It's not _just_ packs: running out of memory is also because of
git-rev-list --objects being pretty memory hungry. I've improved the
memory usage several times by over 50%, but people keep trying larger
projects. It used to be that I considered the kernel a large history, now
we're talking about things that have ten times the number of objects).
Martin - do you have some place to make that big mozilla repo available?
It would be a good test-case..
Linus
^ permalink raw reply [relevance 3%]
* Re: Figured out how to get Mozilla into git
@ 2006-06-09 20:17 3% ` Jon Smirl
2006-06-09 20:44 4% ` Jakub Narebski
` (2 more replies)
0 siblings, 3 replies; 200+ results
From: Jon Smirl @ 2006-06-09 20:17 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Martin Langhoff, git
On 6/9/06, Linus Torvalds <torvalds@osdl.org> wrote:
>
>
> On Fri, 9 Jun 2006, Jon Smirl wrote:
> >
> > That looks too small. My svn git import is 2.7GB and the source CVS is
> > 3.0GB. The svn import wasn't finished when I stopped it.
>
> Git is much better at packing than either CVS or SVN. Get used to it ;)
The git tree that Martin got from cvsps is much smaller that the git
tree I got from going to svn then to git. I don't why the trees are
700KB different, it may be different amounts of packing, or one of the
conversion tools is losing something.
Earlier he said:
>git-repack -a -d but it OOMs on my 2GB+2GBswap machine :(
> > My cvsps process is still running from last night. The error file is
> > 341MB. How big is it when the conversion is finished? My machine is
> > swapping to death.
>
> Do you have all the cvsps patches? There's a few important ones floating
> around, and David Mansfield never did a 2.2 release..
I am running cvsps-2.1-3.fc5 so I may be wasting my time. Error out is
535MB now.
He sent me some git patches, but none for cvsps.
> I'm pretty sure Martin doesn't run plain 2.1.
I haven't come up with anything that is likely to result in Mozilla
switching over to git. Right now it takes three days to convert the
tree. The tree will have to be run in parallel for a while to convince
everyone to switch. I don't have a solution to keeping it in sync in
near real time (commits would still go to CVS). Most Mozilla
developers are interested but the infrastructure needs some help.
Martin has also brought up the problem with needing a partial clone so
that everyone doesn't have to bring down the entire repository. A
trunk checkout is 340MB and Martin's git tree is 2GB (mine 2.7GB). A
kernel tree is only 680M.
--
Jon Smirl
jonsmirl@gmail.com
^ permalink raw reply [relevance 3%]
* Re: Figured out how to get Mozilla into git
2006-06-09 20:17 3% ` Jon Smirl
@ 2006-06-09 20:44 4% ` Jakub Narebski
2006-06-09 21:05 0% ` Nicolas Pitre
2006-06-10 1:23 0% ` Martin Langhoff
2 siblings, 0 replies; 200+ results
From: Jakub Narebski @ 2006-06-09 20:44 UTC (permalink / raw)
To: git
Jon Smirl wrote:
> Martin has also brought up the problem with needing a partial clone so
> that everyone doesn't have to bring down the entire repository. A
> trunk checkout is 340MB and Martin's git tree is 2GB (mine 2.7GB). A
> kernel tree is only 680M.
Partial/shallow nor lazy clone we don't have (although there might be some
shallow clone partial solutions in topic branches and/or patches flying
around in git mailing list). Yet.
But you can do what was done for Linux kernel: split repository into current
and historical, and you can join them (join the history) if needed using
grafts. And even if one need historical repository, it is neede to
clone/copy only _once_. With alternatives (using historical repository as
one of alternatives for current repository) someone who has both
repositories does need only a little more space, I think, than if one used
single repository.
--
Jakub Narebski
Warsaw, Poland
^ permalink raw reply [relevance 4%]
* Re: Figured out how to get Mozilla into git
2006-06-09 20:17 3% ` Jon Smirl
2006-06-09 20:44 4% ` Jakub Narebski
@ 2006-06-09 21:05 0% ` Nicolas Pitre
2006-06-09 21:46 0% ` Jon Smirl
2006-06-10 1:23 0% ` Martin Langhoff
2 siblings, 1 reply; 200+ results
From: Nicolas Pitre @ 2006-06-09 21:05 UTC (permalink / raw)
To: Jon Smirl; +Cc: Linus Torvalds, Martin Langhoff, git
On Fri, 9 Jun 2006, Jon Smirl wrote:
> I haven't come up with anything that is likely to result in Mozilla
> switching over to git. Right now it takes three days to convert the
> tree. The tree will have to be run in parallel for a while to convince
> everyone to switch. I don't have a solution to keeping it in sync in
> near real time (commits would still go to CVS). Most Mozilla
> developers are interested but the infrastructure needs some help.
This is true. GIT is still evolving and certainly needs work to cope
with environments and datasets that were never tested before. The
Mozilla repo is one of those and we're certainly interested into making
it work well. GIT might not be right for it just yet, but if you could
let us rsync your converted repo to play with that might help us work on
proper fixes for that kind of repo.
> Martin has also brought up the problem with needing a partial clone so
> that everyone doesn't have to bring down the entire repository.
If it can be repacked into a single pack that size might get much
smaller too.
Nicolas
^ permalink raw reply [relevance 0%]
* Re: Figured out how to get Mozilla into git
2006-06-09 21:05 0% ` Nicolas Pitre
@ 2006-06-09 21:46 0% ` Jon Smirl
0 siblings, 0 replies; 200+ results
From: Jon Smirl @ 2006-06-09 21:46 UTC (permalink / raw)
To: Nicolas Pitre; +Cc: Linus Torvalds, Martin Langhoff, git
On 6/9/06, Nicolas Pitre <nico@cam.org> wrote:
> On Fri, 9 Jun 2006, Jon Smirl wrote:
>
> > I haven't come up with anything that is likely to result in Mozilla
> > switching over to git. Right now it takes three days to convert the
> > tree. The tree will have to be run in parallel for a while to convince
> > everyone to switch. I don't have a solution to keeping it in sync in
> > near real time (commits would still go to CVS). Most Mozilla
> > developers are interested but the infrastructure needs some help.
>
> This is true. GIT is still evolving and certainly needs work to cope
> with environments and datasets that were never tested before. The
> Mozilla repo is one of those and we're certainly interested into making
> it work well. GIT might not be right for it just yet, but if you could
> let us rsync your converted repo to play with that might help us work on
> proper fixes for that kind of repo.
I'm rebuilding it on my shared hosting account at dreamhost.com. I'll
see if I can get it built before they notice and kill my process. My
account there is on a 4GB quad xeon box so hopefully it can convert
the tree faster. My account has 1TB download per month so rsync will
be ok. Not bad for $12 the first year.
It would take over a day to rsync it off from my home machine.
> > Martin has also brought up the problem with needing a partial clone so
> > that everyone doesn't have to bring down the entire repository.
>
> If it can be repacked into a single pack that size might get much
> smaller too.
>
>
> Nicolas
>
--
Jon Smirl
jonsmirl@gmail.com
^ permalink raw reply [relevance 0%]
* Re: Figured out how to get Mozilla into git
2006-06-09 20:17 3% ` Jon Smirl
2006-06-09 20:44 4% ` Jakub Narebski
2006-06-09 21:05 0% ` Nicolas Pitre
@ 2006-06-10 1:23 0% ` Martin Langhoff
2 siblings, 0 replies; 200+ results
From: Martin Langhoff @ 2006-06-10 1:23 UTC (permalink / raw)
To: Jon Smirl; +Cc: Linus Torvalds, git
On 6/10/06, Jon Smirl <jonsmirl@gmail.com> wrote:
> The git tree that Martin got from cvsps is much smaller that the git
> tree I got from going to svn then to git. I don't why the trees are
> 700KB different, it may be different amounts of packing, or one of the
> conversion tools is losing something.
Don't read too much into that. Packing/repacking points make a _huge_
difference, and even if one of our trees is a bit corrupt, the
packsizes should be about the same.
(With the patches I sent you we _are_ choosing to ignore a few
branches that don't seem to make sense in cvsps output. These will
show up in the error output -- what I saw were very old, possibly
corrupt branches there, stuff I wouldn't shed a tear over, but it is
worth reviewing).
> I haven't come up with anything that is likely to result in Mozilla
> switching over to git. Right now it takes three days to convert the
> tree. The tree will have to be run in parallel for a while to convince
> everyone to switch. I don't have a solution to keeping it in sync in
> near real time (commits would still go to CVS). Most Mozilla
> developers are interested but the infrastructure needs some help.
Don't worry about the initial import time. Once you've done it, you
can run the incremental import (which will take a few minutes) even
hourly to keep 'in sync'.
> Martin has also brought up the problem with needing a partial clone so
> that everyone doesn't have to bring down the entire repository. A
> trunk checkout is 340MB and Martin's git tree is 2GB (mine 2.7GB). A
> kernel tree is only 680M.
Now that I have managed to repack the repo, it is indeed back in the
600M range. Actually, I just re-repacked, it took under a minute, and
it shrank down to 607MB.
Yay.
I'm sure that if you git-repack -a -d on a machine with plenty of
memory once or twice, we'll have matching packs.
cheers,
martin
^ permalink raw reply [relevance 0%]
* Lazy clone ideas
@ 2006-06-10 8:58 6% Jakub Narebski
0 siblings, 0 replies; 200+ results
From: Jakub Narebski @ 2006-06-10 8:58 UTC (permalink / raw)
To: git
I've started new thread for lazy clone ideas,
splitting from "Figured out how to get Mozilla into git"
Rogan Dawes wrote:
> Here's an idea. How about separating trees and commits from the actual
> blobs (e.g. in separate packs)? My reasoning is that the commits and
> trees should only be a small portion of the overall repository size, and
> should not be that expensive to transfer. (Of course, this is only a
> guess, and needs some numbers to back it up.)
>
> So, a shallow clone would receive all of the tree objects, and all of
> the commit objects, and could then request a pack containing the blobs
> represented by the current HEAD.
That would be _lazy_ clone (with on-demand pack downloading from "master"
full history repository), rather than shallow clone.
I had an idea for having all the commit objects (without all the tree
objects) below the soft-grafts line (beyond the line we cut-off full
history and start being lazy).
> In this way, the user has a history that will show all of the commit
> messages, and would be able to see _which_ files have changed over time
> e.g. gitk would still work - except for the actual file level diff, "git
> log" should also still work, etc
>
> This would also enable other optimisations.
>
> For example, documentation people would only need to get the objects
> under the doc/ tree, and would not need to actually check out the
> source. Git could detect any actual changes by checking whether it has
> the previous blob in its local repository, and whether the file exists
> locally. Creating a patch would obviously require that the person checks
> out the previous version, but one could theoretically commit a new blob
> to a repo without having the previous one (not saying that this would be
> a good idea, of course)
Something akin to CVS's modules, or rather to how CVS modules can be abused?
Something called, I think, partial checkout?
This is a separate idea and I think worth implementing even for full
repository.
> This would probably require Eric Biederman's "direct access to blob"
> patches, I guess, in order to be feasible.
And it would need place to store URI from where to doenload objects
on-demand: perhaps 'remote alternatives'?
--
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git
^ permalink raw reply [relevance 6%]
* [PATCH] The name of the hash is SHA-1, use it consistently in Documentation
@ 2006-06-11 20:37 1% Horst H. von Brand
0 siblings, 0 replies; 200+ results
From: Horst H. von Brand @ 2006-06-11 20:37 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
Signed-off-by: Horst H. von Brand <vonbrand@inf.utfsm.cl>
---
Documentation/config.txt | 2 +-
Documentation/core-tutorial.txt | 8 ++++----
Documentation/diff-format.txt | 8 ++++----
Documentation/diffcore.txt | 2 +-
Documentation/git-branch.txt | 2 +-
Documentation/git-cat-file.txt | 2 +-
Documentation/git-checkout.txt | 2 +-
Documentation/git-cherry.txt | 4 ++--
Documentation/git-diff-index.txt | 8 ++++----
Documentation/git-fsck-objects.txt | 8 ++++----
Documentation/git-init-db.txt | 2 +-
Documentation/git-ls-files.txt | 2 +-
Documentation/git-merge-index.txt | 2 +-
Documentation/git-mktag.txt | 6 +++---
Documentation/git-name-rev.txt | 2 +-
Documentation/git-patch-id.txt | 2 +-
Documentation/git-push.txt | 2 +-
Documentation/git-receive-pack.txt | 4 ++--
Documentation/git-rev-parse.txt | 8 ++++----
Documentation/git-show-branch.txt | 4 ++--
Documentation/git-show-index.txt | 2 +-
Documentation/git-tag.txt | 2 +-
Documentation/git-unpack-file.txt | 2 +-
Documentation/git-update-index.txt | 14 +++++++-------
Documentation/git-verify-pack.txt | 4 ++--
Documentation/git-verify-tag.txt | 2 +-
Documentation/git.txt | 2 +-
Documentation/glossary.txt | 4 ++--
Documentation/tutorial-2.txt | 14 +++++++-------
29 files changed, 63 insertions(+), 63 deletions(-)
diff --git a/Documentation/config.txt b/Documentation/config.txt
index a04c5ad..169640a 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -72,7 +72,7 @@ core.preferSymlinkRefs::
core.logAllRefUpdates::
If true, `git-update-ref` will append a line to
- "$GIT_DIR/logs/<ref>" listing the new SHA1 and the date/time
+ "$GIT_DIR/logs/<ref>" listing the new SHA-1 and the date/time
of the update. If the file does not exist it will be
created automatically. This information can be used to
determine what commit was the tip of a branch "2 days ago".
diff --git a/Documentation/core-tutorial.txt b/Documentation/core-tutorial.txt
index 1185897..151434b 100644
--- a/Documentation/core-tutorial.txt
+++ b/Documentation/core-tutorial.txt
@@ -100,9 +100,9 @@ branch. A number of the git tools will a
valid, though.
[NOTE]
-An 'object' is identified by its 160-bit SHA1 hash, aka 'object name',
+An 'object' is identified by its 160-bit SHA-1 hash, aka 'object name',
and a reference to an object is always the 40-byte hex
-representation of that SHA1 name. The files in the `refs`
+representation of that SHA-1 name. The files in the `refs`
subdirectory are expected to contain these hex references
(usually with a final `\'\n\'` at the end), and you should thus
expect to see a number of 41-byte files containing these
@@ -772,7 +772,7 @@ already discussed, the `HEAD` branch is
these object pointers.
You can at any time create a new branch by just picking an arbitrary
-point in the project history, and just writing the SHA1 name of that
+point in the project history, and just writing the SHA-1 name of that
object into a file under `.git/refs/heads/`. You can use any filename you
want (and indeed, subdirectories), but the convention is that the
"normal" branch is called `master`. That's just a convention, though,
@@ -1260,7 +1260,7 @@ file (the first tree goes to stage 1, th
etc.). After reading three trees into three stages, the paths
that are the same in all three stages are 'collapsed' into stage
0. Also paths that are the same in two of three stages are
-collapsed into stage 0, taking the SHA1 from either stage 2 or
+collapsed into stage 0, taking the SHA-1 from either stage 2 or
stage 3, whichever is different from stage 1 (i.e. only one side
changed from the common ancestor).
diff --git a/Documentation/diff-format.txt b/Documentation/diff-format.txt
index 617d8f5..d0d08bb 100644
--- a/Documentation/diff-format.txt
+++ b/Documentation/diff-format.txt
@@ -35,9 +35,9 @@ That is, from the left to the right:
. a space.
. mode for "dst"; 000000 if deletion or unmerged.
. a space.
-. sha1 for "src"; 0\{40\} if creation or unmerged.
+. SHA-1 for "src"; 0\{40\} if creation or unmerged.
. a space.
-. sha1 for "dst"; 0\{40\} if creation, unmerged or "look at work tree".
+. SHA-1 for "dst"; 0\{40\} if creation, unmerged or "look at work tree".
. a space.
. status, followed by optional "score" number.
. a tab or a NUL when '-z' option is used.
@@ -46,7 +46,7 @@ That is, from the left to the right:
. path for "dst"; only exists for C or R.
. an LF or a NUL when '-z' option is used, to terminate the record.
-<sha1> is shown as all 0's if a file is new on the filesystem
+<SHA-1> is shown as all 0's if a file is new on the filesystem
and it is out of sync with the index.
Example:
@@ -97,7 +97,7 @@ where:
<old|new>-file:: are files GIT_EXTERNAL_DIFF can use to read the
contents of <old|new>,
- <old|new>-hex:: are the 40-hexdigit SHA1 hashes,
+ <old|new>-hex:: are the 40-hexdigit SHA-1 hashes,
<old|new>-mode:: are the octal representation of the file modes.
+
diff --git a/Documentation/diffcore.txt b/Documentation/diffcore.txt
index cb4e562..984bb2b 100644
--- a/Documentation/diffcore.txt
+++ b/Documentation/diffcore.txt
@@ -115,7 +115,7 @@ it changes it to:
For the purpose of breaking a filepair, diffcore-break examines
the extent of changes between the contents of the files before
and after modification (i.e. the contents that have "bcd1234..."
-and "0123456..." as their SHA1 content ID, in the above
+and "0123456..." as their SHA-1 content ID, in the above
example). The amount of deletion of original contents and
insertion of new material are added together, and if it exceeds
the "break score", the filepair is broken into two. The break
diff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt
index d43ef1d..e16944d 100644
--- a/Documentation/git-branch.txt
+++ b/Documentation/git-branch.txt
@@ -38,7 +38,7 @@ OPTIONS
-l::
Create the branch's ref log. This activates recording of
all changes to made the branch ref, enabling use of date
- based sha1 expressions such as "<branchname>@{yesterday}".
+ based SHA-1 expressions such as "<branchname>@{yesterday}".
-f::
Force the creation of a new branch even if it means deleting
diff --git a/Documentation/git-cat-file.txt b/Documentation/git-cat-file.txt
index 5e9cbf8..8aa9fcb 100644
--- a/Documentation/git-cat-file.txt
+++ b/Documentation/git-cat-file.txt
@@ -19,7 +19,7 @@ or '-s' is used to find the object size.
OPTIONS
-------
<object>::
- The sha1 identifier of the object.
+ The SHA-1 identifier of the object.
-t::
Instead of the content, show the object type identified by
diff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt
index fbdbadc..77db0b3 100644
--- a/Documentation/git-checkout.txt
+++ b/Documentation/git-checkout.txt
@@ -43,7 +43,7 @@ OPTIONS
-l::
Create the new branch's ref log. This activates recording of
all changes to made the branch ref, enabling use of date
- based sha1 expressions such as "<branchname>@{yesterday}".
+ based SHA-1 expressions such as "<branchname>@{yesterday}".
-m::
If you have local modifications to one or more files that
diff --git a/Documentation/git-cherry.txt b/Documentation/git-cherry.txt
index 893baaa..5c783d4 100644
--- a/Documentation/git-cherry.txt
+++ b/Documentation/git-cherry.txt
@@ -15,12 +15,12 @@ The changeset (or "diff") of each commit
is compared against each commit between the fork-point and <upstream>.
Every commit with a changeset that doesn't exist in the other branch
-has its id (sha1) reported, prefixed by a symbol. Those existing only
+has its id (SHA-1) reported, prefixed by a symbol. Those existing only
in the <upstream> branch are prefixed with a minus (-) sign, and those
that only exist in the <head> branch are prefixed with a plus (+) symbol.
Because git-cherry compares the changeset rather than the commit id
-(sha1), you can use git-cherry to find out if a commit you made locally
+(SHA-1), you can use git-cherry to find out if a commit you made locally
has been applied <upstream> under a different commit id. For example,
this will happen if you're feeding patches <upstream> via email rather
than pushing or pulling commits directly.
diff --git a/Documentation/git-diff-index.txt b/Documentation/git-diff-index.txt
index 9cd43f1..750d646 100644
--- a/Documentation/git-diff-index.txt
+++ b/Documentation/git-diff-index.txt
@@ -93,7 +93,7 @@ you *could* commit. Again, the output ma
output to a tee, but with a twist.
The twist is that if some file doesn't match the index, we don't have
-a backing store thing for it, and we use the magic "all-zero" sha1 to
+a backing store thing for it, and we use the magic "all-zero" SHA-1 to
show that. So let's say that you have edited `kernel/sched.c`, but
have not actually done a "git-update-index" on it yet - there is no
"object" associated with the new state, and you get:
@@ -102,7 +102,7 @@ have not actually done a "git-update-ind
*100644->100664 blob 7476bb......->000000...... kernel/sched.c
i.e., it shows that the tree has changed, and that `kernel/sched.c` has is
-not up-to-date and may contain new stuff. The all-zero sha1 means that to
+not up-to-date and may contain new stuff. The all-zero SHA-1 means that to
get the real diff, you need to look at the object in the working directory
directly rather than do an object-to-object diff.
@@ -115,8 +115,8 @@ touched it. In either case, it's a note
NOTE: You can have a mixture of files show up as "has been updated"
and "is still dirty in the working directory" together. You can always
tell which file is in which state, since the "has been updated" ones
-show a valid sha1, and the "not in sync with the index" ones will
-always have the special all-zero sha1.
+show a valid SHA-1, and the "not in sync with the index" ones will
+always have the special all-zero SHA-1.
Author
diff --git a/Documentation/git-fsck-objects.txt b/Documentation/git-fsck-objects.txt
index d0af99d..78c6b59 100644
--- a/Documentation/git-fsck-objects.txt
+++ b/Documentation/git-fsck-objects.txt
@@ -22,7 +22,7 @@ OPTIONS
An object to treat as the head of an unreachability trace.
+
If no objects are given, git-fsck-objects defaults to using the
-index file and all SHA1 references in .git/refs/* as heads.
+index file and all SHA-1 references in .git/refs/* as heads.
--unreachable::
Print out objects that exist but that aren't readable from any
@@ -55,7 +55,7 @@ index file and all SHA1 references in .g
objects that triggers this check, but it is recommended
to check new projects with this flag.
-It tests SHA1 and general object sanity, and it does full tracking of
+It tests SHA-1 and general object sanity, and it does full tracking of
the resulting reachability and everything else. It prints out any
corruption it finds (missing or bad objects), and if you use the
'--unreachable' flag it will also print out objects that exist but
@@ -87,7 +87,7 @@ expect dangling commits - potential head
root nodes.
missing sha1 directory '<dir>'::
- The directory holding the sha1 objects is missing.
+ The directory holding the SHA-1 objects is missing.
unreachable <type> <object>::
The <type> object <object>, isn't actually referred to directly
@@ -109,7 +109,7 @@ warning: git-fsck-objects: tree <tree> h
And it shouldn't...
sha1 mismatch <object>::
- The database has an object who's sha1 doesn't match the
+ The database has an object who's SHA-1 doesn't match the
database value.
This indicates a serious data integrity problem.
diff --git a/Documentation/git-init-db.txt b/Documentation/git-init-db.txt
index 8a150d8..9ebd7d2 100644
--- a/Documentation/git-init-db.txt
+++ b/Documentation/git-init-db.txt
@@ -39,7 +39,7 @@ If the `$GIT_DIR` environment variable i
to use instead of `./.git` for the base of the repository.
If the object storage directory is specified via the `$GIT_OBJECT_DIRECTORY`
-environment variable then the sha1 directories are created underneath -
+environment variable then the SHA-1 directories are created underneath -
otherwise the default `$GIT_DIR/objects` directory is used.
A shared repository allows users belonging to the same group to push into that
diff --git a/Documentation/git-ls-files.txt b/Documentation/git-ls-files.txt
index 4d8a2ad..be85561 100644
--- a/Documentation/git-ls-files.txt
+++ b/Documentation/git-ls-files.txt
@@ -123,7 +123,7 @@ which case it outputs:
"git-ls-files --unmerged" and "git-ls-files --stage" can be used to examine
detailed information on unmerged paths.
-For an unmerged path, instead of recording a single mode/SHA1 pair,
+For an unmerged path, instead of recording a single mode/SHA-1 pair,
the dircache records up to three such pairs; one from tree O in stage
1, A in stage 2, and B in stage 3. This information can be used by
the user (or the porcelain) to see what should eventually be recorded at the
diff --git a/Documentation/git-merge-index.txt b/Documentation/git-merge-index.txt
index 6cd0601..eb8e019 100644
--- a/Documentation/git-merge-index.txt
+++ b/Documentation/git-merge-index.txt
@@ -13,7 +13,7 @@ SYNOPSIS
DESCRIPTION
-----------
This looks up the <file>(s) in the index and, if there are any merge
-entries, passes the SHA1 hash for those files as arguments 1, 2, 3 (empty
+entries, passes the SHA-1 hash for those files as arguments 1, 2, 3 (empty
argument if no file), and <file> as argument 4. File modes for the three
files are passed as arguments 5, 6 and 7.
diff --git a/Documentation/git-mktag.txt b/Documentation/git-mktag.txt
index 2860a3d..d78d2dc 100644
--- a/Documentation/git-mktag.txt
+++ b/Documentation/git-mktag.txt
@@ -19,9 +19,9 @@ The output is the new tag's <object> ide
Tag Format
----------
-A tag signature file has a very simple fixed format: three lines of
+A tag signature file has a very simple fixed format: Three lines of
- object <sha1>
+ object <SHA-1>
type <typename>
tag <tagname>
@@ -30,7 +30,7 @@ doesn't care about, but that can be veri
The size of the full object is artificially limited to 8kB. (Just
because I'm a lazy bastard, and if you can't fit a signature in that
-size, you're doing something wrong)
+size, you're doing something wrong.)
Author
diff --git a/Documentation/git-name-rev.txt b/Documentation/git-name-rev.txt
index 39a1434..0c8e8e3 100644
--- a/Documentation/git-name-rev.txt
+++ b/Documentation/git-name-rev.txt
@@ -26,7 +26,7 @@ OPTIONS
List all commits reachable from all refs
--stdin::
- Read from stdin, append "(<rev_name>)" to all sha1's of name'able
+ Read from stdin, append "(<rev_name>)" to all SHA-1s of name'able
commits, and pass to stdout
EXAMPLE
diff --git a/Documentation/git-patch-id.txt b/Documentation/git-patch-id.txt
index 5389097..f57d2b2 100644
--- a/Documentation/git-patch-id.txt
+++ b/Documentation/git-patch-id.txt
@@ -11,7 +11,7 @@ SYNOPSIS
DESCRIPTION
-----------
-A "patch ID" is nothing but a SHA1 of the diff associated with a patch, with
+A "patch ID" is nothing but a SHA-1 of the diff associated with a patch, with
whitespace and line numbers ignored. As such, it's "reasonably stable", but at
the same time also reasonably unique, i.e., two patches that have the same "patch
ID" are almost guaranteed to be the same thing.
diff --git a/Documentation/git-push.txt b/Documentation/git-push.txt
index d5b5ca1..3cb33d7 100644
--- a/Documentation/git-push.txt
+++ b/Documentation/git-push.txt
@@ -34,7 +34,7 @@ OPTIONS
the destination ref.
+
The <src> side can be an
-arbitrary "SHA1 expression" that can be used as an
+arbitrary "SHA-1 expression" that can be used as an
argument to `git-cat-file -t`. E.g. `master~4` (push
four parents before the current master head).
+
diff --git a/Documentation/git-receive-pack.txt b/Documentation/git-receive-pack.txt
index 60debca..ad91e24 100644
--- a/Documentation/git-receive-pack.txt
+++ b/Documentation/git-receive-pack.txt
@@ -21,7 +21,7 @@ program pair is meant to be used to push
repository. For pull operations, see 'git-fetch-pack' and
'git-clone-pack'.
-The command allows for creation and fast forwarding of sha1 refs
+The command allows for creation and fast forwarding of SHA-1 refs
(heads/tags) on the remote end (strictly speaking, it is the
local end receive-pack runs, but to the user who is sitting at
the send-pack end, it is updating the remote. Confused?)
@@ -32,7 +32,7 @@ and executable, it is called with three
$GIT_DIR/hooks/update refname sha1-old sha1-new
The refname parameter is relative to $GIT_DIR; e.g. for the
-master head this is "refs/heads/master". Two sha1 are the
+master head this is "refs/heads/master". Two SHA-1s are the
object names for the refname before and after the update. Note
that the hook is called before the refname is updated, so either
sha1-old is 0{40} (meaning there is no such ref yet), or it
diff --git a/Documentation/git-rev-parse.txt b/Documentation/git-rev-parse.txt
index 627cde8..25098bd 100644
--- a/Documentation/git-rev-parse.txt
+++ b/Documentation/git-rev-parse.txt
@@ -59,7 +59,7 @@ OPTIONS
one.
--symbolic::
- Usually the object names are output in SHA1 form (with
+ Usually the object names are output in SHA-1 form (with
possible '{caret}' prefix); this option makes them output in a
form as close to the original input as possible.
@@ -90,7 +90,7 @@ OPTIONS
Show `$GIT_DIR` if defined else show the path to the .git directory.
--short, --short=number::
- Instead of outputting the full SHA1 values of object names try to
+ Instead of outputting the full SHA-1 values of object names try to
abbreviate them to a shorter unique name. When no length is specified
7 is used. The minimum length is 4.
@@ -110,10 +110,10 @@ SPECIFYING REVISIONS
--------------------
A revision parameter typically, but not necessarily, names a
-commit object. They use what is called an 'extended SHA1'
+commit object. They use what is called an 'extended SHA-1'
syntax.
-* The full SHA1 object name (40-byte hexadecimal string), or
+* The full SHA-1 object name (40-byte hexadecimal string), or
a substring of such that is unique within the repository.
E.g. dae86e1950b1277e545cee180551750029cfe735 and dae86e both
name the same commit object if there are no other object in
diff --git a/Documentation/git-show-branch.txt b/Documentation/git-show-branch.txt
index f115b45..8937428 100644
--- a/Documentation/git-show-branch.txt
+++ b/Documentation/git-show-branch.txt
@@ -28,7 +28,7 @@ no <rev> nor <glob> is given on the comm
OPTIONS
-------
<rev>::
- Arbitrary extended SHA1 expression (see `git-rev-parse`)
+ Arbitrary extended SHA-1 expression (see `git-rev-parse`)
that typically names a branch HEAD or a tag.
<glob>::
@@ -97,7 +97,7 @@ displayed, indented N places. If a comm
branch, the I-th indentation character shows a `+` sign;
otherwise it shows a space. Merge commits are denoted by
a `-` sign. Each commit shows a short name that
-can be used as an extended SHA1 to name that commit.
+can be used as an extended SHA-1 to name that commit.
The following example shows three branches, "master", "fixes"
and "mhf":
diff --git a/Documentation/git-show-index.txt b/Documentation/git-show-index.txt
index be09b62..04f1d22 100644
--- a/Documentation/git-show-index.txt
+++ b/Documentation/git-show-index.txt
@@ -18,7 +18,7 @@ git-pack-objects command, and dumps its
The information it outputs is subset of what you can get from
'git-verify-pack -v'; this command only shows the packfile
-offset and SHA1 of each object.
+offset and SHA-1 of each object.
Author
diff --git a/Documentation/git-tag.txt b/Documentation/git-tag.txt
index 45476c2..f0f7d8c 100644
--- a/Documentation/git-tag.txt
+++ b/Documentation/git-tag.txt
@@ -24,7 +24,7 @@ creates a 'tag' object, and requires the
`-m <msg>` is given, an editor is started for the user to type
in the tag message.
-Otherwise just the SHA1 object name of the commit object is
+Otherwise just the SHA-1 object name of the commit object is
written (i.e. a lightweight tag).
A GnuPG signed tag object will be created when `-s` or `-u
diff --git a/Documentation/git-unpack-file.txt b/Documentation/git-unpack-file.txt
index 213dc81..c7b3be1 100644
--- a/Documentation/git-unpack-file.txt
+++ b/Documentation/git-unpack-file.txt
@@ -13,7 +13,7 @@ SYNOPSIS
DESCRIPTION
-----------
-Creates a file holding the contents of the blob specified by sha1. It
+Creates a file holding the contents of the blob specified by SHA-1. It
returns the name of the temporary file in the following format:
.merge_file_XXXXX
diff --git a/Documentation/git-update-index.txt b/Documentation/git-update-index.txt
index 3ae6e74..6135601 100644
--- a/Documentation/git-update-index.txt
+++ b/Documentation/git-update-index.txt
@@ -129,7 +129,7 @@ OPTIONS
Using --refresh
---------------
-'--refresh' does not calculate a new sha1 file or bring the index
+'--refresh' does not calculate a new SHA-1 file or bring the index
up-to-date for mode/content changes. But what it *does* do is to
"re-match" the stat information of a file with the index, so that you
can refresh the index for a file that hasn't been changed but where
@@ -144,10 +144,10 @@ Using --cacheinfo or --info-only
current working directory. This is useful for minimum-checkout
merging.
-To pretend you have a file with mode and sha1 at path, say:
+To pretend you have a file with mode and SHA-1 at path, say:
----------------
-$ git-update-index --cacheinfo mode sha1 path
+$ git-update-index --cacheinfo mode SHA-1 path
----------------
'--info-only' is used to register files without placing them in the object
@@ -167,19 +167,19 @@ Using --index-info
multiple entry definitions from the standard input, and designed
specifically for scripts. It can take inputs of three formats:
- . mode SP sha1 TAB path
+ . mode SP SHA-1 TAB path
+
The first format is what "git-apply --index-info"
reports, and used to reconstruct a partial tree
that is used for phony merge base tree when falling
back on 3-way merge.
- . mode SP type SP sha1 TAB path
+ . mode SP type SP SHA-1 TAB path
+
The second format is to stuff git-ls-tree output
into the index file.
- . mode SP sha1 SP stage TAB path
+ . mode SP SHA-1 SP stage TAB path
+
This format is to put higher order stages into the
index file and matches git-ls-files --stage output.
@@ -205,7 +205,7 @@ you can feed the following input to `--i
------------
The first line of the input feeds 0 as the mode to remove the
-path; the SHA1 does not matter as long as it is well formatted.
+path; the SHA-1 does not matter as long as it is well formatted.
Then the second and third line feeds stage 1 and stage 2 entries
for that path. After the above, we would end up with this:
diff --git a/Documentation/git-verify-pack.txt b/Documentation/git-verify-pack.txt
index 7a6132b..4fa5923 100644
--- a/Documentation/git-verify-pack.txt
+++ b/Documentation/git-verify-pack.txt
@@ -32,11 +32,11 @@ OUTPUT FORMAT
-------------
When specifying the -v option the format used is:
- SHA1 type size offset-in-packfile
+ SHA-1 type size offset-in-packfile
for objects that are not deltified in the pack, and
- SHA1 type size offset-in-packfile depth base-SHA1
+ SHA-1 type size offset-in-packfile depth base-SHA1
for objects that are deltified.
diff --git a/Documentation/git-verify-tag.txt b/Documentation/git-verify-tag.txt
index 0f9bdb5..d610a8b 100644
--- a/Documentation/git-verify-tag.txt
+++ b/Documentation/git-verify-tag.txt
@@ -16,7 +16,7 @@ Validates the gpg signature created by g
OPTIONS
-------
<tag>::
- SHA1 identifier of a git tag object.
+ SHA-1 identifier of a git tag object.
Author
------
diff --git a/Documentation/git.txt b/Documentation/git.txt
index d4472b5..2d454f8 100644
--- a/Documentation/git.txt
+++ b/Documentation/git.txt
@@ -585,7 +585,7 @@ git so take care if using Cogito etc.
'GIT_OBJECT_DIRECTORY'::
If the object storage directory is specified via this
- environment variable then the sha1 directories are created
+ environment variable then the SHA-1 directories are created
underneath - otherwise the default `$GIT_DIR/objects`
directory is used.
diff --git a/Documentation/glossary.txt b/Documentation/glossary.txt
index 116ddb7..e83cd42 100644
--- a/Documentation/glossary.txt
+++ b/Documentation/glossary.txt
@@ -163,7 +163,7 @@ merge::
object::
The unit of storage in git. It is uniquely identified by
- the SHA1 of its contents. Consequently, an object can not
+ the SHA-1 of its contents. Consequently, an object can not
be changed.
object database::
@@ -243,7 +243,7 @@ rebase::
changes from that branch.
ref::
- A 40-byte hex representation of a SHA1 or a name that denotes
+ A 40-byte hex representation of a SHA-1 or a name that denotes
a particular object. These may be stored in `$GIT_DIR/refs/`.
refspec::
diff --git a/Documentation/tutorial-2.txt b/Documentation/tutorial-2.txt
index 894ca5e..0dc91e7 100644
--- a/Documentation/tutorial-2.txt
+++ b/Documentation/tutorial-2.txt
@@ -32,9 +32,9 @@ with?
We saw in part one of the tutorial that commits have names like this.
It turns out that every object in the git history is stored under
-such a 40-digit hex name. That name is the SHA1 hash of the object's
+such a 40-digit hex name. That name is the SHA-1 hash of the object's
contents; among other things, this ensures that git will never store
-the same data twice (since identical data is given an identical SHA1
+the same data twice (since identical data is given an identical SHA-1
name), and that the contents of a git object will never change (since
that would change the object's name as well).
@@ -51,14 +51,14 @@ A tree can refer to one or more "blob" o
a file. In addition, a tree can also refer to other tree objects,
thus creating a directory hierarchy. You can examine the contents of
any tree using ls-tree (remember that a long enough initial portion
-of the SHA1 will also work):
+of the SHA-1 will also work):
------------------------------------------------
$ git ls-tree 92b8b694
100644 blob 3b18e512dba79e4c8300dd08aeb37f8e728b8dad file.txt
------------------------------------------------
-Thus we see that this tree has one file in it. The SHA1 hash is a
+Thus we see that this tree has one file in it. The SHA-1 hash is a
reference to that file's data:
------------------------------------------------
@@ -77,7 +77,7 @@ Note that this is the old file data; so
its response to the initial tree was a tree with a snapshot of the
directory state that was recorded by the first commit.
-All of these objects are stored under their SHA1 names inside the git
+All of these objects are stored under their SHA-1 names inside the git
directory:
------------------------------------------------
@@ -114,7 +114,7 @@ ref: refs/heads/master
As you can see, this tells us which branch we're currently on, and it
tells us this by naming a file under the .git directory, which itself
-contains a SHA1 name referring to a commit object, which we can
+contains a SHA-1 name referring to a commit object, which we can
examine with cat-file:
------------------------------------------------
@@ -180,7 +180,7 @@ project's history:
Note, by the way, that lots of commands take a tree as an argument.
But as we can see above, a tree can be referred to in many different
-ways--by the SHA1 name for that tree, by the name of a commit that
+ways--by the SHA-1 name for that tree, by the name of a commit that
refers to the tree, by the name of a branch whose head refers to that
tree, etc.--and most such commands can accept any of these names.
--
1.4.0.g1b2d
^ permalink raw reply related [relevance 1%]
* Re: [RFC] GIT user survey
@ 2006-06-29 9:49 4% ` Jakub Narebski
0 siblings, 0 replies; 200+ results
From: Jakub Narebski @ 2006-06-29 9:49 UTC (permalink / raw)
To: git
Matthias Kestenholz <lists@spinlock.ch> wrote:
> Adrien Beau (adrienbeau@gmail.com) wrote:
>>
>> The results of the Mercurial survey have been posted there:
>> http://www.selenic.com/mercurial/wiki/index.cgi/UserSurvey
>>
>> An interesting read.
>
> I find the answers to the question, what people most like to see
> improved interesting: The improvement which got mentioned most often
> was "merge across rename", something which git does already.
>
> It seems, that partial checkouts and truncated history are the
> only things left to implement for git from this list.
I think that at least some of the infrastructure for partial checkouts
is in place due to preliminary work for subproject (gitlink or bind)
support in git: git-read-tree and git-write-tree --prefix=<prefix>/
option suppport. But I might be mistaken.
Truncating history "by hand" is possible even now, using graft file.
There is recurring talk about "shallow clones", lately about "lazy clones".
There were mentioned here also split-history idea and sparse clone idea.
--
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git
^ permalink raw reply [relevance 4%]
* Re: Java GIT/Eclipse GIT version 0.1.1
@ 2006-07-28 6:49 1% ` Peter Baumann
2006-07-28 7:08 1% ` Pavel Roskin
0 siblings, 1 reply; 200+ results
From: Peter Baumann @ 2006-07-28 6:49 UTC (permalink / raw)
To: git
On 2006-07-28, Shawn Pearce <spearce@spearce.org> wrote:
> My Java GIT library and Eclipse GIT team provider is now at a point
> where it may be partially useful to someone else who is also trying
> to write something which interacts with GIT. Or who might also
> be interested in seeing a pure-Java Eclipse team provider for GIT.
>
> So I've posted my repository (currently ~200 KB) on my website:
>
> http://www.spearce.org/projects/scm/egit.git
>
Doesn't work for me.
devil:~/src git clone http://www.spearce.org/projects/scm/egit.git
error: File ac32c7cc2f7cf87a1ed80d0cdfca2af2a0385bb2 (http://www.spearce.org/projects/scm/egit.git/objects/ac/32c7cc2f7cf87a1ed80d0cdfca2af2a0385bb2) corrupt
Getting pack list for http://www.spearce.org/projects/scm/egit.git/
Getting alternates list for http://www.spearce.org/projects/scm/egit.git/
Also look at <html xmlns="http://www.w3.org/1999/
Also look at <title>Insufficiently Random: The lonely musings of a loosely connected software developer.<
Also look at @import url( http://www.spearce.org/wordpress/wp-content/themes/ir-classic/style
Also look at <link rel="pingback" href="http://www.spearce.org/wordpress/xmlrpc.
Also look at <link rel='archives' title='April 2006' href='http://www.spearce.org/2006/
Also look at <link rel='archives' title='February 2006' href='http://www.spearce.org/2006/
[...]
Also look at <li><a href="feed:http://www.spearce.org/comments/feed/" title="The latest comments to all posts in RSS">Comments <abbr title="Really Simple Syndication">RSS</abbr></
*** glibc detected *** double free or corruption (!prev): 0x080933b0 ***
/usr/bin/git-clone: line 29: 10712 Aborted git-http-fetch -v -a -w "$tname" "$name" "$1/"
-Peter
^ permalink raw reply [relevance 1%]
* Re: Java GIT/Eclipse GIT version 0.1.1
2006-07-28 6:49 1% ` Peter Baumann
@ 2006-07-28 7:08 1% ` Pavel Roskin
2006-07-28 7:23 0% ` Peter Baumann
2006-07-29 3:32 1% ` Shawn Pearce
0 siblings, 2 replies; 200+ results
From: Pavel Roskin @ 2006-07-28 7:08 UTC (permalink / raw)
To: Peter Baumann; +Cc: git
Quoting Peter Baumann <Peter.B.Baumann@stud.informatik.uni-erlangen.de>:
> On 2006-07-28, Shawn Pearce <spearce@spearce.org> wrote:
> > My Java GIT library and Eclipse GIT team provider is now at a point
> > where it may be partially useful to someone else who is also trying
> > to write something which interacts with GIT. Or who might also
> > be interested in seeing a pure-Java Eclipse team provider for GIT.
> >
> > So I've posted my repository (currently ~200 KB) on my website:
> >
> > http://www.spearce.org/projects/scm/egit.git
> >
>
> Doesn't work for me.
Neither does it for me:
$ git clone http://www.spearce.org/projects/scm/egit.git
error: File ac32c7cc2f7cf87a1ed80d0cdfca2af2a0385bb2
(http://www.spearce.org/projects/scm/egit.git/objects/ac/32c7cc2f7cf87a1ed80d0cdfca2af2a0385bb2)
corrupt
Getting pack list for http://www.spearce.org/projects/scm/egit.git/
error: XML error: not well-formed (invalid token)
> *** glibc detected *** double free or corruption (!prev): 0x080933b0 ***
> /usr/bin/git-clone: line 29: 10712 Aborted git-http-fetch -v
> -a -w "$tname" "$name" "$1/"
I'm not getting that. I hope you are just using an obsolete version of git.
--
Regards,
Pavel Roskin
^ permalink raw reply [relevance 1%]
* Re: Java GIT/Eclipse GIT version 0.1.1
2006-07-28 7:08 1% ` Pavel Roskin
@ 2006-07-28 7:23 0% ` Peter Baumann
2006-07-29 3:32 1% ` Shawn Pearce
1 sibling, 0 replies; 200+ results
From: Peter Baumann @ 2006-07-28 7:23 UTC (permalink / raw)
To: git
On 2006-07-28, Pavel Roskin <proski@gnu.org> wrote:
> Quoting Peter Baumann <Peter.B.Baumann@stud.informatik.uni-erlangen.de>:
>
>> On 2006-07-28, Shawn Pearce <spearce@spearce.org> wrote:
>> > My Java GIT library and Eclipse GIT team provider is now at a point
>> > where it may be partially useful to someone else who is also trying
>> > to write something which interacts with GIT. Or who might also
>> > be interested in seeing a pure-Java Eclipse team provider for GIT.
>> >
>> > So I've posted my repository (currently ~200 KB) on my website:
>> >
>> > http://www.spearce.org/projects/scm/egit.git
>> >
>>
>> Doesn't work for me.
>
> Neither does it for me:
>
> $ git clone http://www.spearce.org/projects/scm/egit.git
> error: File ac32c7cc2f7cf87a1ed80d0cdfca2af2a0385bb2
> (http://www.spearce.org/projects/scm/egit.git/objects/ac/32c7cc2f7cf87a1ed80d0cdfca2af2a0385bb2)
> corrupt
> Getting pack list for http://www.spearce.org/projects/scm/egit.git/
> error: XML error: not well-formed (invalid token)
>
>> *** glibc detected *** double free or corruption (!prev): 0x080933b0 ***
>> /usr/bin/git-clone: line 29: 10712 Aborted git-http-fetch -v
>> -a -w "$tname" "$name" "$1/"
>
> I'm not getting that. I hope you are just using an obsolete version of git.
Not _that_ old, me thinks. I'm using the debian unstable version.
devil:~ dpkg -l |grep git-core
ii git-core 1.4.1-1 content addressable filesystem
(Yes, I'am aware that this version has the timing bug on the server
side, but I was just too lazy to compile git myself this time :-)
-Peter
^ permalink raw reply [relevance 0%]
* Re: Java GIT/Eclipse GIT version 0.1.1
2006-07-28 7:08 1% ` Pavel Roskin
2006-07-28 7:23 0% ` Peter Baumann
@ 2006-07-29 3:32 1% ` Shawn Pearce
1 sibling, 0 replies; 200+ results
From: Shawn Pearce @ 2006-07-29 3:32 UTC (permalink / raw)
To: Pavel Roskin; +Cc: Peter Baumann, git
Pavel Roskin <proski@gnu.org> wrote:
> Quoting Peter Baumann <Peter.B.Baumann@stud.informatik.uni-erlangen.de>:
>
> > On 2006-07-28, Shawn Pearce <spearce@spearce.org> wrote:
> > > My Java GIT library and Eclipse GIT team provider is now at a point
> > > where it may be partially useful to someone else who is also trying
> > > to write something which interacts with GIT. Or who might also
> > > be interested in seeing a pure-Java Eclipse team provider for GIT.
> > >
> > > So I've posted my repository (currently ~200 KB) on my website:
> > >
> > > http://www.spearce.org/projects/scm/egit.git
> > >
> >
> > Doesn't work for me.
>
> Neither does it for me:
>
> $ git clone http://www.spearce.org/projects/scm/egit.git
> error: File ac32c7cc2f7cf87a1ed80d0cdfca2af2a0385bb2
> (http://www.spearce.org/projects/scm/egit.git/objects/ac/32c7cc2f7cf87a1ed80d0cdfca2af2a0385bb2)
> corrupt
> Getting pack list for http://www.spearce.org/projects/scm/egit.git/
> error: XML error: not well-formed (invalid token)
Hmm. My website is known to return 200 OK status codes on missing
files with HTML pages rather than proper 404 Not Found. I guess
I need to get that fixed.
I just compiled and installed `next` (1.4.2.rc1.g802da) and it can
clone this repository just fine over HTTP, despite my broken server.
So I'm not really sure what is going on.
I should look into fixing my server, but its low on my priority list.
--
Shawn.
^ permalink raw reply [relevance 1%]
* [PATCH] Workaround for strange cmp bug
@ 2006-08-09 10:24 2% Johannes Schindelin
0 siblings, 0 replies; 200+ results
From: Johannes Schindelin @ 2006-08-09 10:24 UTC (permalink / raw)
To: git, junkio
The cmp(1) (cmp (GNU diffutils) 2.8.7) distributed with openSUSE 10.1 has
a subtle "shortcoming":
$ echo a > a
$ echo b > b
$ cmp a b && echo nonono
a b differ: char 1, line 1
$ cmp a b >/dev/null && echo nonono
nonono
$ cmp -s a b >/dev/null && echo nonono
So, if cmp should _not_ be quiet, _and_ the output is redirected to
/dev/null, it has a bogus exit value. Our test suite redirects to
/dev/null, which triggers that bug. (Obviously, the tests pass when
running with '-v', which made that a real bugger to debug.)
Since we have all too many '&&' cascades in the test scripts, and you
have to run 'bash -x t*.sh' anyway, the output of cmp when running
the tests with '-v' is not too helpful. Therefore we can replace all
calls to cmp with 'cmp -s'.
This patch was produced by
$ perl -i.bak -pe 's/cmp ([^-])/cmp -s $1/' t/*.sh
Signed-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
---
t/t1002-read-tree-m-u-2way.sh | 32 +++++++++++++++---------------
t/t1003-read-tree-prefix.sh | 2 +-
t/t1020-subdirectory.sh | 16 ++++++++-------
t/t1200-tutorial.sh | 22 ++++++++++-----------
t/t1300-repo-config.sh | 40 +++++++++++++++++++-------------------
t/t2101-update-index-reupdate.sh | 12 ++++++-----
t/t3300-funny-names.sh | 2 +-
t/t4012-diff-binary.sh | 4 ++--
t/t4109-apply-multifrag.sh | 12 ++++++-----
t/t4110-apply-scan.sh | 2 +-
t/t5300-pack-object.sh | 12 ++++++-----
t/t5400-send-pack.sh | 4 ++--
t/t6021-merge-criss-cross.sh | 2 +-
t/t9101-git-svn-props.sh | 2 +-
t/t9105-git-svn-commit-diff.sh | 2 +-
15 files changed, 83 insertions(+), 83 deletions(-)
diff --git a/t/t1002-read-tree-m-u-2way.sh b/t/t1002-read-tree-m-u-2way.sh
index da3c813..6be4ee2 100755
--- a/t/t1002-read-tree-m-u-2way.sh
+++ b/t/t1002-read-tree-m-u-2way.sh
@@ -59,9 +59,9 @@ test_expect_success \
git-read-tree --reset -u $treeH &&
git-read-tree -m -u $treeH $treeM &&
git-ls-files --stage >1-3.out &&
- cmp M.out 1-3.out &&
+ cmp -s M.out 1-3.out &&
sum bozbar frotz nitfol >actual3.sum &&
- cmp M.sum actual3.sum &&
+ cmp -s M.sum actual3.sum &&
check_cache_at bozbar clean &&
check_cache_at frotz clean &&
check_cache_at nitfol clean'
@@ -79,7 +79,7 @@ test_expect_success \
compare_change 4diff.out expected &&
check_cache_at yomin clean &&
sum bozbar frotz nitfol >actual4.sum &&
- cmp M.sum actual4.sum &&
+ cmp -s M.sum actual4.sum &&
echo yomin >yomin1 &&
diff yomin yomin1 &&
rm -f yomin1'
@@ -98,7 +98,7 @@ test_expect_success \
compare_change 5diff.out expected &&
check_cache_at yomin dirty &&
sum bozbar frotz nitfol >actual5.sum &&
- cmp M.sum actual5.sum &&
+ cmp -s M.sum actual5.sum &&
: dirty index should have prevented -u from checking it out. &&
echo yomin yomin >yomin1 &&
diff yomin yomin1 &&
@@ -115,7 +115,7 @@ test_expect_success \
diff -U0 M.out 6.out &&
check_cache_at frotz clean &&
sum bozbar frotz nitfol >actual3.sum &&
- cmp M.sum actual3.sum &&
+ cmp -s M.sum actual3.sum &&
echo frotz >frotz1 &&
diff frotz frotz1 &&
rm -f frotz1'
@@ -132,7 +132,7 @@ test_expect_success \
diff -U0 M.out 7.out &&
check_cache_at frotz dirty &&
sum bozbar frotz nitfol >actual7.sum &&
- if cmp M.sum actual7.sum; then false; else :; fi &&
+ if cmp -s M.sum actual7.sum; then false; else :; fi &&
: dirty index should have prevented -u from checking it out. &&
echo frotz frotz >frotz1 &&
diff frotz frotz1 &&
@@ -163,9 +163,9 @@ test_expect_success \
git-update-index --add rezrov &&
git-read-tree -m -u $treeH $treeM &&
git-ls-files --stage >10.out &&
- cmp M.out 10.out &&
+ cmp -s M.out 10.out &&
sum bozbar frotz nitfol >actual10.sum &&
- cmp M.sum actual10.sum'
+ cmp -s M.sum actual10.sum'
test_expect_success \
'11 - dirty path removed.' \
@@ -210,9 +210,9 @@ test_expect_success \
compare_change 14diff.out expected &&
sum bozbar frotz >actual14.sum &&
grep -v nitfol M.sum > expected14.sum &&
- cmp expected14.sum actual14.sum &&
+ cmp -s expected14.sum actual14.sum &&
sum bozbar frotz nitfol >actual14a.sum &&
- if cmp M.sum actual14a.sum; then false; else :; fi &&
+ if cmp -s M.sum actual14a.sum; then false; else :; fi &&
check_cache_at nitfol clean &&
echo nitfol nitfol >nitfol1 &&
diff nitfol nitfol1 &&
@@ -232,9 +232,9 @@ test_expect_success \
check_cache_at nitfol dirty &&
sum bozbar frotz >actual15.sum &&
grep -v nitfol M.sum > expected15.sum &&
- cmp expected15.sum actual15.sum &&
+ cmp -s expected15.sum actual15.sum &&
sum bozbar frotz nitfol >actual15a.sum &&
- if cmp M.sum actual15a.sum; then false; else :; fi &&
+ if cmp -s M.sum actual15a.sum; then false; else :; fi &&
echo nitfol nitfol nitfol >nitfol1 &&
diff nitfol nitfol1 &&
rm -f nitfol1'
@@ -267,7 +267,7 @@ test_expect_success \
diff -U0 M.out 18.out &&
check_cache_at bozbar clean &&
sum bozbar frotz nitfol >actual18.sum &&
- cmp M.sum actual18.sum'
+ cmp -s M.sum actual18.sum'
test_expect_success \
'19 - local change already having a good result, further modified.' \
@@ -282,9 +282,9 @@ test_expect_success \
check_cache_at bozbar dirty &&
sum frotz nitfol >actual19.sum &&
grep -v bozbar M.sum > expected19.sum &&
- cmp expected19.sum actual19.sum &&
+ cmp -s expected19.sum actual19.sum &&
sum bozbar frotz nitfol >actual19a.sum &&
- if cmp M.sum actual19a.sum; then false; else :; fi &&
+ if cmp -s M.sum actual19a.sum; then false; else :; fi &&
echo gnusto gnusto >bozbar1 &&
diff bozbar bozbar1 &&
rm -f bozbar1'
@@ -300,7 +300,7 @@ test_expect_success \
diff -U0 M.out 20.out &&
check_cache_at bozbar clean &&
sum bozbar frotz nitfol >actual20.sum &&
- cmp M.sum actual20.sum'
+ cmp -s M.sum actual20.sum'
test_expect_success \
'21 - no local change, dirty cache.' \
diff --git a/t/t1003-read-tree-prefix.sh b/t/t1003-read-tree-prefix.sh
index 48ab117..a7156b2 100755
--- a/t/t1003-read-tree-prefix.sh
+++ b/t/t1003-read-tree-prefix.sh
@@ -21,7 +21,7 @@ two/one' >expect
test_expect_success 'read-tree --prefix' '
git-read-tree --prefix=two/ $tree &&
git-ls-files >actual &&
- cmp expect actual
+ cmp -s expect actual
'
test_done
diff --git a/t/t1020-subdirectory.sh b/t/t1020-subdirectory.sh
index 4409b87..8bd4174 100755
--- a/t/t1020-subdirectory.sh
+++ b/t/t1020-subdirectory.sh
@@ -46,10 +46,10 @@ test_expect_success 'cat-file' '
two=`expr "$two" : "[0-7]* \\([0-9a-f]*\\)"` &&
echo "$two" &&
git-cat-file -p "$two" >actual &&
- cmp dir/two actual &&
+ cmp -s dir/two actual &&
cd dir &&
git-cat-file -p "$two" >actual &&
- cmp two actual
+ cmp -s two actual
'
rm -f actual dir/actual
@@ -86,10 +86,10 @@ test_expect_success 'write-tree' '
test_expect_success 'checkout-index' '
cd $HERE &&
git-checkout-index -f -u one &&
- cmp one original.one &&
+ cmp -s one original.one &&
cd dir &&
git-checkout-index -f -u two &&
- cmp two ../original.two
+ cmp -s two ../original.two
'
test_expect_success 'read-tree' '
@@ -97,13 +97,13 @@ test_expect_success 'read-tree' '
rm -f one dir/two &&
tree=`git-write-tree` &&
git-read-tree --reset -u "$tree" &&
- cmp one original.one &&
- cmp dir/two original.two &&
+ cmp -s one original.one &&
+ cmp -s dir/two original.two &&
cd dir &&
rm -f two &&
git-read-tree --reset -u "$tree" &&
- cmp two ../original.two &&
- cmp ../one ../original.one
+ cmp -s two ../original.two &&
+ cmp -s ../one ../original.one
'
test_done
diff --git a/t/t1200-tutorial.sh b/t/t1200-tutorial.sh
index c7db20e..2e2a898 100755
--- a/t/t1200-tutorial.sh
+++ b/t/t1200-tutorial.sh
@@ -27,9 +27,9 @@ index 557db03..263414f 100644
+It's a new day for git
EOF
git-diff-files -p > diff.output
-test_expect_success 'git-diff-files -p' 'cmp diff.expect diff.output'
+test_expect_success 'git-diff-files -p' 'cmp -s diff.expect diff.output'
git diff > diff.output
-test_expect_success 'git diff' 'cmp diff.expect diff.output'
+test_expect_success 'git diff' 'cmp -s diff.expect diff.output'
tree=$(git-write-tree 2>/dev/null)
@@ -40,10 +40,10 @@ output="$(echo "Initial commit" | git-co
test_expect_success 'commit' "test 'Committing initial tree 8988da15d077d4829fc51d8544c097def6644dbb' = \"$output\""
git-diff-index -p HEAD > diff.output
-test_expect_success 'git-diff-index -p HEAD' 'cmp diff.expect diff.output'
+test_expect_success 'git-diff-index -p HEAD' 'cmp -s diff.expect diff.output'
git diff HEAD > diff.output
-test_expect_success 'git diff HEAD' 'cmp diff.expect diff.output'
+test_expect_success 'git diff HEAD' 'cmp -s diff.expect diff.output'
#rm hello
#test_expect_success 'git-read-tree --reset HEAD' "git-read-tree --reset HEAD ; test \"hello: needs update\" = \"$(git-update-index --refresh)\""
@@ -75,15 +75,15 @@ git-whatchanged -p --root | \
sed -e "1s/^\(.\{7\}\).\{40\}/\1VARIABLE/" \
-e "2,3s/^\(.\{8\}\).*$/\1VARIABLE/" \
> whatchanged.output
-test_expect_success 'git-whatchanged -p --root' 'cmp whatchanged.expect whatchanged.output'
+test_expect_success 'git-whatchanged -p --root' 'cmp -s whatchanged.expect whatchanged.output'
git tag my-first-tag
-test_expect_success 'git tag my-first-tag' 'cmp .git/refs/heads/master .git/refs/tags/my-first-tag'
+test_expect_success 'git tag my-first-tag' 'cmp -s .git/refs/heads/master .git/refs/tags/my-first-tag'
# TODO: test git-clone
git checkout -b mybranch
-test_expect_success 'git checkout -b mybranch' 'cmp .git/refs/heads/master .git/refs/heads/mybranch'
+test_expect_success 'git checkout -b mybranch' 'cmp -s .git/refs/heads/master .git/refs/heads/mybranch'
cat > branch.expect <<EOF
master
@@ -91,7 +91,7 @@ cat > branch.expect <<EOF
EOF
git branch > branch.output
-test_expect_success 'git branch' 'cmp branch.expect branch.output'
+test_expect_success 'git branch' 'cmp -s branch.expect branch.output'
git checkout mybranch
echo "Work, work, work" >>hello
@@ -125,7 +125,7 @@ cat > show-branch.expect << EOF
EOF
git show-branch --topo-order master mybranch > show-branch.output
-test_expect_success 'git show-branch' 'cmp show-branch.expect show-branch.output'
+test_expect_success 'git show-branch' 'cmp -s show-branch.expect show-branch.output'
git checkout mybranch
@@ -138,7 +138,7 @@ EOF
git resolve HEAD master "Merge upstream changes." | \
sed -e "1s/[0-9a-f]\{40\}/VARIABLE/g" > resolve.output
-test_expect_success 'git resolve' 'cmp resolve.expect resolve.output'
+test_expect_success 'git resolve' 'cmp -s resolve.expect resolve.output'
cat > show-branch2.expect << EOF
! [master] Merged "mybranch" changes.
@@ -148,7 +148,7 @@ cat > show-branch2.expect << EOF
EOF
git show-branch --topo-order master mybranch > show-branch2.output
-test_expect_success 'git show-branch' 'cmp show-branch2.expect show-branch2.output'
+test_expect_success 'git show-branch' 'cmp -s show-branch2.expect show-branch2.output'
# TODO: test git fetch
diff --git a/t/t1300-repo-config.sh b/t/t1300-repo-config.sh
index 0de2497..5af856d 100755
--- a/t/t1300-repo-config.sh
+++ b/t/t1300-repo-config.sh
@@ -16,7 +16,7 @@ cat > expect << EOF
penguin = little blue
EOF
-test_expect_success 'initial' 'cmp .git/config expect'
+test_expect_success 'initial' 'cmp -s .git/config expect'
git-repo-config Core.Movie BadPhysics
@@ -26,7 +26,7 @@ cat > expect << EOF
Movie = BadPhysics
EOF
-test_expect_success 'mixed case' 'cmp .git/config expect'
+test_expect_success 'mixed case' 'cmp -s .git/config expect'
git-repo-config Cores.WhatEver Second
@@ -38,7 +38,7 @@ cat > expect << EOF
WhatEver = Second
EOF
-test_expect_success 'similar section' 'cmp .git/config expect'
+test_expect_success 'similar section' 'cmp -s .git/config expect'
git-repo-config CORE.UPPERCASE true
@@ -51,7 +51,7 @@ cat > expect << EOF
WhatEver = Second
EOF
-test_expect_success 'similar section' 'cmp .git/config expect'
+test_expect_success 'similar section' 'cmp -s .git/config expect'
test_expect_success 'replace with non-match' \
'git-repo-config core.penguin kingpin !blue'
@@ -69,7 +69,7 @@ cat > expect << EOF
WhatEver = Second
EOF
-test_expect_success 'non-match result' 'cmp .git/config expect'
+test_expect_success 'non-match result' 'cmp -s .git/config expect'
cat > .git/config << EOF
[beta] ; silly comment # another comment
@@ -97,7 +97,7 @@ # empty line
[nextSection] noNewline = ouch
EOF
-test_expect_success 'multiple unset is correct' 'cmp .git/config expect'
+test_expect_success 'multiple unset is correct' 'cmp -s .git/config expect'
mv .git/config2 .git/config
@@ -114,7 +114,7 @@ # empty line
[nextSection] noNewline = ouch
EOF
-test_expect_success 'all replaced' 'cmp .git/config expect'
+test_expect_success 'all replaced' 'cmp -s .git/config expect'
git-repo-config beta.haha alpha
@@ -128,7 +128,7 @@ # empty line
[nextSection] noNewline = ouch
EOF
-test_expect_success 'really mean test' 'cmp .git/config expect'
+test_expect_success 'really mean test' 'cmp -s .git/config expect'
git-repo-config nextsection.nonewline wow
@@ -143,7 +143,7 @@ # empty line
nonewline = wow
EOF
-test_expect_success 'really really mean test' 'cmp .git/config expect'
+test_expect_success 'really really mean test' 'cmp -s .git/config expect'
test_expect_success 'get value' 'test alpha = $(git-repo-config beta.haha)'
git-repo-config --unset beta.haha
@@ -158,7 +158,7 @@ # empty line
nonewline = wow
EOF
-test_expect_success 'unset' 'cmp .git/config expect'
+test_expect_success 'unset' 'cmp -s .git/config expect'
git-repo-config nextsection.NoNewLine "wow2 for me" "for me$"
@@ -173,7 +173,7 @@ # empty line
NoNewLine = wow2 for me
EOF
-test_expect_success 'multivar' 'cmp .git/config expect'
+test_expect_success 'multivar' 'cmp -s .git/config expect'
test_expect_success 'non-match' \
'git-repo-config --get nextsection.nonewline !for'
@@ -200,7 +200,7 @@ # empty line
NoNewLine = wow2 for me
EOF
-test_expect_success 'multivar replace' 'cmp .git/config expect'
+test_expect_success 'multivar replace' 'cmp -s .git/config expect'
test_expect_failure 'ambiguous value' 'git-repo-config nextsection.nonewline'
@@ -222,7 +222,7 @@ # empty line
NoNewLine = wow2 for me
EOF
-test_expect_success 'multivar unset' 'cmp .git/config expect'
+test_expect_success 'multivar unset' 'cmp -s .git/config expect'
test_expect_failure 'invalid key' 'git-repo-config inval.2key blabla'
@@ -245,7 +245,7 @@ # empty line
Alpha = beta
EOF
-test_expect_success 'hierarchical section value' 'cmp .git/config expect'
+test_expect_success 'hierarchical section value' 'cmp -s .git/config expect'
cat > expect << EOF
beta.noindent=sillyValue
@@ -255,7 +255,7 @@ version.1.2.3eX.alpha=beta
EOF
test_expect_success 'working --list' \
- 'git-repo-config --list > output && cmp output expect'
+ 'git-repo-config --list > output && cmp -s output expect'
cat > expect << EOF
beta.noindent sillyValue
@@ -263,7 +263,7 @@ nextsection.nonewline wow2 for me
EOF
test_expect_success '--get-regexp' \
- 'git-repo-config --get-regexp in > output && cmp output expect'
+ 'git-repo-config --get-regexp in > output && cmp -s output expect'
cat > .git/config << EOF
[novalue]
@@ -292,7 +292,7 @@ cat > expect << EOF
x = y
EOF
-test_expect_success 'new section is partial match of another' 'cmp .git/config expect'
+test_expect_success 'new section is partial match of another' 'cmp -s .git/config expect'
git-repo-config b.x y
git-repo-config a.b c
@@ -307,7 +307,7 @@ cat > expect << EOF
x = y
EOF
-test_expect_success 'new variable inserts into proper section' 'cmp .git/config expect'
+test_expect_success 'new variable inserts into proper section' 'cmp -s .git/config expect'
cat > other-config << EOF
[ein]
@@ -320,7 +320,7 @@ EOF
GIT_CONFIG=other-config git-repo-config -l > output
-test_expect_success 'alternative GIT_CONFIG' 'cmp output expect'
+test_expect_success 'alternative GIT_CONFIG' 'cmp -s output expect'
GIT_CONFIG=other-config git-repo-config anwohner.park ausweis
@@ -331,7 +331,7 @@ cat > expect << EOF
park = ausweis
EOF
-test_expect_success '--set in alternative GIT_CONFIG' 'cmp other-config expect'
+test_expect_success '--set in alternative GIT_CONFIG' 'cmp -s other-config expect'
test_done
diff --git a/t/t2101-update-index-reupdate.sh b/t/t2101-update-index-reupdate.sh
index a78ea7f..bc452c4 100755
--- a/t/t2101-update-index-reupdate.sh
+++ b/t/t2101-update-index-reupdate.sh
@@ -17,7 +17,7 @@ test_expect_success 'update-index --add'
echo goodbye people >file2 &&
git-update-index --add file1 file2 &&
git-ls-files -s >current &&
- cmp current expected'
+ cmp -s current expected'
test_expect_success 'update-index --again' \
'rm -f file1 &&
@@ -30,7 +30,7 @@ test_expect_success 'update-index --agai
echo happy - failed as expected
fi &&
git-ls-files -s >current &&
- cmp current expected'
+ cmp -s current expected'
cat > expected <<\EOF
100644 0f1ae1422c2bf43f117d3dbd715c988a9ed2103f 0 file2
@@ -38,7 +38,7 @@ EOF
test_expect_success 'update-index --remove --again' \
'git-update-index --remove --again &&
git-ls-files -s >current &&
- cmp current expected'
+ cmp -s current expected'
test_expect_success 'first commit' 'git-commit -m initial'
@@ -55,7 +55,7 @@ test_expect_success 'update-index again'
echo happy >dir1/file3 &&
git-update-index --again &&
git-ls-files -s >current &&
- cmp current expected'
+ cmp -s current expected'
cat > expected <<\EOF
100644 d7fb3f695f06c759dbf3ab00046e7cc2da22d10f 0 dir1/file3
@@ -68,7 +68,7 @@ test_expect_success 'update-index --upda
git-update-index --again &&
cd .. &&
git-ls-files -s >current &&
- cmp current expected'
+ cmp -s current expected'
cat > expected <<\EOF
100644 594fb5bb1759d90998e2bf2a38261ae8e243c760 0 dir1/file3
@@ -79,6 +79,6 @@ test_expect_success 'update-index --upda
cat file2 >dir1/file3 &&
git-update-index --again dir1/ &&
git-ls-files -s >current &&
- cmp current expected'
+ cmp -s current expected'
test_done
diff --git a/t/t3300-funny-names.sh b/t/t3300-funny-names.sh
index c12270e..d2c1af8 100755
--- a/t/t3300-funny-names.sh
+++ b/t/t3300-funny-names.sh
@@ -24,7 +24,7 @@ EOF
cat >"$p1" "$p0"
echo 'Foo Bar Baz' >"$p2"
-test -f "$p1" && cmp "$p0" "$p1" || {
+test -f "$p1" && cmp -s "$p0" "$p1" || {
# since FAT/NTFS does not allow tabs in filenames, skip this test
say 'Your filesystem does not allow tabs in filenames, test skipped.'
test_done
diff --git a/t/t4012-diff-binary.sh b/t/t4012-diff-binary.sh
index 323606c..0ff3c4d 100755
--- a/t/t4012-diff-binary.sh
+++ b/t/t4012-diff-binary.sh
@@ -25,11 +25,11 @@ cat > expected <<\EOF
EOF
test_expect_success 'diff without --binary' \
'git-diff | git-apply --stat --summary >current &&
- cmp current expected'
+ cmp -s current expected'
test_expect_success 'diff with --binary' \
'git-diff --binary | git-apply --stat --summary >current &&
- cmp current expected'
+ cmp -s current expected'
# apply needs to be able to skip the binary material correctly
# in order to report the line number of a corrupt patch.
diff --git a/t/t4109-apply-multifrag.sh b/t/t4109-apply-multifrag.sh
index 5988e1a..85ef40e 100755
--- a/t/t4109-apply-multifrag.sh
+++ b/t/t4109-apply-multifrag.sh
@@ -145,8 +145,8 @@ mv main.c main.c.git
test_expect_success "S = patch (1)" \
'cat patch1.patch patch2.patch | patch -p1'
-test_expect_success "S = cmp (1)" \
- 'cmp main.c.git main.c'
+test_expect_success "S = cmp -s (1)" \
+ 'cmp -s main.c.git main.c'
rm -f main.c main.c.git
@@ -157,8 +157,8 @@ mv main.c main.c.git
test_expect_success "S = patch (2)" \
'cat patch1.patch patch2.patch patch3.patch | patch -p1'
-test_expect_success "S = cmp (2)" \
- 'cmp main.c.git main.c'
+test_expect_success "S = cmp -s (2)" \
+ 'cmp -s main.c.git main.c'
rm -f main.c main.c.git
@@ -169,8 +169,8 @@ mv main.c main.c.git
test_expect_success "S = patch (3)" \
'cat patch1.patch patch4.patch | patch -p1'
-test_expect_success "S = cmp (3)" \
- 'cmp main.c.git main.c'
+test_expect_success "S = cmp -s (3)" \
+ 'cmp -s main.c.git main.c'
test_done
diff --git a/t/t4110-apply-scan.sh b/t/t4110-apply-scan.sh
index 005f744..3c767a4 100755
--- a/t/t4110-apply-scan.sh
+++ b/t/t4110-apply-scan.sh
@@ -95,7 +95,7 @@ test_expect_success "S = patch scan" \
mv new.txt patch.txt
test_expect_success "S = cmp" \
- 'cmp apply.txt patch.txt'
+ 'cmp -s apply.txt patch.txt'
test_done
diff --git a/t/t5300-pack-object.sh b/t/t5300-pack-object.sh
index de45ac4..5564162 100755
--- a/t/t5300-pack-object.sh
+++ b/t/t5300-pack-object.sh
@@ -56,7 +56,7 @@ test_expect_success \
'(cd ../.git && find objects -type f -print) |
while read path
do
- cmp $path ../.git/$path || {
+ cmp -s $path ../.git/$path || {
echo $path differs.
return 1
}
@@ -86,7 +86,7 @@ test_expect_success \
'(cd ../.git && find objects -type f -print) |
while read path
do
- cmp $path ../.git/$path || {
+ cmp -s $path ../.git/$path || {
echo $path differs.
return 1
}
@@ -182,17 +182,17 @@ test_expect_success \
'build pack index for an existing pack' \
'cp test-1-${packname_1}.pack test-3.pack &&
git-index-pack -o tmp.idx test-3.pack &&
- cmp tmp.idx test-1-${packname_1}.idx &&
+ cmp -s tmp.idx test-1-${packname_1}.idx &&
git-index-pack test-3.pack &&
- cmp test-3.idx test-1-${packname_1}.idx &&
+ cmp -s test-3.idx test-1-${packname_1}.idx &&
cp test-2-${packname_2}.pack test-3.pack &&
git-index-pack -o tmp.idx test-2-${packname_2}.pack &&
- cmp tmp.idx test-2-${packname_2}.idx &&
+ cmp -s tmp.idx test-2-${packname_2}.idx &&
git-index-pack test-3.pack &&
- cmp test-3.idx test-2-${packname_2}.idx &&
+ cmp -s test-3.idx test-2-${packname_2}.idx &&
:'
diff --git a/t/t5400-send-pack.sh b/t/t5400-send-pack.sh
index f3694ac..cb32283 100755
--- a/t/t5400-send-pack.sh
+++ b/t/t5400-send-pack.sh
@@ -52,7 +52,7 @@ test_expect_success \
echo >&2 Thanks, it correctly failed.
true
fi &&
- if cmp victim/.git/refs/heads/master .git/refs/heads/master
+ if cmp -s victim/.git/refs/heads/master .git/refs/heads/master
then
# should have been left as it was!
false
@@ -61,7 +61,7 @@ test_expect_success \
fi &&
# this should update
git-send-pack --force ./victim/.git/ master &&
- cmp victim/.git/refs/heads/master .git/refs/heads/master
+ cmp -s victim/.git/refs/heads/master .git/refs/heads/master
'
test_done
diff --git a/t/t6021-merge-criss-cross.sh b/t/t6021-merge-criss-cross.sh
index 8f7366d..97e85b9 100755
--- a/t/t6021-merge-criss-cross.sh
+++ b/t/t6021-merge-criss-cross.sh
@@ -93,6 +93,6 @@ cat > file-expect <<EOF
9
EOF
-test_expect_success 'Criss-cross merge result' 'cmp file file-expect'
+test_expect_success 'Criss-cross merge result' 'cmp -s file file-expect'
test_done
diff --git a/t/t9101-git-svn-props.sh b/t/t9101-git-svn-props.sh
index a5a235f..e19c3df 100755
--- a/t/t9101-git-svn-props.sh
+++ b/t/t9101-git-svn-props.sh
@@ -97,7 +97,7 @@ test_expect_success 'fetch and pull late
for i in crlf ne_crlf lf ne_lf cr ne_cr empty_cr empty_lf empty empty_crlf
do
- test_expect_success "Comparing $i" "cmp $i new_wc/$i"
+ test_expect_success "Comparing $i" "cmp -s $i new_wc/$i"
done
diff --git a/t/t9105-git-svn-commit-diff.sh b/t/t9105-git-svn-commit-diff.sh
index f994b72..315bdd3 100755
--- a/t/t9105-git-svn-commit-diff.sh
+++ b/t/t9105-git-svn-commit-diff.sh
@@ -35,7 +35,7 @@ test_expect_success 'test the commit-dif
test -n '$prev' && test -n '$head' &&
git-svn commit-diff '$prev' '$head' '$svnrepo' &&
svn co $svnrepo wc &&
- cmp readme wc/readme
+ cmp -s readme wc/readme
"
test_done
--
1.4.2.rc3.ge5673-dirty
^ permalink raw reply related [relevance 2%]
* Re: Compression and dictionaries
@ 2006-08-14 15:26 1% ` Johannes Schindelin
0 siblings, 0 replies; 200+ results
From: Johannes Schindelin @ 2006-08-14 15:26 UTC (permalink / raw)
To: Alex Riesen; +Cc: Jon Smirl, git
Hi,
On Mon, 14 Aug 2006, Alex Riesen wrote:
> On 8/14/06, Jon Smirl <jonsmirl@gmail.com> wrote:
> > Changing the probabilities probably won't help much, but there may be
> > good gains from partially eliminating 1M encoding maps.
>
> will the old git installations, without the maps, still be able to decode the
> pack created this way?
Probably not. But then, I would _not_ want this in upload-pack, so it is a
strictly local thing -- either you repacked with a dictionary yourself, or
there would be no explicit dictionary.
However, as I said, I _think_ this discussion is moot. You'd probably be
better off making the windows wider, activating stronger compression,
basically investing more time for the repacker. Plus, this would benefit
cloned repos as well.
Ciao,
Dscho
^ permalink raw reply [relevance 1%]
* Re: git clone dies (large git repository)
@ 2006-08-19 20:46 4% ` Junio C Hamano
0 siblings, 0 replies; 200+ results
From: Junio C Hamano @ 2006-08-19 20:46 UTC (permalink / raw)
To: Troy Telford; +Cc: git
"Troy Telford" <ttelford@linuxnetworx.com> writes:
> I originally had everything as loose objects. I then ran 'git-repack
> -d' on occasion, so I had a combination of a large pack file, smaller
> pack files, and loose objects. Finally, I tried 'git repack -a -d'
> and consolidated it all into a single 4GB pack file. It didn't seem
> to make much difference in the output.
>
> Am I bumping some sort of limitation within git, or have I uncovered a bug?
The former. Unfortunately this comes from an old design
decision.
Fortunately this design decision is not something irreversible
(see Chapter 1 of Documentation/ManagementStyle in the kernel
repository ;-).
The packfile is a dual-use format. When used for network
transfer, we only send the .pack file and have the recipient
reconstruct the corresponding .idx file. When used locally, we
need both .pack and .idx file; .pack contains the meat of the
data, and .idx allows us random access to the objects stored in
the corresponding .pack file.
What is interesting is that .pack format does not have (as far
as I know) inherent size limitation. However, .idx file has
hardcoded 32-bit offsets into .pack -- hence, in practice, you
cannot use a .pack that is over 4GB locally.
One crude workaround that would work _today_ for your situation
without changing file formats would be to use git-fetch into an
empty repository (and do ref cloning by hand) instead of using
git-clone. git-fetch gets .pack data over the wire and explode
the objects contained in the stream into individual objects (as
opposed to git-clone gets .pack data, stores it as a .pack and
tries to create corresponding .idx which in your case would bust
the 32-bit limit and fail).
This is from a private note I sent to Linus on Jun 26 2005 when
pack & idx pairs were initially introduced.
- Design decision. As before, you have assumption that nothing
is longer than 2^32 bytes. I am not unhappy with that
restriction with individual objects (even their uncompressed
size limited below 4GB or even 2GB is fine --- after all we
are talking about a source control system). I am however
wondering if we would regret it later to have a packed file
also limited to 4GB by having object_entry.offset "unsigned
long" (and fwrite htonl'ed 4 bytes). I personally do not
have problem with this, but I can easily see HPA frowning on
us. He didn't like it when I said "in GIT world, file sizes
and offsets are of type 'unsigned long'" some time ago.
I do not have a copy of a response from Linus to this point, but
if I recall things correctly, since then, the plan always has
been (1) to limit the size of individual packfiles to fit within
the idx limit and/or (2) extend the idx format to be able to
express offset over 2^32. The latter is possible because idx
file is a local matter, used only for local accesses and does
not get set over the wire.
However, even if we revise the .idx file format, we have another
practical problem to solve. Currently we assume that we can mmap
one packfile as a whole and do a random access into it. This
needs to be changed so that we (perhaps optionally, only when
dealing with a huge packfile) mmap part of a .pack at a time.
I recall more recently (as opposed to the heated discussion
immediately after packfile was introduced June last year) we had
another discussion about people not being able to mmap huge
packfiles, and partial mmapping was one of the things that were
discussed there.
^ permalink raw reply [relevance 4%]
* [PATCH 7/7] git-svn(1): improve asciidoc markup
@ 2006-08-25 1:07 7% ` Jonas Fonseca
0 siblings, 0 replies; 200+ results
From: Jonas Fonseca @ 2006-08-25 1:07 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
Use list continuation to have better wrapping. This accounts for most of
the changes because it reindents a lot of text without applying other
changes.
Use cross-referencing for interlinking and the gitlink macro for pointing
to other tools in the git suite.
Signed-off-by: Jonas Fonseca <fonseca@diku.dk>
---
Documentation/git-svn.txt | 199 ++++++++++++++++++++++++++-------------------
1 files changed, 114 insertions(+), 85 deletions(-)
diff --git a/Documentation/git-svn.txt b/Documentation/git-svn.txt
index 7d86809..f21aced 100644
--- a/Documentation/git-svn.txt
+++ b/Documentation/git-svn.txt
@@ -12,10 +12,8 @@ SYNOPSIS
DESCRIPTION
-----------
git-svn is a simple conduit for changesets between a single Subversion
-branch and git.
-
-git-svn is not to be confused with git-svnimport. The were designed
-with very different goals in mind.
+branch and git. It is not to be confused with gitlink:git-svnimport[1].
+They were designed with very different goals in mind.
git-svn is designed for an individual developer who wants a
bidirectional flow of changesets between a single branch in Subversion
@@ -34,26 +32,29 @@ git-svnimport is designed for.
COMMANDS
--------
-init::
+--
+
+'init'::
Creates an empty git repository with additional metadata
directories for git-svn. The Subversion URL must be specified
as a command-line argument.
-fetch::
- Fetch unfetched revisions from the Subversion URL we are
- tracking. refs/remotes/git-svn will be updated to the
- latest revision.
+'fetch'::
- Note: You should never attempt to modify the remotes/git-svn
- branch outside of git-svn. Instead, create a branch from
- remotes/git-svn and work on that branch. Use the 'commit'
- command (see below) to write git commits back to
- remotes/git-svn.
+Fetch unfetched revisions from the Subversion URL we are
+tracking. refs/remotes/git-svn will be updated to the
+latest revision.
- See 'Additional Fetch Arguments' if you are interested in
- manually joining branches on commit.
+Note: You should never attempt to modify the remotes/git-svn
+branch outside of git-svn. Instead, create a branch from
+remotes/git-svn and work on that branch. Use the 'commit'
+command (see below) to write git commits back to
+remotes/git-svn.
-commit::
+See '<<fetch-args,Additional Fetch Arguments>>' if you are interested in
+manually joining branches on commit.
+
+'commit'::
Commit specified commit or tree objects to SVN. This relies on
your imported fetch data being up-to-date. This makes
absolutely no attempts to do patching when committing to SVN, it
@@ -61,9 +62,9 @@ commit::
commit. All merging is assumed to have taken place
independently of git-svn functions.
-rebuild::
+'rebuild'::
Not a part of daily usage, but this is a useful command if
- you've just cloned a repository (using git-clone) that was
+ you've just cloned a repository (using gitlink:git-clone[1]) that was
tracked with git-svn. Unfortunately, git-clone does not clone
git-svn metadata and the svn working tree that git-svn uses for
its operations. This rebuilds the metadata so git-svn can
@@ -71,130 +72,152 @@ rebuild::
specified at the command-line if the directory/repository you're
tracking has moved or changed protocols.
-show-ignore::
+'show-ignore'::
Recursively finds and lists the svn:ignore property on
directories. The output is suitable for appending to
the $GIT_DIR/info/exclude file.
+--
+
OPTIONS
-------
+--
+
-r <ARG>::
--revision <ARG>::
- Only used with the 'fetch' command.
- Takes any valid -r<argument> svn would accept and passes it
- directly to svn. -r<ARG1>:<ARG2> ranges and "{" DATE "}" syntax
- is also supported. This is passed directly to svn, see svn
- documentation for more details.
+Only used with the 'fetch' command.
- This can allow you to make partial mirrors when running fetch.
+Takes any valid -r<argument> svn would accept and passes it
+directly to svn. -r<ARG1>:<ARG2> ranges and "{" DATE "}" syntax
+is also supported. This is passed directly to svn, see svn
+documentation for more details.
+
+This can allow you to make partial mirrors when running fetch.
-::
--stdin::
- Only used with the 'commit' command.
- Read a list of commits from stdin and commit them in reverse
- order. Only the leading sha1 is read from each line, so
- git-rev-list --pretty=oneline output can be used.
+Only used with the 'commit' command.
+
+Read a list of commits from stdin and commit them in reverse
+order. Only the leading sha1 is read from each line, so
+git-rev-list --pretty=oneline output can be used.
--rmdir::
- Only used with the 'commit' command.
- Remove directories from the SVN tree if there are no files left
- behind. SVN can version empty directories, and they are not
- removed by default if there are no files left in them. git
- cannot version empty directories. Enabling this flag will make
- the commit to SVN act like git.
+Only used with the 'commit' command.
- repo-config key: svn.rmdir
+Remove directories from the SVN tree if there are no files left
+behind. SVN can version empty directories, and they are not
+removed by default if there are no files left in them. git
+cannot version empty directories. Enabling this flag will make
+the commit to SVN act like git.
+
+repo-config key: svn.rmdir
-e::
--edit::
- Only used with the 'commit' command.
- Edit the commit message before committing to SVN. This is off by
- default for objects that are commits, and forced on when committing
- tree objects.
+Only used with the 'commit' command.
+
+Edit the commit message before committing to SVN. This is off by
+default for objects that are commits, and forced on when committing
+tree objects.
- repo-config key: svn.edit
+repo-config key: svn.edit
-l<num>::
--find-copies-harder::
- Both of these are only used with the 'commit' command.
- They are both passed directly to git-diff-tree see
- git-diff-tree(1) for more information.
+Both of these are only used with the 'commit' command.
- repo-config key: svn.l
- repo-config key: svn.findcopiesharder
+They are both passed directly to git-diff-tree see
+gitlink:git-diff-tree[1] for more information.
+
+[verse]
+repo-config key: svn.l
+repo-config key: svn.findcopiesharder
-A<filename>::
--authors-file=<filename>::
- Syntax is compatible with the files used by git-svnimport and
- git-cvsimport:
+Syntax is compatible with the files used by git-svnimport and
+git-cvsimport:
------------------------------------------------------------------------
-loginname = Joe User <user@example.com>
+ loginname = Joe User <user@example.com>
------------------------------------------------------------------------
- If this option is specified and git-svn encounters an SVN
- committer name that does not exist in the authors-file, git-svn
- will abort operation. The user will then have to add the
- appropriate entry. Re-running the previous git-svn command
- after the authors-file is modified should continue operation.
+If this option is specified and git-svn encounters an SVN
+committer name that does not exist in the authors-file, git-svn
+will abort operation. The user will then have to add the
+appropriate entry. Re-running the previous git-svn command
+after the authors-file is modified should continue operation.
+
+repo-config key: svn.authors-file
- repo-config key: svn.authors-file
+--
ADVANCED OPTIONS
----------------
+--
+
-b<refname>::
--branch <refname>::
- Used with 'fetch' or 'commit'.
+Used with 'fetch' or 'commit'.
- This can be used to join arbitrary git branches to remotes/git-svn
- on new commits where the tree object is equivalent.
+This can be used to join arbitrary git branches to remotes/git-svn
+on new commits where the tree object is equivalent.
- When used with different GIT_SVN_ID values, tags and branches in
- SVN can be tracked this way, as can some merges where the heads
- end up having completely equivalent content. This can even be
- used to track branches across multiple SVN _repositories_.
+When used with different GIT_SVN_ID values, tags and branches in
+SVN can be tracked this way, as can some merges where the heads
+end up having completely equivalent content. This can even be
+used to track branches across multiple SVN _repositories_.
- This option may be specified multiple times, once for each
- branch.
+This option may be specified multiple times, once for each
+branch.
- repo-config key: svn.branch
+repo-config key: svn.branch
-i<GIT_SVN_ID>::
--id <GIT_SVN_ID>::
- This sets GIT_SVN_ID (instead of using the environment). See
- the section on "Tracking Multiple Repositories or Branches" for
- more information on using GIT_SVN_ID.
+
+This sets GIT_SVN_ID (instead of using the environment). See the
+section on
+'<<tracking-multiple-repos,Tracking Multiple Repositories or Branches>>'
+for more information on using GIT_SVN_ID.
+
+--
COMPATIBILITY OPTIONS
---------------------
+--
+
--upgrade::
- Only used with the 'rebuild' command.
+Only used with the 'rebuild' command.
- Run this if you used an old version of git-svn that used
- "git-svn-HEAD" instead of "remotes/git-svn" as the branch
- for tracking the remote.
+Run this if you used an old version of git-svn that used
+"git-svn-HEAD" instead of "remotes/git-svn" as the branch
+for tracking the remote.
--no-ignore-externals::
- Only used with the 'fetch' and 'rebuild' command.
+Only used with the 'fetch' and 'rebuild' command.
+
+By default, git-svn passes --ignore-externals to svn to avoid
+fetching svn:external trees into git. Pass this flag to enable
+externals tracking directly via git.
- By default, git-svn passes --ignore-externals to svn to avoid
- fetching svn:external trees into git. Pass this flag to enable
- externals tracking directly via git.
+Versions of svn that do not support --ignore-externals are
+automatically detected and this flag will be automatically
+enabled for them.
- Versions of svn that do not support --ignore-externals are
- automatically detected and this flag will be automatically
- enabled for them.
+Otherwise, do not enable this flag unless you know what you're
+doing.
- Otherwise, do not enable this flag unless you know what you're
- doing.
+repo-config key: svn.noignoreexternals
- repo-config key: svn.noignoreexternals
+--
Basic Examples
~~~~~~~~~~~~~~
@@ -226,6 +249,7 @@ any automated merge/branch tracking on t
entirely up to the user on the git side. It's simply not worth it to do
a useful translation when the original signal is weak.
+[[tracking-multiple-repos]]
TRACKING MULTIPLE REPOSITORIES OR BRANCHES
------------------------------------------
This is for advanced users, most users should ignore this section.
@@ -241,6 +265,7 @@ invocation. The interface branch will b
remotes/git-svn. Any remotes/$GIT_SVN_ID branch should never be modified
by the user outside of git-svn commands.
+[[fetch-args]]
ADDITIONAL FETCH ARGUMENTS
--------------------------
This is for advanced users, most users should ignore this section.
@@ -251,11 +276,15 @@ optionally be specified in the form of s
command-line. Unfetched SVN revisions may also be tied to particular
git commits with the following syntax:
+------------------------------------------------
svn_revision_number=git_commit_sha1
+------------------------------------------------
-This allows you to tie unfetched SVN revision 375 to your current HEAD::
+This allows you to tie unfetched SVN revision 375 to your current HEAD:
- `git-svn fetch 375=$(git-rev-parse HEAD)`
+------------------------------------------------
+ git-svn fetch 375=$(git-rev-parse HEAD)
+------------------------------------------------
Advanced Example: Tracking a Reorganized Repository
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--
1.4.2.GIT
--
Jonas Fonseca
^ permalink raw reply related [relevance 7%]
* Re: Mozilla version control requirements and git
@ 2006-09-03 3:29 4% ` Jon Smirl
0 siblings, 0 replies; 200+ results
From: Jon Smirl @ 2006-09-03 3:29 UTC (permalink / raw)
To: Martin Langhoff; +Cc: git
On 9/2/06, Martin Langhoff <martin.langhoff@gmail.com> wrote:
> On 9/3/06, Jon Smirl <jonsmirl@gmail.com> wrote:
> > The Mozilla people have a web page describing what they are looking
> > for in a new version control system. How does git stack up?
>
> Hi Jon,
>
> you've been playing with GIT quite a bit by now, so I guess you know
> the answer ;-) Is there anything in particular you are wondering
> about?
Shallow clones are a big problem. We have Mozilla down to 450MB is
git, but that is still gigantic for anyone doing an initial check out,
especially if they don't have good broadband. It is over 10x the data
that CVS brings down. Even without doing shallow clones git still
needs to be modified to restart an interrupted pack transfer.
>
> The one item that sticks out for me as not there is ACLs, but access
> controls can be implemented in hooks for direct pushes. Maintain an
> .htaccess-like file and have a perl script to check it on pushes to
> the repo.
I don't see ACLs as that big an issue. If you convert to model where
everyone has their own repo and you just push changesets at each
other, ACLs are much less important. You need ACLs when 2,000 people
have commit privs.
>
> Oh, and "partial tree pulls for localisers". Perhaps git-cvsserver can
> help there? Localisers can just use TortoiseCVS and get a checkout of
> the language pack subdir.
Partial repo pulls and an issue to. The mozilla repo has much more
than a browser in it, it also has a large mail/news program. A partial
repo pull may not be what is needed for git, instead git needs a
partial repo checkout.
--
Jon Smirl
jonsmirl@gmail.com
--
VGER BF report: U 0.827771
^ permalink raw reply [relevance 4%]
* [PATCH 3/3] git-commit.sh: convert run_status to a C builtin
[not found] <64c62cc942e872b29d7225999e74a07be586674a.1157610743.git.peff@peff.net>
@ 2006-09-07 6:36 2% ` Jeff King
0 siblings, 0 replies; 200+ results
From: Jeff King @ 2006-09-07 6:36 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
This creates a new git-runstatus which should do roughly the same thing
as the run_status function from git-commit.sh. Except for color support,
the main focus has been to keep the output identical, so that it can be
verified as correct and then used as a C platform for other improvements to
the status printing code.
---
.gitignore | 1
Makefile | 3 -
builtin-runstatus.c | 34 ++++++
builtin.h | 1
dir.c | 7 +
dir.h | 1
git-commit.sh | 106 +------------------
git.c | 1
status.c | 283 +++++++++++++++++++++++++++++++++++++++++++++++++++
status.h | 31 ++++++
10 files changed, 368 insertions(+), 100 deletions(-)
diff --git a/.gitignore b/.gitignore
index 78cb671..f014ad3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -94,6 +94,7 @@ git-rev-list
git-rev-parse
git-revert
git-rm
+git-runstatus
git-send-email
git-send-pack
git-sh-setup
diff --git a/Makefile b/Makefile
index 78748cb..d0ba3b5 100644
--- a/Makefile
+++ b/Makefile
@@ -252,7 +252,7 @@ LIB_OBJS = \
fetch-clone.o revision.o pager.o tree-walk.o xdiff-interface.o \
write_or_die.o trace.o \
alloc.o merge-file.o path-list.o help.o unpack-trees.o $(DIFF_OBJS) \
- color.o
+ color.o status.o
BUILTIN_OBJS = \
builtin-add.o \
@@ -286,6 +286,7 @@ BUILTIN_OBJS = \
builtin-rev-list.o \
builtin-rev-parse.o \
builtin-rm.o \
+ builtin-runstatus.o \
builtin-show-branch.o \
builtin-stripspace.o \
builtin-symbolic-ref.o \
diff --git a/builtin-runstatus.c b/builtin-runstatus.c
new file mode 100644
index 0000000..f3e44de
--- /dev/null
+++ b/builtin-runstatus.c
@@ -0,0 +1,34 @@
+#include "status.h"
+#include "cache.h"
+
+extern int status_use_color;
+
+static const char runstatus_usage[] =
+"git-runstatus [--color|--nocolor] [--amend] [--verbose]";
+
+int cmd_runstatus(int argc, const char **argv, const char *prefix)
+{
+ struct status s;
+ int i;
+
+ git_config(git_status_config);
+ status_prepare(&s);
+
+ for (i = 1; i < argc; i++) {
+ if (!strcmp(argv[i], "--color"))
+ status_use_color = 1;
+ else if (!strcmp(argv[i], "--nocolor"))
+ status_use_color = 0;
+ else if (!strcmp(argv[i], "--amend")) {
+ s.amend = 1;
+ s.reference = "HEAD^1";
+ }
+ else if (!strcmp(argv[i], "--verbose"))
+ s.verbose = 1;
+ else
+ usage(runstatus_usage);
+ }
+
+ status_print(&s);
+ return s.commitable ? 0 : 1;
+}
diff --git a/builtin.h b/builtin.h
index 25431d7..53a896c 100644
--- a/builtin.h
+++ b/builtin.h
@@ -47,6 +47,7 @@ extern int cmd_repo_config(int argc, con
extern int cmd_rev_list(int argc, const char **argv, const char *prefix);
extern int cmd_rev_parse(int argc, const char **argv, const char *prefix);
extern int cmd_rm(int argc, const char **argv, const char *prefix);
+extern int cmd_runstatus(int argc, const char **argv, const char *prefix);
extern int cmd_show_branch(int argc, const char **argv, const char *prefix);
extern int cmd_show(int argc, const char **argv, const char *prefix);
extern int cmd_stripspace(int argc, const char **argv, const char *prefix);
diff --git a/dir.c b/dir.c
index 5a40d8f..e2f472b 100644
--- a/dir.c
+++ b/dir.c
@@ -397,3 +397,10 @@ int read_directory(struct dir_struct *di
qsort(dir->entries, dir->nr, sizeof(struct dir_entry *), cmp_name);
return dir->nr;
}
+
+int
+file_exists(const char *f)
+{
+ struct stat sb;
+ return stat(f, &sb) == 0;
+}
diff --git a/dir.h b/dir.h
index 56a1b7f..313f8ab 100644
--- a/dir.h
+++ b/dir.h
@@ -47,5 +47,6 @@ extern int excluded(struct dir_struct *,
extern void add_excludes_from_file(struct dir_struct *, const char *fname);
extern void add_exclude(const char *string, const char *base,
int baselen, struct exclude_list *which);
+extern int file_exists(const char *);
#endif
diff --git a/git-commit.sh b/git-commit.sh
index 4cf3fab..10c269a 100755
--- a/git-commit.sh
+++ b/git-commit.sh
@@ -60,26 +60,6 @@ #
}
run_status () {
- (
- # We always show status for the whole tree.
- cd "$TOP"
-
- IS_INITIAL="$initial_commit"
- REFERENCE=HEAD
- case "$amend" in
- t)
- # If we are amending the initial commit, there
- # is no HEAD^1.
- if git-rev-parse --verify "HEAD^1" >/dev/null 2>&1
- then
- REFERENCE="HEAD^1"
- IS_INITIAL=
- else
- IS_INITIAL=t
- fi
- ;;
- esac
-
# If TMP_INDEX is defined, that means we are doing
# "--only" partial commit, and that index file is used
# to build the tree for the commit. Otherwise, if
@@ -96,85 +76,13 @@ run_status () {
export GIT_INDEX_FILE
fi
- case "$branch" in
- refs/heads/master) ;;
- *) echo "# On branch $branch" ;;
- esac
-
- if test -z "$IS_INITIAL"
- then
- git-diff-index -M --cached --name-status \
- --diff-filter=MDTCRA $REFERENCE |
- sed -e '
- s/\\/\\\\/g
- s/ /\\ /g
- ' |
- report "Updated but not checked in" "will commit"
- committable="$?"
- else
- echo '#
-# Initial commit
-#'
- git-ls-files |
- sed -e '
- s/\\/\\\\/g
- s/ /\\ /g
- s/^/A /
- ' |
- report "Updated but not checked in" "will commit"
-
- committable="$?"
- fi
-
- git-diff-files --name-status |
- sed -e '
- s/\\/\\\\/g
- s/ /\\ /g
- ' |
- report "Changed but not updated" \
- "use git-update-index to mark for commit"
-
- option=""
- if test -z "$untracked_files"; then
- option="--directory --no-empty-directory"
- fi
- hdr_shown=
- if test -f "$GIT_DIR/info/exclude"
- then
- git-ls-files --others $option \
- --exclude-from="$GIT_DIR/info/exclude" \
- --exclude-per-directory=.gitignore
- else
- git-ls-files --others $option \
- --exclude-per-directory=.gitignore
- fi |
- while read line; do
- if [ -z "$hdr_shown" ]; then
- echo '#'
- echo '# Untracked files:'
- echo '# (use "git add" to add to commit)'
- echo '#'
- hdr_shown=1
- fi
- echo "# $line"
- done
-
- if test -n "$verbose" -a -z "$IS_INITIAL"
- then
- git-diff-index --cached -M -p --diff-filter=MDTCRA $REFERENCE
- fi
- case "$committable" in
- 0)
- case "$amend" in
- t)
- echo "# No changes" ;;
- *)
- echo "nothing to commit" ;;
- esac
- exit 1 ;;
- esac
- exit 0
- )
+ case "$status_only" in
+ t) color= ;;
+ *) color=--nocolor ;;
+ esac
+ git-runstatus ${color} \
+ ${verbose:+--verbose} \
+ ${amend:+--amend}
}
trap '
diff --git a/git.c b/git.c
index 335f405..495b39a 100644
--- a/git.c
+++ b/git.c
@@ -252,6 +252,7 @@ static void handle_internal_command(int
{ "rev-list", cmd_rev_list, RUN_SETUP },
{ "rev-parse", cmd_rev_parse, RUN_SETUP },
{ "rm", cmd_rm, RUN_SETUP },
+ { "runstatus", cmd_runstatus, RUN_SETUP },
{ "show-branch", cmd_show_branch, RUN_SETUP },
{ "show", cmd_show, RUN_SETUP | USE_PAGER },
{ "stripspace", cmd_stripspace },
diff --git a/status.c b/status.c
new file mode 100644
index 0000000..82aa881
--- /dev/null
+++ b/status.c
@@ -0,0 +1,283 @@
+#include "status.h"
+#include "color.h"
+#include "cache.h"
+#include "object.h"
+#include "dir.h"
+#include "commit.h"
+#include "diff.h"
+#include "revision.h"
+#include "diffcore.h"
+
+int status_use_color = 0;
+static char status_colors[][COLOR_MAXLEN] = {
+ "", /* STATUS_HEADER: normal */
+ "\033[32m", /* STATUS_UPDATED: green */
+ "\033[31m", /* STATUS_CHANGED: red */
+ "\033[31m", /* STATUS_UNTRACKED: red */
+};
+
+static int
+parse_status_slot(const char *var, int offset) {
+ if (!strcasecmp(var+offset, "header"))
+ return STATUS_HEADER;
+ if (!strcasecmp(var+offset, "updated"))
+ return STATUS_UPDATED;
+ if (!strcasecmp(var+offset, "changed"))
+ return STATUS_CHANGED;
+ if (!strcasecmp(var+offset, "untracked"))
+ return STATUS_UNTRACKED;
+ die("bad config variable '%s'", var);
+}
+
+static const char*
+color(int slot)
+{
+ return status_use_color ? status_colors[slot] : "";
+}
+
+void
+status_prepare(struct status *s)
+{
+ unsigned char sha1[20];
+ const char *head;
+
+ s->is_initial = get_sha1("HEAD", sha1) ? 1 : 0;
+
+ head = resolve_ref(git_path("HEAD"), sha1, 0);
+ s->branch = head ?
+ strdup(head + strlen(get_git_dir()) + 1) :
+ NULL;
+
+ s->reference = "HEAD";
+ s->amend = 0;
+ s->verbose = 0;
+ s->commitable = 0;
+}
+
+static void
+status_print_header(const char *main, const char *sub)
+{
+ const char *c = color(STATUS_HEADER);
+ color_printf(c, "# %s:\n", main);
+ color_printf(c, "# (%s)\n", sub);
+ color_printf(c, "#\n");
+}
+
+static void
+status_print_trailer(void)
+{
+ color_printf(color(STATUS_HEADER), "#\n");
+}
+
+static void
+status_print_filepair(int t, struct diff_filepair *p)
+{
+ const char *c = color(t);
+ color_printf(color(STATUS_HEADER), "#\t");
+ switch (p->status) {
+ case DIFF_STATUS_ADDED:
+ color_printf(c, "new file: %s\n", p->one->path); break;
+ case DIFF_STATUS_COPIED:
+ color_printf(c, "copied: %s -> %s\n",
+ p->one->path, p->two->path);
+ break;
+ case DIFF_STATUS_DELETED:
+ color_printf(c, "deleted: %s\n", p->one->path); break;
+ case DIFF_STATUS_MODIFIED:
+ color_printf(c, "modified: %s\n", p->one->path); break;
+ case DIFF_STATUS_RENAMED:
+ color_printf(c, "renamed: %s -> %s\n",
+ p->one->path, p->two->path);
+ break;
+ case DIFF_STATUS_TYPE_CHANGED:
+ color_printf(c, "typechange: %s\n", p->one->path); break;
+ case DIFF_STATUS_UNKNOWN:
+ color_printf(c, "unknown: %s\n", p->one->path); break;
+ case DIFF_STATUS_UNMERGED:
+ color_printf(c, "unmerged: %s\n", p->one->path); break;
+ default:
+ die("bug: unhandled diff status %c", p->status);
+ }
+}
+
+static void
+status_print_updated_cb(struct diff_queue_struct *q,
+ struct diff_options *options,
+ void *data)
+{
+ struct status *s = data;
+ int shown_header = 0;
+ int i;
+ if (q->nr) {
+ }
+ for (i = 0; i < q->nr; i++) {
+ if (q->queue[i]->status == 'U')
+ continue;
+ if (!shown_header) {
+ status_print_header("Updated but not checked in",
+ "will commit");
+ s->commitable = 1;
+ }
+ status_print_filepair(STATUS_UPDATED, q->queue[i]);
+ }
+ if (shown_header)
+ status_print_trailer();
+}
+
+static void
+status_print_changed_cb(struct diff_queue_struct *q,
+ struct diff_options *options,
+ void *data)
+{
+ int i;
+ if (q->nr)
+ status_print_header("Changed but not updated",
+ "use git-update-index to mark for commit");
+ for (i = 0; i < q->nr; i++)
+ status_print_filepair(STATUS_CHANGED, q->queue[i]);
+ if (q->nr)
+ status_print_trailer();
+}
+
+void
+status_print_initial(struct status *s)
+{
+ int i;
+ read_cache();
+ if (active_nr) {
+ s->commitable = 1;
+ status_print_header("Updated but not checked in",
+ "will commit");
+ }
+ for (i = 0; i < active_nr; i++) {
+ color_printf(color(STATUS_HEADER), "#\t");
+ color_printf(color(STATUS_UPDATED), "new file: %s\n",
+ active_cache[i]->name);
+ }
+ if (active_nr)
+ status_print_trailer();
+}
+
+static void
+status_print_updated(struct status *s)
+{
+ struct rev_info rev;
+ const char *argv[] = { NULL, NULL, NULL };
+ argv[1] = s->reference;
+ init_revisions(&rev, NULL);
+ setup_revisions(2, argv, &rev, NULL);
+ rev.diffopt.output_format |= DIFF_FORMAT_CALLBACK;
+ rev.diffopt.format_callback = status_print_updated_cb;
+ rev.diffopt.format_callback_data = s;
+ rev.diffopt.detect_rename = 1;
+ run_diff_index(&rev, 1);
+}
+
+static void
+status_print_changed(struct status *s)
+{
+ struct rev_info rev;
+ const char *argv[] = { NULL, NULL };
+ init_revisions(&rev, "");
+ setup_revisions(1, argv, &rev, NULL);
+ rev.diffopt.output_format |= DIFF_FORMAT_CALLBACK;
+ rev.diffopt.format_callback = status_print_changed_cb;
+ rev.diffopt.format_callback_data = s;
+ run_diff_files(&rev, 0);
+}
+
+static void
+status_print_untracked(const struct status *s)
+{
+ struct dir_struct dir;
+ const char *x;
+ int i;
+ int shown_header = 0;
+
+ memset(&dir, 0, sizeof(dir));
+
+ dir.exclude_per_dir = ".gitignore";
+ x = git_path("info/exclude");
+ if (file_exists(x))
+ add_excludes_from_file(&dir, x);
+
+ read_directory(&dir, ".", "", 0);
+ for(i = 0; i < dir.nr; i++) {
+ /* check for matching entry, which is unmerged; lifted from
+ * builtin-ls-files:show_other_files */
+ struct dir_entry *ent = dir.entries[i];
+ int pos = cache_name_pos(ent->name, ent->len);
+ struct cache_entry *ce;
+ if (0 <= pos)
+ die("bug in status_print_untracked");
+ pos = -pos - 1;
+ if (pos < active_nr) {
+ ce = active_cache[pos];
+ if (ce_namelen(ce) == ent->len &&
+ !memcmp(ce->name, ent->name, ent->len))
+ continue;
+ }
+ if (!shown_header) {
+ status_print_header("Untracked files",
+ "use \"git add\" to add to commit");
+ shown_header = 1;
+ }
+ color_printf(color(STATUS_HEADER), "#\t");
+ color_printf(color(STATUS_UNTRACKED), "%.*s\n",
+ ent->len, ent->name);
+ }
+}
+
+static void
+status_print_verbose(struct status *s)
+{
+ struct rev_info rev;
+ const char *argv[] = { NULL, NULL, NULL };
+ argv[1] = s->reference;
+ init_revisions(&rev, NULL);
+ setup_revisions(2, argv, &rev, NULL);
+ rev.diffopt.output_format |= DIFF_FORMAT_PATCH;
+ rev.diffopt.detect_rename = 1;
+ run_diff_index(&rev, 1);
+}
+
+void
+status_print(struct status *s)
+{
+ if (s->branch && strcmp(s->branch, "refs/heads/master"))
+ color_printf(color(STATUS_HEADER),
+ "# On branch %s\n", s->branch);
+
+ if (s->is_initial) {
+ color_printf(color(STATUS_HEADER), "#\n");
+ color_printf(color(STATUS_HEADER), "# Initial commit\n");
+ color_printf(color(STATUS_HEADER), "#\n");
+ status_print_initial(s);
+ }
+ else {
+ status_print_updated(s);
+ discard_cache();
+ }
+
+ status_print_changed(s);
+ status_print_untracked(s);
+
+ if (s->verbose && !s->is_initial)
+ status_print_verbose(s);
+ if (!s->commitable)
+ printf("%s\n", s->amend ? "# No changes" : "nothing to commit");
+}
+
+int
+git_status_config(const char *k, const char *v)
+{
+ if (!strcmp(k, "status.color")) {
+ status_use_color = git_config_colorbool(k, v);
+ return 0;
+ }
+ if (!strncmp(k, "status.color.", 13)) {
+ int slot = parse_status_slot(k, 13);
+ color_parse(v, k, status_colors[slot]);
+ }
+ return git_default_config(k, v);
+}
diff --git a/status.h b/status.h
new file mode 100644
index 0000000..3e60146
--- /dev/null
+++ b/status.h
@@ -0,0 +1,31 @@
+#ifndef STATUS_H
+#define STATUS_H
+
+enum color_status {
+ STATUS_HEADER,
+ STATUS_UPDATED,
+ STATUS_CHANGED,
+ STATUS_UNTRACKED,
+};
+
+struct status {
+ int is_initial;
+ char *branch;
+ const char *reference;
+ int commitable;
+ int verbose;
+ int amend;
+};
+
+int git_status_config(const char *var, const char *value);
+void status_prepare(struct status *s);
+void status_print(struct status *s);
+
+struct cache_entry;
+typedef void (*status_cb)(struct cache_entry *);
+int status_foreach_cached(status_cb cb);
+int status_foreach_updated(status_cb cb);
+int status_foreach_changed(status_cb cb);
+int status_foreach_untracked(status_cb cb);
+
+#endif /* STATUS_H */
--
1.4.2.ge490e-dirty
^ permalink raw reply related [relevance 2%]
* [PATCH] git-commit.sh: convert run_status to a C builtin
@ 2006-09-08 8:05 2% Jeff King
0 siblings, 0 replies; 200+ results
From: Jeff King @ 2006-09-08 8:05 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
This creates a new git-runstatus which should do roughly the same thing
as the run_status function from git-commit.sh. Except for color support,
the main focus has been to keep the output identical, so that it can be
verified as correct and then used as a C platform for other improvements to
the status printing code.
Signed-off-by: Jeff King <peff@peff.net>
---
This is a resend with:
- formatting cleanups
- s/status/wt_status/
- avoid letting colored sections cross newlines
.gitignore | 1
Makefile | 3 -
builtin-runstatus.c | 34 ++++++
builtin.h | 1
dir.c | 7 +
dir.h | 1
git-commit.sh | 106 +-------------------
git.c | 1
wt-status.c | 271 +++++++++++++++++++++++++++++++++++++++++++++++++++
wt-status.h | 24 +++++
10 files changed, 349 insertions(+), 100 deletions(-)
diff --git a/.gitignore b/.gitignore
index 78cb671..f014ad3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -94,6 +94,7 @@ git-rev-list
git-rev-parse
git-revert
git-rm
+git-runstatus
git-send-email
git-send-pack
git-sh-setup
diff --git a/Makefile b/Makefile
index 78748cb..a9314ac 100644
--- a/Makefile
+++ b/Makefile
@@ -252,7 +252,7 @@ LIB_OBJS = \
fetch-clone.o revision.o pager.o tree-walk.o xdiff-interface.o \
write_or_die.o trace.o \
alloc.o merge-file.o path-list.o help.o unpack-trees.o $(DIFF_OBJS) \
- color.o
+ color.o wt-status.o
BUILTIN_OBJS = \
builtin-add.o \
@@ -286,6 +286,7 @@ BUILTIN_OBJS = \
builtin-rev-list.o \
builtin-rev-parse.o \
builtin-rm.o \
+ builtin-runstatus.o \
builtin-show-branch.o \
builtin-stripspace.o \
builtin-symbolic-ref.o \
diff --git a/builtin-runstatus.c b/builtin-runstatus.c
new file mode 100644
index 0000000..7979d61
--- /dev/null
+++ b/builtin-runstatus.c
@@ -0,0 +1,34 @@
+#include "wt-status.h"
+#include "cache.h"
+
+extern int wt_status_use_color;
+
+static const char runstatus_usage[] =
+"git-runstatus [--color|--nocolor] [--amend] [--verbose]";
+
+int cmd_runstatus(int argc, const char **argv, const char *prefix)
+{
+ struct wt_status s;
+ int i;
+
+ git_config(git_status_config);
+ wt_status_prepare(&s);
+
+ for (i = 1; i < argc; i++) {
+ if (!strcmp(argv[i], "--color"))
+ wt_status_use_color = 1;
+ else if (!strcmp(argv[i], "--nocolor"))
+ wt_status_use_color = 0;
+ else if (!strcmp(argv[i], "--amend")) {
+ s.amend = 1;
+ s.reference = "HEAD^1";
+ }
+ else if (!strcmp(argv[i], "--verbose"))
+ s.verbose = 1;
+ else
+ usage(runstatus_usage);
+ }
+
+ wt_status_print(&s);
+ return s.commitable ? 0 : 1;
+}
diff --git a/builtin.h b/builtin.h
index 25431d7..53a896c 100644
--- a/builtin.h
+++ b/builtin.h
@@ -47,6 +47,7 @@ extern int cmd_repo_config(int argc, con
extern int cmd_rev_list(int argc, const char **argv, const char *prefix);
extern int cmd_rev_parse(int argc, const char **argv, const char *prefix);
extern int cmd_rm(int argc, const char **argv, const char *prefix);
+extern int cmd_runstatus(int argc, const char **argv, const char *prefix);
extern int cmd_show_branch(int argc, const char **argv, const char *prefix);
extern int cmd_show(int argc, const char **argv, const char *prefix);
extern int cmd_stripspace(int argc, const char **argv, const char *prefix);
diff --git a/dir.c b/dir.c
index 5a40d8f..e2f472b 100644
--- a/dir.c
+++ b/dir.c
@@ -397,3 +397,10 @@ int read_directory(struct dir_struct *di
qsort(dir->entries, dir->nr, sizeof(struct dir_entry *), cmp_name);
return dir->nr;
}
+
+int
+file_exists(const char *f)
+{
+ struct stat sb;
+ return stat(f, &sb) == 0;
+}
diff --git a/dir.h b/dir.h
index 56a1b7f..313f8ab 100644
--- a/dir.h
+++ b/dir.h
@@ -47,5 +47,6 @@ extern int excluded(struct dir_struct *,
extern void add_excludes_from_file(struct dir_struct *, const char *fname);
extern void add_exclude(const char *string, const char *base,
int baselen, struct exclude_list *which);
+extern int file_exists(const char *);
#endif
diff --git a/git-commit.sh b/git-commit.sh
index 4cf3fab..10c269a 100755
--- a/git-commit.sh
+++ b/git-commit.sh
@@ -60,26 +60,6 @@ #
}
run_status () {
- (
- # We always show status for the whole tree.
- cd "$TOP"
-
- IS_INITIAL="$initial_commit"
- REFERENCE=HEAD
- case "$amend" in
- t)
- # If we are amending the initial commit, there
- # is no HEAD^1.
- if git-rev-parse --verify "HEAD^1" >/dev/null 2>&1
- then
- REFERENCE="HEAD^1"
- IS_INITIAL=
- else
- IS_INITIAL=t
- fi
- ;;
- esac
-
# If TMP_INDEX is defined, that means we are doing
# "--only" partial commit, and that index file is used
# to build the tree for the commit. Otherwise, if
@@ -96,85 +76,13 @@ run_status () {
export GIT_INDEX_FILE
fi
- case "$branch" in
- refs/heads/master) ;;
- *) echo "# On branch $branch" ;;
- esac
-
- if test -z "$IS_INITIAL"
- then
- git-diff-index -M --cached --name-status \
- --diff-filter=MDTCRA $REFERENCE |
- sed -e '
- s/\\/\\\\/g
- s/ /\\ /g
- ' |
- report "Updated but not checked in" "will commit"
- committable="$?"
- else
- echo '#
-# Initial commit
-#'
- git-ls-files |
- sed -e '
- s/\\/\\\\/g
- s/ /\\ /g
- s/^/A /
- ' |
- report "Updated but not checked in" "will commit"
-
- committable="$?"
- fi
-
- git-diff-files --name-status |
- sed -e '
- s/\\/\\\\/g
- s/ /\\ /g
- ' |
- report "Changed but not updated" \
- "use git-update-index to mark for commit"
-
- option=""
- if test -z "$untracked_files"; then
- option="--directory --no-empty-directory"
- fi
- hdr_shown=
- if test -f "$GIT_DIR/info/exclude"
- then
- git-ls-files --others $option \
- --exclude-from="$GIT_DIR/info/exclude" \
- --exclude-per-directory=.gitignore
- else
- git-ls-files --others $option \
- --exclude-per-directory=.gitignore
- fi |
- while read line; do
- if [ -z "$hdr_shown" ]; then
- echo '#'
- echo '# Untracked files:'
- echo '# (use "git add" to add to commit)'
- echo '#'
- hdr_shown=1
- fi
- echo "# $line"
- done
-
- if test -n "$verbose" -a -z "$IS_INITIAL"
- then
- git-diff-index --cached -M -p --diff-filter=MDTCRA $REFERENCE
- fi
- case "$committable" in
- 0)
- case "$amend" in
- t)
- echo "# No changes" ;;
- *)
- echo "nothing to commit" ;;
- esac
- exit 1 ;;
- esac
- exit 0
- )
+ case "$status_only" in
+ t) color= ;;
+ *) color=--nocolor ;;
+ esac
+ git-runstatus ${color} \
+ ${verbose:+--verbose} \
+ ${amend:+--amend}
}
trap '
diff --git a/git.c b/git.c
index 335f405..495b39a 100644
--- a/git.c
+++ b/git.c
@@ -252,6 +252,7 @@ static void handle_internal_command(int
{ "rev-list", cmd_rev_list, RUN_SETUP },
{ "rev-parse", cmd_rev_parse, RUN_SETUP },
{ "rm", cmd_rm, RUN_SETUP },
+ { "runstatus", cmd_runstatus, RUN_SETUP },
{ "show-branch", cmd_show_branch, RUN_SETUP },
{ "show", cmd_show, RUN_SETUP | USE_PAGER },
{ "stripspace", cmd_stripspace },
diff --git a/wt-status.c b/wt-status.c
new file mode 100644
index 0000000..ec2c728
--- /dev/null
+++ b/wt-status.c
@@ -0,0 +1,271 @@
+#include "wt-status.h"
+#include "color.h"
+#include "cache.h"
+#include "object.h"
+#include "dir.h"
+#include "commit.h"
+#include "diff.h"
+#include "revision.h"
+#include "diffcore.h"
+
+int wt_status_use_color = 0;
+static char wt_status_colors[][COLOR_MAXLEN] = {
+ "", /* WT_STATUS_HEADER: normal */
+ "\033[32m", /* WT_STATUS_UPDATED: green */
+ "\033[31m", /* WT_STATUS_CHANGED: red */
+ "\033[31m", /* WT_STATUS_UNTRACKED: red */
+};
+
+static int parse_status_slot(const char *var, int offset)
+{
+ if (!strcasecmp(var+offset, "header"))
+ return WT_STATUS_HEADER;
+ if (!strcasecmp(var+offset, "updated"))
+ return WT_STATUS_UPDATED;
+ if (!strcasecmp(var+offset, "changed"))
+ return WT_STATUS_CHANGED;
+ if (!strcasecmp(var+offset, "untracked"))
+ return WT_STATUS_UNTRACKED;
+ die("bad config variable '%s'", var);
+}
+
+static const char* color(int slot)
+{
+ return wt_status_use_color ? wt_status_colors[slot] : "";
+}
+
+void wt_status_prepare(struct wt_status *s)
+{
+ unsigned char sha1[20];
+ const char *head;
+
+ s->is_initial = get_sha1("HEAD", sha1) ? 1 : 0;
+
+ head = resolve_ref(git_path("HEAD"), sha1, 0);
+ s->branch = head ?
+ strdup(head + strlen(get_git_dir()) + 1) :
+ NULL;
+
+ s->reference = "HEAD";
+ s->amend = 0;
+ s->verbose = 0;
+ s->commitable = 0;
+}
+
+static void wt_status_print_header(const char *main, const char *sub)
+{
+ const char *c = color(WT_STATUS_HEADER);
+ color_printf_ln(c, "# %s:", main);
+ color_printf_ln(c, "# (%s)", sub);
+ color_printf_ln(c, "#");
+}
+
+static void wt_status_print_trailer(void)
+{
+ color_printf_ln(color(WT_STATUS_HEADER), "#");
+}
+
+static void wt_status_print_filepair(int t, struct diff_filepair *p)
+{
+ const char *c = color(t);
+ color_printf(color(WT_STATUS_HEADER), "#\t");
+ switch (p->status) {
+ case DIFF_STATUS_ADDED:
+ color_printf(c, "new file: %s", p->one->path); break;
+ case DIFF_STATUS_COPIED:
+ color_printf(c, "copied: %s -> %s",
+ p->one->path, p->two->path);
+ break;
+ case DIFF_STATUS_DELETED:
+ color_printf_ln(c, "deleted: %s", p->one->path); break;
+ case DIFF_STATUS_MODIFIED:
+ color_printf(c, "modified: %s", p->one->path); break;
+ case DIFF_STATUS_RENAMED:
+ color_printf(c, "renamed: %s -> %s",
+ p->one->path, p->two->path);
+ break;
+ case DIFF_STATUS_TYPE_CHANGED:
+ color_printf(c, "typechange: %s", p->one->path); break;
+ case DIFF_STATUS_UNKNOWN:
+ color_printf(c, "unknown: %s", p->one->path); break;
+ case DIFF_STATUS_UNMERGED:
+ color_printf(c, "unmerged: %s", p->one->path); break;
+ default:
+ die("bug: unhandled diff status %c", p->status);
+ }
+ printf("\n");
+}
+
+static void wt_status_print_updated_cb(struct diff_queue_struct *q,
+ struct diff_options *options,
+ void *data)
+{
+ struct wt_status *s = data;
+ int shown_header = 0;
+ int i;
+ if (q->nr) {
+ }
+ for (i = 0; i < q->nr; i++) {
+ if (q->queue[i]->status == 'U')
+ continue;
+ if (!shown_header) {
+ wt_status_print_header("Updated but not checked in",
+ "will commit");
+ s->commitable = 1;
+ shown_header = 1;
+ }
+ wt_status_print_filepair(WT_STATUS_UPDATED, q->queue[i]);
+ }
+ if (shown_header)
+ wt_status_print_trailer();
+}
+
+static void wt_status_print_changed_cb(struct diff_queue_struct *q,
+ struct diff_options *options,
+ void *data)
+{
+ int i;
+ if (q->nr)
+ wt_status_print_header("Changed but not updated",
+ "use git-update-index to mark for commit");
+ for (i = 0; i < q->nr; i++)
+ wt_status_print_filepair(WT_STATUS_CHANGED, q->queue[i]);
+ if (q->nr)
+ wt_status_print_trailer();
+}
+
+void wt_status_print_initial(struct wt_status *s)
+{
+ int i;
+ read_cache();
+ if (active_nr) {
+ s->commitable = 1;
+ wt_status_print_header("Updated but not checked in",
+ "will commit");
+ }
+ for (i = 0; i < active_nr; i++) {
+ color_printf(color(WT_STATUS_HEADER), "#\t");
+ color_printf_ln(color(WT_STATUS_UPDATED), "new file: %s",
+ active_cache[i]->name);
+ }
+ if (active_nr)
+ wt_status_print_trailer();
+}
+
+static void wt_status_print_updated(struct wt_status *s)
+{
+ struct rev_info rev;
+ const char *argv[] = { NULL, NULL, NULL };
+ argv[1] = s->reference;
+ init_revisions(&rev, NULL);
+ setup_revisions(2, argv, &rev, NULL);
+ rev.diffopt.output_format |= DIFF_FORMAT_CALLBACK;
+ rev.diffopt.format_callback = wt_status_print_updated_cb;
+ rev.diffopt.format_callback_data = s;
+ rev.diffopt.detect_rename = 1;
+ run_diff_index(&rev, 1);
+}
+
+static void wt_status_print_changed(struct wt_status *s)
+{
+ struct rev_info rev;
+ const char *argv[] = { NULL, NULL };
+ init_revisions(&rev, "");
+ setup_revisions(1, argv, &rev, NULL);
+ rev.diffopt.output_format |= DIFF_FORMAT_CALLBACK;
+ rev.diffopt.format_callback = wt_status_print_changed_cb;
+ rev.diffopt.format_callback_data = s;
+ run_diff_files(&rev, 0);
+}
+
+static void wt_status_print_untracked(const struct wt_status *s)
+{
+ struct dir_struct dir;
+ const char *x;
+ int i;
+ int shown_header = 0;
+
+ memset(&dir, 0, sizeof(dir));
+
+ dir.exclude_per_dir = ".gitignore";
+ x = git_path("info/exclude");
+ if (file_exists(x))
+ add_excludes_from_file(&dir, x);
+
+ read_directory(&dir, ".", "", 0);
+ for(i = 0; i < dir.nr; i++) {
+ /* check for matching entry, which is unmerged; lifted from
+ * builtin-ls-files:show_other_files */
+ struct dir_entry *ent = dir.entries[i];
+ int pos = cache_name_pos(ent->name, ent->len);
+ struct cache_entry *ce;
+ if (0 <= pos)
+ die("bug in wt_status_print_untracked");
+ pos = -pos - 1;
+ if (pos < active_nr) {
+ ce = active_cache[pos];
+ if (ce_namelen(ce) == ent->len &&
+ !memcmp(ce->name, ent->name, ent->len))
+ continue;
+ }
+ if (!shown_header) {
+ wt_status_print_header("Untracked files",
+ "use \"git add\" to add to commit");
+ shown_header = 1;
+ }
+ color_printf(color(WT_STATUS_HEADER), "#\t");
+ color_printf_ln(color(WT_STATUS_UNTRACKED), "%.*s",
+ ent->len, ent->name);
+ }
+}
+
+static void wt_status_print_verbose(struct wt_status *s)
+{
+ struct rev_info rev;
+ const char *argv[] = { NULL, NULL, NULL };
+ argv[1] = s->reference;
+ init_revisions(&rev, NULL);
+ setup_revisions(2, argv, &rev, NULL);
+ rev.diffopt.output_format |= DIFF_FORMAT_PATCH;
+ rev.diffopt.detect_rename = 1;
+ run_diff_index(&rev, 1);
+}
+
+void wt_status_print(struct wt_status *s)
+{
+ if (s->branch && strcmp(s->branch, "refs/heads/master"))
+ color_printf_ln(color(WT_STATUS_HEADER),
+ "# On branch %s", s->branch);
+
+ if (s->is_initial) {
+ color_printf_ln(color(WT_STATUS_HEADER), "#");
+ color_printf_ln(color(WT_STATUS_HEADER), "# Initial commit");
+ color_printf_ln(color(WT_STATUS_HEADER), "#");
+ wt_status_print_initial(s);
+ }
+ else {
+ wt_status_print_updated(s);
+ discard_cache();
+ }
+
+ wt_status_print_changed(s);
+ wt_status_print_untracked(s);
+
+ if (s->verbose && !s->is_initial)
+ wt_status_print_verbose(s);
+ if (!s->commitable)
+ printf("%s\n", s->amend ? "# No changes" : "nothing to commit");
+}
+
+int git_status_config(const char *k, const char *v)
+{
+ if (!strcmp(k, "status.color")) {
+ wt_status_use_color = git_config_colorbool(k, v);
+ return 0;
+ }
+ if (!strncmp(k, "status.color.", 13)) {
+ int slot = parse_status_slot(k, 13);
+ color_parse(v, k, wt_status_colors[slot]);
+ }
+ return git_default_config(k, v);
+}
diff --git a/wt-status.h b/wt-status.h
new file mode 100644
index 0000000..75d3cfe
--- /dev/null
+++ b/wt-status.h
@@ -0,0 +1,24 @@
+#ifndef STATUS_H
+#define STATUS_H
+
+enum color_wt_status {
+ WT_STATUS_HEADER,
+ WT_STATUS_UPDATED,
+ WT_STATUS_CHANGED,
+ WT_STATUS_UNTRACKED,
+};
+
+struct wt_status {
+ int is_initial;
+ char *branch;
+ const char *reference;
+ int commitable;
+ int verbose;
+ int amend;
+};
+
+int git_status_config(const char *var, const char *value);
+void wt_status_prepare(struct wt_status *s);
+void wt_status_print(struct wt_status *s);
+
+#endif /* STATUS_H */
--
1.4.2.g5290b
^ permalink raw reply related [relevance 2%]
* Re: Change set based shallow clone
@ 2006-09-08 14:20 5% ` Jon Smirl
0 siblings, 1 reply; 200+ results
From: Jon Smirl @ 2006-09-08 14:20 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Martin Langhoff, git
On 9/8/06, Junio C Hamano <junkio@cox.net> wrote:
> [*4*] In git, there is no inherent server vs client or upstream
> vs downstream relationship between repositories. You may be
> even fetching from many people and do not have a set upstream at
> all. Or you are _the_ upstream, and your notebook has the
> latest devevelopment history, and after pushing that latest
> history to your mothership repository, you may decide you do not
> want ancient development history on a puny notebook, and locally
> cauterize the history on your notebook repository and prune
> ancient stuff. The objects missing from the notebook repository
> are retrievable from your mothership repository again if/when
> needed and you as the user would know that (and if you are lucky
> you may even remember that a few months later), but git doesn't,
> and there is no reason for git to want to know it. If we want
> to do "fault-in on demand", we need to add a way to say "it is
> Ok for this repository to be incomplete -- objects that are
> missing must be completed from that repository (or those
> repositories)". But that's quite a special case of having a
> fixed upstream.
A 'not-present' object would be a normal git object, it would contain
a list of sha1s that it is stubbing for. These alias sha1s need to end
up somewhere where the git tools can find them. Maybe put all of the
'not-present' objects into their own pack and add the aliases to the
index. If the aliases point back the 'not-present' object everything
can be validated even if the alias sha1s don't match the one of the
object. This pack would be private and not sent to other repositories.
It would be useful to maintain a list of possible remote repositories
to search for the missing objects if needed. This list could be shared
with people that clone from you.
If you clone from a remote repository that is a partial copy you may
not be able to get all of the objects you want. The only choice here
is to point them to 'not-present' stub and try searching the
alternative repository list.
If you really want to build something for the future, have all of the
git repositories on the net talk to each other and use a distributed
hash scheme to spread redundant copies of the objects out over the
cloud of servers. This will have the effect of creating a global
namespace for all git projects.
--
Jon Smirl
jonsmirl@gmail.com
^ permalink raw reply [relevance 5%]
* Re: Change set based shallow clone
@ 2006-09-08 23:09 6% ` Linus Torvalds
0 siblings, 0 replies; 200+ results
From: Linus Torvalds @ 2006-09-08 23:09 UTC (permalink / raw)
To: Jon Smirl; +Cc: linux@horizon.com, Git Mailing List, Paul Mackerras
On Fri, 8 Sep 2006, Jon Smirl wrote:
>
> gitk would need to be modified to only run enough of the commit tree
> to draw what is displayed in the window. As you page down it would
> retrive more commits if needed. There is no need for gitk to run 250K
> commits when I'm usually never going to look at them all. Of course
> this may mean some rework for gitk.
Actually, it's more than a little rework.
The _real_ problem is that gitk uses "--topo-order" to git-rev-list, which
basically means that git-rev-list needs to parse EVERY SINGLE COMMIT.
So far, nobody has written a topological sort that can reasonably
efficiently handle partial trees and automatically notice when there is no
way that a DAG cannot have any more references to a commit any more (if
you can show that the result would cause a cycle, you could output a
partial topological tree early).
It's possible that no such topological sorting (ie the efficient kind,
that can work with partial DAG's) even exists.
So if you want to be able to visualize a partial repository, you need to
teach git to not need "--topo-order" first. That's likely the _big_
change. After that, the rest should be easy.
[ One way to do it might be: the normal ordering of revisions without
"--topo-order) is "_close_ to topological", and gitk could just decide
to re-compute the whole graph whenever it gets a commit that has a
parent that it has already graphed. Done right, it would probably almost
never actually generate re-computed graphs (if you only actually
generate the graph when the user scrolls down to it).
Getting rid of the --topo-order requirement would speed up gitk
absolutely immensely, especially for unpacked cold-cache archives. So it
would probably be a good thing to do, regardless of any shallow clone
issues ]
Hmm?
Linus
^ permalink raw reply [relevance 6%]
* Re: Change set based shallow clone
@ 2006-09-09 3:13 4% ` Petr Baudis
2006-09-09 8:39 3% ` Jakub Narebski
0 siblings, 1 reply; 200+ results
From: Petr Baudis @ 2006-09-09 3:13 UTC (permalink / raw)
To: Jakub Narebski; +Cc: git
Dear diary, on Fri, Sep 08, 2006 at 05:50:40PM CEST, I got a letter
where Jakub Narebski <jnareb@gmail.com> said that...
> My idea for lazy clone/fetch (lazy = on-demand) is via remote alternatives
> mechanism. We put URI for repository (repositories) that hosts the project,
> and we would need at start to download at least heads and tags, and only
> heads and tags.
One thing to note is that you won't last very long without getting
at least basically all the commits from the history. git log, git
merge-base and such would either just suck them all, get partially moved
to the server side, or would undergo quite a painful and slooooooooow
process "get me commit X... thank you, sir. hmm, it appears that its
parent is commit Y. could you get me commit Y, please...? thank you,
sir. hmm, it appears...".
--
Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
Snow falling on Perl. White noise covering line noise.
Hides all the bugs too. -- J. Putnam
^ permalink raw reply [relevance 4%]
* Re: Change set based shallow clone
2006-09-09 3:13 4% ` Petr Baudis
@ 2006-09-09 8:39 3% ` Jakub Narebski
0 siblings, 0 replies; 200+ results
From: Jakub Narebski @ 2006-09-09 8:39 UTC (permalink / raw)
To: git
Petr Baudis wrote:
> Dear diary, on Fri, Sep 08, 2006 at 05:50:40PM CEST, I got a letter
> where Jakub Narebski <jnareb@gmail.com> said that...
>> My idea for lazy clone/fetch (lazy = on-demand) is via remote alternatives
>> mechanism. We put URI for repository (repositories) that hosts the project,
>> and we would need at start to download at least heads and tags, and only
>> heads and tags.
>
> One thing to note is that you won't last very long without getting
> at least basically all the commits from the history. git log, git
> merge-base and such would either just suck them all, get partially moved
> to the server side, or would undergo quite a painful and slooooooooow
> process "get me commit X... thank you, sir. hmm, it appears that its
> parent is commit Y. could you get me commit Y, please...? thank you,
> sir. hmm, it appears...".
As I said there is load of troubles with lazy clone/fetch = remote
alternatives I didn't thought about.
git log/git rev-list and git fsck-objects among them.
--
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git
^ permalink raw reply [relevance 3%]
* [PATCH] branch: write branch properties
@ 2006-09-24 22:42 4% Santi Béjar
2006-09-24 23:00 4% ` Santi Béjar
0 siblings, 1 reply; 200+ results
From: Santi Béjar @ 2006-09-24 22:42 UTC (permalink / raw)
To: git
If you want to work in the 'next' branch of git.git:
$ git clone --use-separate-remote git://git.kernel.org/pub/scm/git/git.git
$ cd git
$ git branch next origin next
Signed-off-by: Santi Béjar <sbejar@gmail.com>
---
Documentation/git-branch.txt | 7 +++++--
git-branch.sh | 17 +++++++++++++++--
git-parse-remote.sh | 21 +++++++++++++++++++++
3 files changed, 41 insertions(+), 4 deletions(-)
diff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt
index d43ef1d..de2889d 100644
--- a/Documentation/git-branch.txt
+++ b/Documentation/git-branch.txt
@@ -9,7 +9,7 @@ SYNOPSIS
--------
[verse]
'git-branch' [-r]
-'git-branch' [-l] [-f] <branchname> [<start-point>]
+'git-branch' [-l] [-f] <branchname> [<start-point> | <remote> <remotebranch>]
'git-branch' (-d | -D) <branchname>...
DESCRIPTION
@@ -18,9 +18,12 @@ With no arguments given (or just `-r`) a
will be shown, the current branch will be highlighted with an asterisk.
In its second form, a new branch named <branchname> will be created.
-It will start out with a head equal to the one given as <start-point>.
+It will start out with a head equal to the one given as <start-point>,
+or from branch <remotebranch> of the repository <remote>.
If no <start-point> is given, the branch will be created with a head
equal to that of the currently checked out branch.
+In the form <remote> <remotebranch> it will also record the branch
+properties `branch.<branchname>.remote` and `branch.<branchname>.merge`.
With a `-d` or `-D` option, `<branchname>` will be deleted. You may
specify more than one branch for deletion. If the branch currently
diff --git a/git-branch.sh b/git-branch.sh
index e0501ec..94dd157 100755
--- a/git-branch.sh
+++ b/git-branch.sh
@@ -1,9 +1,10 @@
#!/bin/sh
-USAGE='[-l] [(-d | -D) <branchname>] | [[-f] <branchname> [<start-point>]] | -r'
+USAGE='[-l] [(-d | -D) <branchname>] | [[-f] <branchname> [<start-point> | <remote> <remotebranch>]] | -r'
LONG_USAGE='If no arguments, show available branches and mark current branch with a star.
If one argument, create a new branch <branchname> based off of current HEAD.
-If two arguments, create a new branch <branchname> based off of <start-point>.'
+If two arguments, create a new branch <branchname> based off of <start-point>.
+If three arguments, create a new branch <branchname> based off the branch <remotebranch> of the repository <remote>, writing the branch properties for fetch.'
SUBDIRECTORY_OK='Yes'
. git-sh-setup
@@ -104,6 +105,12 @@ case "$#" in
head=HEAD ;;
2)
head="$2^0" ;;
+3)
+ remote="$2"
+ remote_branch="$3"
+ . ./git-parse-remote.sh
+ ref=$(get_ref_for_remote_branch "$2" "$3")
+ head="$ref^0";;
esac
branchname="$1"
@@ -128,3 +135,9 @@ then
touch "$GIT_DIR/logs/refs/heads/$branchname"
fi
git update-ref -m "branch: Created from $head" "refs/heads/$branchname" $rev
+
+if test -n "$ref"
+then
+ git repo-config branch."$branchname".remote "$remote"
+ git repo-config branch."$branchname".merge "$remote_branch"
+fi
diff --git a/git-parse-remote.sh b/git-parse-remote.sh
index 187f088..51f3b9b 100755
--- a/git-parse-remote.sh
+++ b/git-parse-remote.sh
@@ -209,3 +209,24 @@ resolve_alternates () {
esac
done
}
+
+get_ref_for_remote_branch (){
+ data_source=$(get_data_source "$1")
+ case "$data_source" in
+ '' | config-partial | branches | branches-partial)
+ ;;
+ config)
+ ref=$(git-repo-config --get-all "remote.$1.fetch" |\
+ grep "^$2:")
+ expr "z$ref" : 'z[^:]*:\(.*\)'
+ ;;
+ remotes)
+ ref=$(sed -ne '/^Pull: */{
+ s///p
+ }' "$GIT_DIR/remotes/$1" | grep "$2:")
+ expr "z$ref" : 'z[^:]*:\(.*\)'
+ ;;
+ *)
+ die "internal error: get-ref-for-remote-branch $1 $2" ;;
+ esac
+}
--
1.4.2.1.g279b
^ permalink raw reply related [relevance 4%]
* Re: [PATCH] branch: write branch properties
2006-09-24 22:42 4% [PATCH] branch: write branch properties Santi Béjar
@ 2006-09-24 23:00 4% ` Santi Béjar
2006-09-25 0:41 4% ` Santi Béjar
0 siblings, 1 reply; 200+ results
From: Santi Béjar @ 2006-09-24 23:00 UTC (permalink / raw)
To: git
Santi Béjar <sbejar@gmail.com> writes:
> If you want to work in the 'next' branch of git.git:
>
> $ git clone --use-separate-remote git://git.kernel.org/pub/scm/git/git.git
> $ cd git
> $ git branch next origin next
this has to be: git branch next origin refs/heads/next
and then you work as usual with:
... work
$ git pull
and it does the right thing.
Please use this instead:
-- >8 --
[PATCH] branch: write branch properties
If you want to work in the 'next' branch of git.git:
$ git clone --use-separate-remote git://git.kernel.org/pub/scm/git/git.git
$ cd git
$ git branch next origin refs/heads/next
... work/edit/commit ...
$ git pull
and it merges from branch 'refs/heads/next' of origin.
Signed-off-by: Santi Béjar <sbejar@gmail.com>
---
Documentation/git-branch.txt | 7 +++++--
git-branch.sh | 17 +++++++++++++++--
git-parse-remote.sh | 21 +++++++++++++++++++++
3 files changed, 41 insertions(+), 4 deletions(-)
diff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt
index d43ef1d..de2889d 100644
--- a/Documentation/git-branch.txt
+++ b/Documentation/git-branch.txt
@@ -9,7 +9,7 @@ SYNOPSIS
--------
[verse]
'git-branch' [-r]
-'git-branch' [-l] [-f] <branchname> [<start-point>]
+'git-branch' [-l] [-f] <branchname> [<start-point> | <remote> <remotebranch>]
'git-branch' (-d | -D) <branchname>...
DESCRIPTION
@@ -18,9 +18,12 @@ With no arguments given (or just `-r`) a
will be shown, the current branch will be highlighted with an asterisk.
In its second form, a new branch named <branchname> will be created.
-It will start out with a head equal to the one given as <start-point>.
+It will start out with a head equal to the one given as <start-point>,
+or from branch <remotebranch> of the repository <remote>.
If no <start-point> is given, the branch will be created with a head
equal to that of the currently checked out branch.
+In the form <remote> <remotebranch> it will also record the branch
+properties `branch.<branchname>.remote` and `branch.<branchname>.merge`.
With a `-d` or `-D` option, `<branchname>` will be deleted. You may
specify more than one branch for deletion. If the branch currently
diff --git a/git-branch.sh b/git-branch.sh
index e0501ec..94dd157 100755
--- a/git-branch.sh
+++ b/git-branch.sh
@@ -1,9 +1,10 @@
#!/bin/sh
-USAGE='[-l] [(-d | -D) <branchname>] | [[-f] <branchname> [<start-point>]] | -r'
+USAGE='[-l] [(-d | -D) <branchname>] | [[-f] <branchname> [<start-point> | <remote> <remotebranch>]] | -r'
LONG_USAGE='If no arguments, show available branches and mark current branch with a star.
If one argument, create a new branch <branchname> based off of current HEAD.
-If two arguments, create a new branch <branchname> based off of <start-point>.'
+If two arguments, create a new branch <branchname> based off of <start-point>.
+If three arguments, create a new branch <branchname> based off the branch <remotebranch> of the repository <remote>, writing the branch properties for fetch.'
SUBDIRECTORY_OK='Yes'
. git-sh-setup
@@ -104,6 +105,12 @@ case "$#" in
head=HEAD ;;
2)
head="$2^0" ;;
+3)
+ remote="$2"
+ remote_branch="$3"
+ . ./git-parse-remote.sh
+ ref=$(get_ref_for_remote_branch "$2" "$3")
+ head="$ref^0";;
esac
branchname="$1"
@@ -128,3 +135,9 @@ then
touch "$GIT_DIR/logs/refs/heads/$branchname"
fi
git update-ref -m "branch: Created from $head" "refs/heads/$branchname" $rev
+
+if test -n "$ref"
+then
+ git repo-config branch."$branchname".remote "$remote"
+ git repo-config branch."$branchname".merge "$remote_branch"
+fi
diff --git a/git-parse-remote.sh b/git-parse-remote.sh
index 187f088..51f3b9b 100755
--- a/git-parse-remote.sh
+++ b/git-parse-remote.sh
@@ -209,3 +209,24 @@ resolve_alternates () {
esac
done
}
+
+get_ref_for_remote_branch (){
+ data_source=$(get_data_source "$1")
+ case "$data_source" in
+ '' | config-partial | branches | branches-partial)
+ ;;
+ config)
+ ref=$(git-repo-config --get-all "remote.$1.fetch" |\
+ grep "^$2:")
+ expr "z$ref" : 'z[^:]*:\(.*\)'
+ ;;
+ remotes)
+ ref=$(sed -ne '/^Pull: */{
+ s///p
+ }' "$GIT_DIR/remotes/$1" | grep "$2:")
+ expr "z$ref" : 'z[^:]*:\(.*\)'
+ ;;
+ *)
+ die "internal error: get-ref-for-remote-branch $1 $2" ;;
+ esac
+}
--
1.4.2.1.g279b
^ permalink raw reply related [relevance 4%]
* Re: [PATCH] branch: write branch properties
2006-09-24 23:00 4% ` Santi Béjar
@ 2006-09-25 0:41 4% ` Santi Béjar
0 siblings, 0 replies; 200+ results
From: Santi Béjar @ 2006-09-25 0:41 UTC (permalink / raw)
To: git
Hi *,
>
> Please use this instead:
>
or even this, sorry:
* . ./git-parse-remotes.sh?
* not a bug, but test for $remote and $remote_branch instead of $ref.
-- >8 --
[PATCH] branch: write branch properties
If you want to work in the 'next' branch of git.git:
$ git clone --use-separate-remote git://git.kernel.org/pub/scm/git/git.git
$ cd git
$ git branch next origin refs/heads/next
... work/edit/commit ...
$ git pull
and it merges from branch 'refs/heads/next' of origin.
Signed-off-by: Santi Béjar <sbejar@gmail.com>
---
Documentation/git-branch.txt | 7 +++++--
git-branch.sh | 17 +++++++++++++++--
git-parse-remote.sh | 21 +++++++++++++++++++++
3 files changed, 41 insertions(+), 4 deletions(-)
diff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt
index d43ef1d..de2889d 100644
--- a/Documentation/git-branch.txt
+++ b/Documentation/git-branch.txt
@@ -9,7 +9,7 @@ SYNOPSIS
--------
[verse]
'git-branch' [-r]
-'git-branch' [-l] [-f] <branchname> [<start-point>]
+'git-branch' [-l] [-f] <branchname> [<start-point> | <remote> <remotebranch>]
'git-branch' (-d | -D) <branchname>...
DESCRIPTION
@@ -18,9 +18,12 @@ With no arguments given (or just `-r`) a
will be shown, the current branch will be highlighted with an asterisk.
In its second form, a new branch named <branchname> will be created.
-It will start out with a head equal to the one given as <start-point>.
+It will start out with a head equal to the one given as <start-point>,
+or from branch <remotebranch> of the repository <remote>.
If no <start-point> is given, the branch will be created with a head
equal to that of the currently checked out branch.
+In the form <remote> <remotebranch> it will also record the branch
+properties `branch.<branchname>.remote` and `branch.<branchname>.merge`.
With a `-d` or `-D` option, `<branchname>` will be deleted. You may
specify more than one branch for deletion. If the branch currently
diff --git a/git-branch.sh b/git-branch.sh
index e0501ec..78e2c92 100755
--- a/git-branch.sh
+++ b/git-branch.sh
@@ -1,9 +1,10 @@
#!/bin/sh
-USAGE='[-l] [(-d | -D) <branchname>] | [[-f] <branchname> [<start-point>]] | -r'
+USAGE='[-l] [(-d | -D) <branchname>] | [[-f] <branchname> [<start-point> | <remote> <remotebranch>]] | -r'
LONG_USAGE='If no arguments, show available branches and mark current branch with a star.
If one argument, create a new branch <branchname> based off of current HEAD.
-If two arguments, create a new branch <branchname> based off of <start-point>.'
+If two arguments, create a new branch <branchname> based off of <start-point>.
+If three arguments, create a new branch <branchname> based off the branch <remotebranch> of the repository <remote>, writing the branch properties for fetch.'
SUBDIRECTORY_OK='Yes'
. git-sh-setup
@@ -104,6 +105,12 @@ case "$#" in
head=HEAD ;;
2)
head="$2^0" ;;
+3)
+ remote="$2"
+ remote_branch="$3"
+ . git-parse-remote
+ ref=$(get_ref_for_remote_branch "$2" "$3")
+ head="$ref^0";;
esac
branchname="$1"
@@ -128,3 +135,9 @@ then
touch "$GIT_DIR/logs/refs/heads/$branchname"
fi
git update-ref -m "branch: Created from $head" "refs/heads/$branchname" $rev
+
+if test -n "$remote" && test -n "$remote_branch"
+then
+ git repo-config branch."$branchname".remote "$remote"
+ git repo-config branch."$branchname".merge "$remote_branch"
+fi
diff --git a/git-parse-remote.sh b/git-parse-remote.sh
index 187f088..51f3b9b 100755
--- a/git-parse-remote.sh
+++ b/git-parse-remote.sh
@@ -209,3 +209,24 @@ resolve_alternates () {
esac
done
}
+
+get_ref_for_remote_branch (){
+ data_source=$(get_data_source "$1")
+ case "$data_source" in
+ '' | config-partial | branches | branches-partial)
+ ;;
+ config)
+ ref=$(git-repo-config --get-all "remote.$1.fetch" |\
+ grep "^$2:")
+ expr "z$ref" : 'z[^:]*:\(.*\)'
+ ;;
+ remotes)
+ ref=$(sed -ne '/^Pull: */{
+ s///p
+ }' "$GIT_DIR/remotes/$1" | grep "$2:")
+ expr "z$ref" : 'z[^:]*:\(.*\)'
+ ;;
+ *)
+ die "internal error: get-ref-for-remote-branch $1 $2" ;;
+ esac
+}
--
1.4.2.1.gf2ca-dirty
^ permalink raw reply related [relevance 4%]
* Re: VCS comparison table
@ 2006-10-14 20:20 2% ` Jakub Narebski
2006-10-14 23:06 0% ` Jon Smirl
2 siblings, 1 reply; 200+ results
From: Jakub Narebski @ 2006-10-14 20:20 UTC (permalink / raw)
To: git
Jon Smirl wrote:
> I was reading Brendan's blog post about Mozilla 2
> http://weblogs.mozillazine.org/roadmap/archives/2006/10/mozilla_2.html
You mean:
"Oh, and isn't it time that we get off of CVS? The best way to do that
without throwing 1.9 into an uproar is to develop Mozilla 2 using a new
Version Control System (VCS) that can merge with CVS (since we will want
to track changes to files not being revamped at first, or at all; and
we'll probably find bugs whose fixes should flow back into 1.9). The
problem with VCSes is that there are too many to choose from now.
Nevertheless, looking for mostly green columns in that chart should help
us make a quick decision. We don't need "the best" or the "newest", but we
do need better merging, branching, and renaming support."
There is work by Jon Smirl and Shawn Pearce on CVS to Git importer which can
manage large and complicated (read: f*cked-up) Mozilla CVS repository.
http://git.or.cz/gitwiki/InterfacesFrontendsAndTools#cvs2git
By the way, I'd rather use SCM comparison table on neutral site, not on SCM
site.
I think that Mozilla project should come with it's own set of requirements
and weights for best SCM _for Mozilla project_.
1. Converting existing CVS repository. This should be without data loss...
well, beside data loss that stems from using CVS in first place. "Best" SCM
would have:
* Tool to convert CVS repository, which can then incrementally import
changes.
* It would be nice to have tool to exchange commits between SCM and CVS,
be it like Tailor/git-svn, or via incremental import and exporting
commits to CVS like git-cvsexportcommit. This would ease changing SCM,
as both new SCM and CVS could be deployed in parallel, for a short time
of course.
* It would be nice to have CVS emulation like git-cvsserver, so users
accustomed to CVS could still use it.
2. Good support for system which most important developers use, and good
support for system which most contributors use. If MS Windows is included
in those, then Git perhaps wouldn't be the best choice.
3. Good support for the workflow used in the project. Is it exchanging
patches via email (hello, Git!), having ssh access to some central
repository with central repository to push changes to or net/mesh of
repositories exchanging information, posting patches on some bug tracking
software integrated with SCM. Is it using many branches (topic branches),
or is it using few branches and merging.
But it is equally important to realize what would be the best workflow to
use, not constraining itself to the workflow imposed by limitations of CVS.
4. Good support for _large_ project, with large history. Namely, that
developer wouldn't need to download many megabytes and/or wouldn't need
megabytes of working area. How that is solved, be it partial checkouts,
lazy/shallow/sparse clone, subprojects, splitting into
projects/repositories and having some superproject or build-time
superproject, splitting repository into current and historical... that of
course depends on SCM.
5. ....
and probably few more
--
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git
^ permalink raw reply [relevance 2%]
* Re: VCS comparison table
2006-10-14 20:20 2% ` Jakub Narebski
@ 2006-10-14 23:06 0% ` Jon Smirl
` (2 more replies)
0 siblings, 3 replies; 200+ results
From: Jon Smirl @ 2006-10-14 23:06 UTC (permalink / raw)
To: Jakub Narebski; +Cc: git
On 10/14/06, Jakub Narebski <jnareb@gmail.com> wrote:
> Jon Smirl wrote:
>
> > I was reading Brendan's blog post about Mozilla 2
> > http://weblogs.mozillazine.org/roadmap/archives/2006/10/mozilla_2.html
>
> You mean:
> "Oh, and isn't it time that we get off of CVS? The best way to do that
> without throwing 1.9 into an uproar is to develop Mozilla 2 using a new
> Version Control System (VCS) that can merge with CVS (since we will want
> to track changes to files not being revamped at first, or at all; and
> we'll probably find bugs whose fixes should flow back into 1.9). The
> problem with VCSes is that there are too many to choose from now.
> Nevertheless, looking for mostly green columns in that chart should help
> us make a quick decision. We don't need "the best" or the "newest", but we
> do need better merging, branching, and renaming support."
>
> There is work by Jon Smirl and Shawn Pearce on CVS to Git importer which can
> manage large and complicated (read: f*cked-up) Mozilla CVS repository.
> http://git.or.cz/gitwiki/InterfacesFrontendsAndTools#cvs2git
I am still working with the developers of the cvs2svn import tool to
fix things so that Mozilla CVS can be correctly imported. There are
still outstanding bugs in cvs2svn preventing a correct import. MozCVS
can be imported, but the resulting repository is not entirely correct.
Once they get the base cvs2svn fixed I'll port my patches to turn it
into cvs2git again.
There is no existing CVS importer that will correctly import the
Mozilla CVS. I have tried them all.
> By the way, I'd rather use SCM comparison table on neutral site, not on SCM
> site.
>
>
> I think that Mozilla project should come with it's own set of requirements
> and weights for best SCM _for Mozilla project_.
>
> 1. Converting existing CVS repository. This should be without data loss...
> well, beside data loss that stems from using CVS in first place. "Best" SCM
> would have:
> * Tool to convert CVS repository, which can then incrementally import
> changes.
> * It would be nice to have tool to exchange commits between SCM and CVS,
> be it like Tailor/git-svn, or via incremental import and exporting
> commits to CVS like git-cvsexportcommit. This would ease changing SCM,
> as both new SCM and CVS could be deployed in parallel, for a short time
> of course.
>From what Brendan wrote they are looking to continue 1.9 in CVS and
start 2.0 in a new SCM. This pretty much mandates tracking CVS into
the new SCM for a long period of time. Possibly as much as two years.
There does not appear to be a need to push 2.0 back into CVS.
> * It would be nice to have CVS emulation like git-cvsserver, so users
> accustomed to CVS could still use it.
This can also solve some of the problems with Windows support.
>
> 2. Good support for system which most important developers use, and good
> support for system which most contributors use. If MS Windows is included
> in those, then Git perhaps wouldn't be the best choice.
Better Windows support is needed to make git the first choice among
the various SCMs.
>
> 3. Good support for the workflow used in the project. Is it exchanging
> patches via email (hello, Git!), having ssh access to some central
> repository with central repository to push changes to or net/mesh of
> repositories exchanging information, posting patches on some bug tracking
> software integrated with SCM. Is it using many branches (topic branches),
> or is it using few branches and merging.
>
> But it is equally important to realize what would be the best workflow to
> use, not constraining itself to the workflow imposed by limitations of CVS.
A big problem for Mozilla is outside companies doing major work in a
local CVS. Since CVS is not decentralized these local repos drift away
from the main one over time making things hard to merge. Any new SCM
will have to be distributed.
> 4. Good support for _large_ project, with large history. Namely, that
> developer wouldn't need to download many megabytes and/or wouldn't need
> megabytes of working area. How that is solved, be it partial checkouts,
> lazy/shallow/sparse clone, subprojects, splitting into
> projects/repositories and having some superproject or build-time
> superproject, splitting repository into current and historical... that of
> course depends on SCM.
git has issues here. The smallest Mozilla download we have built so
far is 450MB for the initial checkout.
>
> 5. ....
>
> and probably few more
The three most complex repositories are the kernel, gcc and Mozilla.
Gcc is in SVN now. Mozilla CVS and the kernel git.
There are much larger repositories around for some of the distros, but
they are doing things like checking ISO images in to the repo which
just makes it big,, not complex.
Top two git issues effecting Mozilla choosing it
1) some way to avoid the initial 450MB download
2) better windows support
--
Jon Smirl
jonsmirl@gmail.com
^ permalink raw reply [relevance 0%]
* Re: VCS comparison table
2006-10-14 23:06 0% ` Jon Smirl
@ 2006-10-15 0:53 1% ` Jakub Narebski
2006-10-15 18:23 0% ` Petr Baudis
2 siblings, 0 replies; 200+ results
From: Jakub Narebski @ 2006-10-15 0:53 UTC (permalink / raw)
To: Jon Smirl; +Cc: git
Jon Smirl wrote:
> On 10/14/06, Jakub Narebski <jnareb@gmail.com> wrote:
>> * It would be nice to have tool to exchange commits between SCM and CVS,
>> be it like Tailor/git-svn, or via incremental import and exporting
>> commits to CVS like git-cvsexportcommit. This would ease changing SCM,
>> as both new SCM and CVS could be deployed in parallel, for a short time
>> of course.
>
> From what Brendan wrote they are looking to continue 1.9 in CVS and
> start 2.0 in a new SCM. This pretty much mandates tracking CVS into
> the new SCM for a long period of time. Possibly as much as two years.
> There does not appear to be a need to push 2.0 back into CVS.
That of course limits what we can do in 1.9 to what CVS supports.
> > * It would be nice to have CVS emulation like git-cvsserver, so users
> > accustomed to CVS could still use it.
>
> This can also solve some of the problems with Windows support.
Well, git-cvsserver (perhaps with some improvements) could also serve as
CVS server for 1.9.
> > 4. Good support for _large_ project, with large history. Namely, that
> > developer wouldn't need to download many megabytes and/or wouldn't need
> > megabytes of working area. How that is solved, be it partial checkouts,
> > lazy/shallow/sparse clone, subprojects, splitting into
> > projects/repositories and having some superproject or build-time
> > superproject, splitting repository into current and historical... that of
> > course depends on SCM.
>
> git has issues here. The smallest Mozilla download we have built so
> far is 450MB for the initial checkout.
One way to reduce repository size would be to split fairly independent
subprojects (inependent = independently testable) into separate repositories,
and perhaps use some kind of "super-repository" (common repository) to join
all the project in one single entity. The split can be done using
git-splitrepo (or something like that) which was posted on git mailing list
(most probably by some member of X.Org), or just cg-admin-rewritehist.
While at it we could split repository into current work and historical repo;
and clean up current work repository from the cruft accumulated (e.g. dead
branches, broken tags etc.).
Another way is to use grafts.
Linux kernel has it's current repository (starting somewhere 2.6.x),
and it's historical repository. I don't remember how they arrived at it
(and don't want to check KernelTrap articles), if the seed for current
work repository was simply project import at some state, or (very slow)
import of BitKeeper history. But if I remember correctly it was born split.
You can join both repositories into one (wrt. log and diff for example)
using grafts.
I'm not sure what happens if you pull from repository which has graft
file "cauterizing" history; would you get graft file and history up to
cutoff point? What would happen if your repository, repository you pull to
has cauterization graft file; would it get cut history? Of course
the problem (and the source of proposal and troubles with implementing
of shallow/sparse/lazy clone) lies if someone branches (in public repo)
from below cutoff point. But that is a matter of policy.
But it is true that the size of Mozilla repository is a challenge.
BTW. do you perchance know how other SCM dels with the repository
of that size?
--
Jakub Narebski
ShadeHawk on #git
Poland
^ permalink raw reply [relevance 1%]
* Re: VCS comparison table
[not found] ` <20061014214452.8c2d2a5c.seanlkml@sympatico.ca>
@ 2006-10-15 1:44 1% ` Sean
0 siblings, 0 replies; 200+ results
From: Sean @ 2006-10-15 1:44 UTC (permalink / raw)
To: Jon Smirl; +Cc: Jakub Narebski, git
On Sat, 14 Oct 2006 20:34:22 -0400
"Jon Smirl" <jonsmirl@gmail.com> wrote:
> That is possible but I wish git had tools supporting this. What do you
> do about core developers that want the full repo syncing to other
> developers that only have a partial copy?
I don't think that will be an issue at all.
As an example, take the current Linux kernel repo maintained by Linus,
and one of the repos containing old historic kernel data imported into
Git. Graft in the old historic data into your clone of Linus' repo,
and you're done. Anyone can pull from you even if they don't have the
historic data themselves.
With a little work you could do the same thing with the Mozilla data.
After you decide where to make the split, you'd have to rewrite the
commit history for the "current" repository, so that it terminates
at an initial commit rather than having a direct connection to the
historic data. After that, the repos could be used just as described
above, separately or graphed together.
As far as I know though, there is still no way to use the git protocol
for the initial pull of such a combined repository. You have to pull
both repos separately and graft them together locally. This sounds
harder than it is though and can be scripted easily.
Sean
^ permalink raw reply [relevance 1%]
* Re: VCS comparison table
2006-10-14 23:06 0% ` Jon Smirl
2006-10-15 0:53 1% ` Jakub Narebski
@ 2006-10-15 18:23 0% ` Petr Baudis
2 siblings, 0 replies; 200+ results
From: Petr Baudis @ 2006-10-15 18:23 UTC (permalink / raw)
To: Jon Smirl; +Cc: Jakub Narebski, git
Dear diary, on Sun, Oct 15, 2006 at 01:06:10AM CEST, I got a letter
where Jon Smirl <jonsmirl@gmail.com> said that...
> On 10/14/06, Jakub Narebski <jnareb@gmail.com> wrote:
> >There is work by Jon Smirl and Shawn Pearce on CVS to Git importer which
> >can
> >manage large and complicated (read: f*cked-up) Mozilla CVS repository.
> > http://git.or.cz/gitwiki/InterfacesFrontendsAndTools#cvs2git
>
> I am still working with the developers of the cvs2svn import tool to
> fix things so that Mozilla CVS can be correctly imported. There are
> still outstanding bugs in cvs2svn preventing a correct import. MozCVS
> can be imported, but the resulting repository is not entirely correct.
>
> Once they get the base cvs2svn fixed I'll port my patches to turn it
> into cvs2git again.
So what exactly is the cvs2git status now? AFAIU, there's a tool that
parses the CVS repository and that is then "piped" to git-fastimport?
git-fastimport is available somewhere (perhaps it would be interesting
to publish it at repo.or.cz or something), is the current cvs2git
version available as well?
> >2. Good support for system which most important developers use, and good
> >support for system which most contributors use. If MS Windows is included
> >in those, then Git perhaps wouldn't be the best choice.
>
> Better Windows support is needed to make git the first choice among
> the various SCMs.
And this is probably not likely to happen soon.
Well, I'm enlisted in a "Programming in Windows" course at my university
now and I had this kind of thoughts, but I really can't promise
anything. :-)
> >4. Good support for _large_ project, with large history. Namely, that
> >developer wouldn't need to download many megabytes and/or wouldn't need
> >megabytes of working area. How that is solved, be it partial checkouts,
> >lazy/shallow/sparse clone, subprojects, splitting into
> >projects/repositories and having some superproject or build-time
> >superproject, splitting repository into current and historical... that of
> >course depends on SCM.
>
> git has issues here. The smallest Mozilla download we have built so
> far is 450MB for the initial checkout.
(BTW, yes, grafting the old history could help this time, but it is a
hack and not a good long-term solution - it is just putting the real
solution away until the project history will re-grew. Periodical
regrafting is even worse hack, since at that moment you break
fast-forwarding and this kind of "restarting the history" breaks deep
into the Git distributiveness.)
> >5. ....
> >
> >and probably few more
>
>
> The three most complex repositories are the kernel, gcc and Mozilla.
> Gcc is in SVN now. Mozilla CVS and the kernel git.
I believe OpenOffice CVS probably beats all three hands down very
easily. KDE is also very big, and I don't think NetBSD is just ISO
images either (if it contains any at all).
--
Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
#!/bin/perl -sp0777i<X+d*lMLa^*lN%0]dsXx++lMlN/dsM0<j]dsj
$/=unpack('H*',$_);$_=`echo 16dio\U$k"SK$/SM$n\EsN0p[lN*1
lK[d2%Sa2/d0$^Ixp"|dc`;s/\W//g;$_=pack('H*',/((..)*)$/)
^ permalink raw reply [relevance 0%]
* Re: VCS comparison table
@ 2006-10-20 22:50 3% ` Jakub Narebski
0 siblings, 0 replies; 200+ results
From: Jakub Narebski @ 2006-10-20 22:50 UTC (permalink / raw)
To: James Henstridge
Cc: bazaar-ng, Linus Torvalds, Carl Worth, Andreas Ericsson, git
On 20-10-2006, James Henstridge wrote:
> On 20/10/06, Jakub Narebski <jnareb@gmail.com> wrote:
>> James Henstridge wrote:
>>> With the above layout, I would just type:
>>> bzr branch http://server/repo/branch1
>>
>> With Cogito (you can think of it either as alternate Git UI, or as SCM
>> built on top of Git) you would use
>>
>> $ cg clone http://server/repo#branch
>>
>> for example
>>
>> $ cg clone git://git.kernel.org/pub/scm/git/git.git#next
>>
>> to clone _single_ branch (in bzr terminology, "heavy checkout" of branch).
>
> My understanding of git is that this would be equivalent to the "bzr
> branch" command. A checkout (heavy or lightweight) has the property
> that commits are made to the original branch.
Not exactly (my mistake in explaining it). "cg clone git://host/repo@branch"
clones only part of history DAG of commits reachable from given branch.
Still it is full repository. You can add branches to it later with
cg-branch-add and fetch changes with cg-fetch.
>> But you can also clone _whole_ repository, _all_ published branches with
>>
>> $ cg clone git://git.kernel.org/pub/scm/git/git.git
>
> I suppose that'd be useful if you want a copy of all the branches at
> once. There is no builtin command in Bazaar to do that at present.
That is _very_ useful. And that is default option for Git. For
example with git.git repository I'm interested both in 'master'
branch (main line of development), and in 'next' branch (development
branch). For example I send some patches, based on 'master', they
get accepted but in 'next' (to cook for a while for example), and
I want to do further work in this direction I have to base my
new work on 'next' branch.
It looks like the Bazaar-NG "branches" are equivalent of the
one-branch-clone of Git.
And if there is no command to clone whole repository, how
you do public repository?
See below.
[...]
> Two points:
> (1) if we are publishing branches, we wouldn't include working trees
> -- they are not needed to pull or merge from such a branch.
Same with Git. Public repositories are usually "bare" clones, i.e.
without working directory. We can clone/fetch from "clothed" repo
without problem - we just have to point to .git.
> (2) if we did have working trees, they'd be rooted at /repo/branch1
> and /repo/branch2 -- not at /repo (since /repo is not a branch).
That's explains it.
> In case (2) there is a potential for conflicts if you nest branches,
> but people don't generally trigger this problem with the way they use
> Bazaar.
There is no problem in Git to have git repository nested within
working area: of course you better ignore .git directory; you can
ignore files in this embedded repository or not.
[...]
>> How checked out working area looks like in Bazaar-NG?
>
> The layout of a standalone branch would be:
> .bzr/repository/ -- storage of trees and metadata
> .bzr/branch/ -- branch metadagta (e.g. pointer to the head revision)
> .bzr/checkout/ -- working tree book-keeping files
> source code
The layout of git repository (git clone, as it is equivalent of bzr branch)
you have the following layout:
.git/objects/ -- repository objects database
.git/refs/ -- heads (branches) and tags
.git/index -- staging area for commit (adding files, merge resolving)
.git/HEAD -- which branch is current branch
source code
> If we use a shared repository, the contained branches would lack the
> .bzr/repository/ directory. The parent directory would instead have a
> .bzr/repository/, but usually wouldn't have .bzr/branch/ (unless there
> is a branch rooted at the base of the repository).
The equivalent of shared repository would be having .git/objects/
to be symlink to some directory which would serve as common area
to store object database.
You can use alternates file: .git/objects/info/alternates can have
list of absolute pathnames (one per line) where objects can be found
instead. If I understand correctly new objects gets commited to current
repository object database, therefore to have equivalent of symlinking
.git/objects directory you would have for every repository which you
want to share object database to have in alternates file all repositories
except self.
Or you can use GIT_ALTERNATE_OBJECT_DIRECTORIES environmental variable.
Repository using any kind of alternates mechanism is not suitable
to publish using "dumb" (non-git-aware) transports.
> if we are publishing a branch to a web server, we'd skip the working
> tree, so the source code and .bzr/checkout/ directory would be
> missing.
For "bare" clone only 'source files' would be missing. Well, perhaps
also '.git/index' but I'm not sure.
> In the case of a checkout, the .bzr/branch/ directory has a special
> format and acts as a pointer to the original branch. If the checkout
> is lightweight, the .bzr/repository/ directory would be missing, and
> bzr would need to contact the original branch for the data.
There is no equivalent for bzr "checkout" (and could you please use
other name for that, like "lazy branch"?) in Git. There was some talk
about how to do "lazy clone"/"remote alternates" in Git, but no consensus
was reached about how to do this effectively, and for both "dumb"
(http, https, ftp, rsync) transports and git-aware (local, git, ssh+git)
transports. From what I've read Bazaar-NG doesn't try the "effective"
part...
[...]
>> Yes, but using Git that way has serious disadvantages. For example
>> there is only one current branch pointer and only one index (dircache)
>> per git repository.
>
> Okay. So using Bazaar terminology, this seems to be an issue of the
> working tree being associated with the repository rather than the
> branch?
From the point of view of Git users, there is (in Bazaar-NG) an issue
of working tree being associated with the individual branch rather than
repository.
In git to work on some project you clone its repository; in bzr to
work on some project you get one of its branches.
IMVHO if "Cheap Branching Anywhere" was changed to "Lightweight Branches"
then Bazaar-NG would have to put "Partial" in there. Unless you setup
your branches to share data, branches are not cheap (in the sense of
disk space). That's probably the cause for _need_ for "checkouts".
Bazaar-NG doesn't encourage using temporary branches, with
lifespan no longer than day. Can you ever switch between branches
using only one working area; can you do it fast?
It looks somewhat like bzr started without permanent branches, and
they were added later (sharing repository data). But I might be mistaken.
P.S. what Git lacks at least now is a way to generate diff between
two different local repositories, but you can always setup alternates
file and fetch the other repository into some tag.
--
Jakub Narebski
Poland
^ permalink raw reply [relevance 3%]
* Re: VCS comparison table
@ 2006-10-21 18:58 3% ` Jan Hudec
[not found] ` <20061021150233.c29e11c5.seanlkml@sympatico.ca>
0 siblings, 1 reply; 200+ results
From: Jan Hudec @ 2006-10-21 18:58 UTC (permalink / raw)
To: Aaron Bentley; +Cc: Sean, Linus Torvalds, bazaar-ng, git, Jakub Narebski
On Tue, Oct 17, 2006 at 03:51:56PM -0400, Aaron Bentley wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> Sean wrote:
> > On Tue, 17 Oct 2006 00:24:15 -0400
> > Aaron Bentley <aaron.bentley@utoronto.ca> wrote:
> >>- - you can use a checkout to maintain a local mirror of a read-only
> >> branch (I do this with http://bazaar-vcs.com/bzr/bzr.dev).
> >
> >
> > I'm not sure what you mean here. A bzr checkout doesn't have any history
> > does it?
>
> By default, they do. You must use a flag to get a checkout with no history.
If I can add some clarification: There is a lightweight checkout and
heavyweight checkout. The former contains no history and does everything
(except status and I am not sure about diff) by accessing the remote
data. The later contains mirror of the history data and does
write-through on commit (and otherwise behaves like normal branch with
repository)
What would be really useful would be a checkout, or even a branch (ie.
with ability to commit locally), that would only contain history data
since some point. This would allow downloading very little data when
branching, but than working locally as with normal repository clone.
In bzr this was already discussed and the storage supports so called
"ghost" revisions, whose existence is known, but not their data. There
are even repositories around that contain them (created by converting
data from arch), but to my best knowledge there is no user interface to
create branches or checkouts with partial data.
--------------------------------------------------------------------------------
- Jan Hudec `Bulb' <bulb@ucw.cz>
^ permalink raw reply [relevance 3%]
* Re: VCS comparison table
[not found] ` <20061021150233.c29e11c5.seanlkml@sympatico.ca>
2006-10-21 19:02 1% ` Sean
@ 2006-10-21 19:02 1% ` Sean
1 sibling, 0 replies; 200+ results
From: Sean @ 2006-10-21 19:02 UTC (permalink / raw)
To: Jan Hudec; +Cc: Aaron Bentley, Linus Torvalds, bazaar-ng, git, Jakub Narebski
On Sat, 21 Oct 2006 20:58:25 +0200
Jan Hudec <bulb@ucw.cz> wrote:
> In bzr this was already discussed and the storage supports so called
> "ghost" revisions, whose existence is known, but not their data. There
> are even repositories around that contain them (created by converting
> data from arch), but to my best knowledge there is no user interface to
> create branches or checkouts with partial data.
In Git the same functionality can be achieved with so called shallow-
clones. Unfortunately, they've only been discussed and not yet
implemented.
Sean
^ permalink raw reply [relevance 1%]
* Re: VCS comparison table
[not found] ` <20061021150233.c29e11c5.seanlkml@sympatico.ca>
@ 2006-10-21 19:02 1% ` Sean
2006-10-21 19:02 1% ` Sean
1 sibling, 0 replies; 200+ results
From: Sean @ 2006-10-21 19:02 UTC (permalink / raw)
To: Jan Hudec; +Cc: Linus Torvalds, bazaar-ng, git, Jakub Narebski
On Sat, 21 Oct 2006 20:58:25 +0200
Jan Hudec <bulb@ucw.cz> wrote:
> In bzr this was already discussed and the storage supports so called
> "ghost" revisions, whose existence is known, but not their data. There
> are even repositories around that contain them (created by converting
> data from arch), but to my best knowledge there is no user interface to
> create branches or checkouts with partial data.
In Git the same functionality can be achieved with so called shallow-
clones. Unfortunately, they've only been discussed and not yet
implemented.
Sean
^ permalink raw reply [relevance 1%]
* Re: VCS comparison table
@ 2006-10-26 11:48 4% ` Jakub Narebski
0 siblings, 0 replies; 200+ results
From: Jakub Narebski @ 2006-10-26 11:48 UTC (permalink / raw)
To: bazaar-ng; +Cc: git
Andreas Ericsson wrote:
> On a side-note, git has made my life easier, so I childishly want to
> defend it and see it on top of every list in the world. Something I'm
> sure I share with more people on this list and with some of the bazaar
> users/devs. ;-)
Let's then us review what started this thread, namely comparison chart
between source control systems
http://bazaar-vcs.org/RcsComparisons
1. Decentralized. O.K.
2. Disconnected Ops. O.K.
3. Simple Namespace. Should be named "Simple Rev Names" instead, Bazaar
should have note that revnos work only for specific workflows
(star-topology); for Git it should be perhaps "Somewhat" here, as <ref>~<n>
(or <ref>@{<n>} if reflog is enabled) _are_ simple (if volatile for branch
<refs>). $(git-merge-base <ref1> <ref2>), usually "hidden" in
<ref1>..<ref2> or <ref1>...<ref2> shortcut is also I think simple. There
was huge discussion here about revnos, revids, workflows (development
topology), fast-forwards, empty merges etc. Bazaar-NG and Git puts
emphasisis on other things. Additionally tags supports removes some of
perceived revnos advantages; tags are simple.
4. Supports Renames. I could agree with "Somewhat" because of not yet
implemented --follow option to git-rev-list (and therefore all porcelain).
Perhaps it would be closer to truth to leave the marker (background color)
as for "Somewhat" and write "N/A" with note that Git has contents and
pathname based heuristic detection of renames, or just put "Detect" or
"Detection" here.
I would certainly change description of what means that SCM doesn't "Support
Renames" or has it implemented partially. Current explanation relies
heavily on _implementation_. The correct wording of current definition
would be that SCM doesn't support renames if history of a file "as visible
to SCM" is broken into before rename and after rename part, and that SCM
support it partially if you can track history of renamed file from
post-rename name but there is left in void history of pre-rename file.
But with this definition Git _does_ "Supports Renames".
I'd rather split "Supports Renames" into engine part (does SCM
remember/detect that rename took place _as_ rename, not remember/detect it
as copiying+deletion; something other than rename) and user interface part:
can user easily deal with renames (this includes merging and viewing file
history).
5 and 6. Needs Repository/Supports Repository. The name is very, very
unclean and stems from branch-centricness of Bazaar. Git should probably
have "Yes" here, as for Git branch is just reference to its tip in
revisions DAG (plus optionally branch tip history in reflog). On the other
hand Git _can_ share object database like branches can be gathered together
to share data into repository. You can have one-branch repositories, you
can clone whole repositories (perhaps Bazaar should have "Somewhat" for
Supports Repository as it doesn't support cloning of whole repository...
bzt, wrong, there is example plugin for that), and you can clone (using
Cogito) only one branch of repository and you can fetch only selected
branches of repository.
Thinking more about it those items should probably read "Support Individual
Branches" (as: can you get only the branch you are interested in, can SCM
support one-branch workflow) and "Support Branch Grouping" or "Support Data
Sharing" (as: can you share DAG between branches, can you share DAG between
repositories).
7. Checkouts (as a noun). This probably read "Support Centralized and
Disconnected Centralized Workflow" but that is perhaps too wordy. Git would
have "No" for "Centralized" and "Somewhat" for "Disconnected Centralized"
meaning that you can set up Git repository to be equivalent of heavyweight
checkout, and push changes to some given repository on commit.
8. Partial Checkouts (as a verb). Here Git should have perhaps "Minimal", as
you can have partial checkouts but only with care (and you still need whole
repository). "No?" is also correct (?).
9. Atomic Commits. O.K. You have to remember that there are consequences
of having Atomic Commits on the details of Partial Checkouts.
10. Cheap Branching Anywhere. Git should probably have "Yes! Yes! Yes!"
here ;-)
11. Smart Merge. O.K. Should probably be explained what constitutes smart
merging. Perhaps instead of "Yes" there should be name of default/smartest
merge strategy used?
12. Cherrypicks. What constitutes "Yes" here? Why "Somewhat" for Git?
It does have git-cherry-pick command for cherry picking...
13. Plugins. I would put "Somewhat" here, or "Scriptable" in the "Somewhat"
or "?" background color for Git. And add note that it is easy to script up
porcelanish command, and to add another merge strategy. There also was
example plugin infrastructure for Cogito, so I'd opt for "Someahwt"
marking.
14. Has Special Server. O.K.
15. Req. Dedicated Server. O.K.
16. Good Windows support. I'd put "Cygwin" instead of "No" for Git, although
with the same marking. And perhaps add note that Git relies heavily on
POSIX.
17 and 18. Fast Local Performance and Fast Network Performance. O.K.
19. Ease of Use. Hmmm... I don't know for Git. I personally find it very
easy to use, but I have not much experiences with other SCM. I wonder why
Bazaar has "No" there...
Too much rewriting to correct the page...
^ permalink raw reply [relevance 4%]
* [PATCH] enhance clone and fetch -k experience
@ 2006-10-27 19:42 5% Nicolas Pitre
0 siblings, 0 replies; 200+ results
From: Nicolas Pitre @ 2006-10-27 19:42 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
Now that index-pack can be streamed with a pack, it is probably a good
idea to use it directly instead of creating a temporary file and running
index-pack afterwards. This way index-pack can abort early whenever a
corruption is encountered even if the pack has not been fully
downloaded, it can display a progress percentage as it knows how much to
expects, and it is a bit faster since the pack indexing is partially
done as data is received. Using fetch -k doesn't need to disable thin
pack generation on the remote end either.
Signed-off-by: Nicolas Pitre <nico@cam.org>
---
diff --git a/fetch-clone.c b/fetch-clone.c
index 76b99af..96cdab4 100644
--- a/fetch-clone.c
+++ b/fetch-clone.c
@@ -3,97 +3,6 @@
#include "pkt-line.h"
#include "sideband.h"
#include <sys/wait.h>
-#include <sys/time.h>
-
-static int finish_pack(const char *pack_tmp_name, const char *me)
-{
- int pipe_fd[2];
- pid_t pid;
- char idx[PATH_MAX];
- char final[PATH_MAX];
- char hash[41];
- unsigned char sha1[20];
- char *cp;
- int err = 0;
-
- if (pipe(pipe_fd) < 0)
- die("%s: unable to set up pipe", me);
-
- strcpy(idx, pack_tmp_name); /* ".git/objects/pack-XXXXXX" */
- cp = strrchr(idx, '/');
- memcpy(cp, "/pidx", 5);
-
- pid = fork();
- if (pid < 0)
- die("%s: unable to fork off git-index-pack", me);
- if (!pid) {
- close(0);
- dup2(pipe_fd[1], 1);
- close(pipe_fd[0]);
- close(pipe_fd[1]);
- execl_git_cmd("index-pack", "-o", idx, pack_tmp_name, NULL);
- error("cannot exec git-index-pack <%s> <%s>",
- idx, pack_tmp_name);
- exit(1);
- }
- close(pipe_fd[1]);
- if (read(pipe_fd[0], hash, 40) != 40) {
- error("%s: unable to read from git-index-pack", me);
- err = 1;
- }
- close(pipe_fd[0]);
-
- for (;;) {
- int status, code;
-
- if (waitpid(pid, &status, 0) < 0) {
- if (errno == EINTR)
- continue;
- error("waitpid failed (%s)", strerror(errno));
- goto error_die;
- }
- if (WIFSIGNALED(status)) {
- int sig = WTERMSIG(status);
- error("git-index-pack died of signal %d", sig);
- goto error_die;
- }
- if (!WIFEXITED(status)) {
- error("git-index-pack died of unnatural causes %d",
- status);
- goto error_die;
- }
- code = WEXITSTATUS(status);
- if (code) {
- error("git-index-pack died with error code %d", code);
- goto error_die;
- }
- if (err)
- goto error_die;
- break;
- }
- hash[40] = 0;
- if (get_sha1_hex(hash, sha1)) {
- error("git-index-pack reported nonsense '%s'", hash);
- goto error_die;
- }
- /* Now we have pack in pack_tmp_name[], and
- * idx in idx[]; rename them to their final names.
- */
- snprintf(final, sizeof(final),
- "%s/pack/pack-%s.pack", get_object_directory(), hash);
- move_temp_to_file(pack_tmp_name, final);
- chmod(final, 0444);
- snprintf(final, sizeof(final),
- "%s/pack/pack-%s.idx", get_object_directory(), hash);
- move_temp_to_file(idx, final);
- chmod(final, 0444);
- return 0;
-
- error_die:
- unlink(idx);
- unlink(pack_tmp_name);
- exit(1);
-}
static pid_t setup_sideband(int sideband, const char *me, int fd[2], int xd[2])
{
@@ -128,7 +37,7 @@ static pid_t setup_sideband(int sideband
return side_pid;
}
-int receive_unpack_pack(int xd[2], const char *me, int quiet, int sideband)
+static int get_pack(int xd[2], const char *me, int sideband, const char **argv)
{
int status;
pid_t pid, side_pid;
@@ -142,135 +51,37 @@ int receive_unpack_pack(int xd[2], const
dup2(fd[0], 0);
close(fd[0]);
close(fd[1]);
- execl_git_cmd("unpack-objects", quiet ? "-q" : NULL, NULL);
- die("git-unpack-objects exec failed");
+ execv_git_cmd(argv);
+ die("%s exec failed", argv[0]);
}
close(fd[0]);
close(fd[1]);
while (waitpid(pid, &status, 0) < 0) {
if (errno != EINTR)
- die("waiting for git-unpack-objects: %s",
- strerror(errno));
+ die("waiting for %s: %s", argv[0], strerror(errno));
}
if (WIFEXITED(status)) {
int code = WEXITSTATUS(status);
if (code)
- die("git-unpack-objects died with error code %d",
- code);
+ die("%s died with error code %d", argv[0], code);
return 0;
}
if (WIFSIGNALED(status)) {
int sig = WTERMSIG(status);
- die("git-unpack-objects died of signal %d", sig);
+ die("%s died of signal %d", argv[0], sig);
}
- die("git-unpack-objects died of unnatural causes %d", status);
+ die("%s died of unnatural causes %d", argv[0], status);
}
-/*
- * We average out the download speed over this many "events", where
- * an event is a minimum of about half a second. That way, we get
- * a reasonably stable number.
- */
-#define NR_AVERAGE (4)
-
-/*
- * A "binary msec" is a power-of-two-msec, aka 1/1024th of a second.
- * Keeping the time in that format means that "bytes / msecs" means
- * the same as kB/s (modulo rounding).
- *
- * 1000512 is a magic number (usecs in a second, rounded up by half
- * of 1024, to make "rounding" come out right ;)
- */
-#define usec_to_binarymsec(x) ((int)(x) / (1000512 >> 10))
+int receive_unpack_pack(int xd[2], const char *me, int quiet, int sideband)
+{
+ const char *argv[3] = { "unpack-objects", quiet ? "-q" : NULL, NULL };
+ return get_pack(xd, me, sideband, argv);
+}
int receive_keep_pack(int xd[2], const char *me, int quiet, int sideband)
{
- char tmpfile[PATH_MAX];
- int ofd, ifd, fd[2];
- unsigned long total;
- static struct timeval prev_tv;
- struct average {
- unsigned long bytes;
- unsigned long time;
- } download[NR_AVERAGE] = { {0, 0}, };
- unsigned long avg_bytes, avg_time;
- int idx = 0;
-
- setup_sideband(sideband, me, fd, xd);
-
- ifd = fd[0];
- snprintf(tmpfile, sizeof(tmpfile),
- "%s/pack/tmp-XXXXXX", get_object_directory());
- ofd = mkstemp(tmpfile);
- if (ofd < 0)
- return error("unable to create temporary file %s", tmpfile);
-
- gettimeofday(&prev_tv, NULL);
- total = 0;
- avg_bytes = 0;
- avg_time = 0;
- while (1) {
- char buf[8192];
- ssize_t sz, wsz, pos;
- sz = read(ifd, buf, sizeof(buf));
- if (sz == 0)
- break;
- if (sz < 0) {
- if (errno != EINTR && errno != EAGAIN) {
- error("error reading pack (%s)", strerror(errno));
- close(ofd);
- unlink(tmpfile);
- return -1;
- }
- sz = 0;
- }
- pos = 0;
- while (pos < sz) {
- wsz = write(ofd, buf + pos, sz - pos);
- if (wsz < 0) {
- error("error writing pack (%s)",
- strerror(errno));
- close(ofd);
- unlink(tmpfile);
- return -1;
- }
- pos += wsz;
- }
- total += sz;
- if (!quiet) {
- static unsigned long last;
- struct timeval tv;
- unsigned long diff = total - last;
- /* not really "msecs", but a power-of-two millisec (1/1024th of a sec) */
- unsigned long msecs;
-
- gettimeofday(&tv, NULL);
- msecs = tv.tv_sec - prev_tv.tv_sec;
- msecs <<= 10;
- msecs += usec_to_binarymsec(tv.tv_usec - prev_tv.tv_usec);
-
- if (msecs > 500) {
- prev_tv = tv;
- last = total;
-
- /* Update averages ..*/
- avg_bytes += diff;
- avg_time += msecs;
- avg_bytes -= download[idx].bytes;
- avg_time -= download[idx].time;
- download[idx].bytes = diff;
- download[idx].time = msecs;
- idx++;
- if (idx >= NR_AVERAGE)
- idx = 0;
-
- fprintf(stderr, "%4lu.%03luMB (%lu kB/s) \r",
- total >> 20,
- 1000*((total >> 10) & 1023)>>10,
- avg_bytes / avg_time );
- }
- }
- }
- close(ofd);
- return finish_pack(tmpfile, me);
+ const char *argv[5] = { "index-pack", "--stdin", "--fix-thin",
+ quiet ? NULL : "-v", NULL };
+ return get_pack(xd, me, sideband, argv);
}
diff --git a/fetch-pack.c b/fetch-pack.c
index 90b7940..36ea092 100644
--- a/fetch-pack.c
+++ b/fetch-pack.c
@@ -518,8 +518,6 @@ int main(int argc, char **argv)
}
if (!dest)
usage(fetch_pack_usage);
- if (keep_pack)
- use_thin_pack = 0;
pid = git_connect(fd, dest, exec);
if (pid < 0)
^ permalink raw reply related [relevance 5%]
* What's in git.git
@ 2006-11-02 0:53 1% Junio C Hamano
0 siblings, 0 replies; 200+ results
From: Junio C Hamano @ 2006-11-02 0:53 UTC (permalink / raw)
To: git
* The 'maint' branch has these fixes since the last announcement.
We have one semantic fix in "maint". To the revision traversal
machinery, --unpacked used to mean that any commit that is in a
pack is uninteresting and tainted its ancestors also
uninteresting. Updated semantics of --unpacked is just an
output filter -- it traverses ancestry chain as usual, but does
not show unpacked commits. This made what "git repack" does
actually make sense when the repository is partly packed in the
half-way (the earlier logic worked fine only if all ancestors of
a packed commit were all packed).
A few minor "diff --cc" output fixes are also in "maint". It
now honours --no-commit-id option and shows function names on
the @@@ ... @@@ line just like normal diffs do.
Christian Couder (2):
Documentation: add upload-archive service to git-daemon.
Documentation: add git in /etc/services.
Edgar Toernig (1):
Use memmove instead of memcpy for overlapping areas
Jakub Narebski (2):
diff-format.txt: Correct information about pathnames quoting in
patch format
gitweb: Check git base URLs before generating URL from it
Jan Harkes (1):
Continue traversal when rev-list --unpacked finds a packed commit.
Junio C Hamano (7):
combine-diff: a few more finishing touches.
combine-diff: fix hunk_comment_line logic.
combine-diff: honour --no-commit-id
Surround "#define DEBUG 0" with "#ifndef DEBUG..#endif"
quote.c: ensure the same quoting across platforms.
revision traversal: --unpacked does not limit commit list anymore.
link_temp_to_file: don't leave the path truncated on
adjust_shared_perm failure
Nicolas Pitre (1):
pack-objects doesn't create random pack names
Rene Scharfe (1):
git-cherry: document limit and add diagram
* The 'master' branch has these since the last announcement.
Linus's packed-refs work with associated refs handling
clean-ups are out on "master", but there is one disclaimer.
Commit walkers cannot fetch from a repository whose refs are
packed and then pruned yet, so people with public repositories
that are expected to be fetched via http should not run
git-pack-refs just yet. I think it is probably just the
matter of updating git-fetch.sh to run ls-remote against the
repository upfront, and use the SHA-1 of wanted branch tip
instead of the branch tip name when running the low-level
git-http-fetch.
git-branch and git-cherry are now built-in.
Andy Parkins (1):
Make filenames line up in git-status output
Christian Couder (14):
Add [-s|--hash] option to Linus' show-ref.
Use Linus' show ref in "git-branch.sh".
Document git-show-ref [-s|--hash] option.
Fix show-ref usage for --dereference.
Add pack-refs and show-ref test cases.
When creating branch c/d check that branch c does not already exists.
Uncomment test case: git branch c/d should barf if branch c exists.
Fix a remove_empty_dir_recursive problem.
Clean up "git-branch.sh" and add remove recursive dir test cases.
Use git-update-ref to delete a tag instead of rm()ing the ref file.
Check that a tag exists using show-ref instead of looking for the
ref file.
Do not create tag leading directories since git update-ref does it.
Documentation: add upload-archive service to git-daemon.
Documentation: add git in /etc/services.
Dennis Stosberg (3):
lock_ref_sha1_basic does not remove empty directories on BSD
Remove bashism from t3210-pack-refs.sh
Bash completion support for aliases
Edgar Toernig (2):
Use memmove instead of memcpy for overlapping areas
Use memmove instead of memcpy for overlapping areas
Jakub Narebski (8):
gitweb: Use --no-commit-id in git_commit and git_commitdiff
diff-format.txt: Correct information about pathnames quoting in
patch format
gitweb: Check git base URLs before generating URL from it
Documentation: Update information about <format> in git-for-each-ref
gitweb: Move git_get_last_activity subroutine earlier
gitweb: Add "next" link to commitdiff view
gitweb: Secure against commit-ish/tree-ish with the same name as path
gitweb: Use 's' regexp modifier to secure against filenames with LF
Jan Harkes (1):
Continue traversal when rev-list --unpacked finds a packed commit.
Jeff King (3):
wt-status: use simplified resolve_ref to find current branch
gitignore: git-pack-refs is a generated file.
gitignore: git-show-ref is a generated file.
Johannes Schindelin (2):
Fix git-update-index --again
show-branch: mark active branch with a '*' again
Jonas Fonseca (1):
Add man page for git-show-ref
Junio C Hamano (42):
Fix t1400-update-ref test minimally
fsck-objects: adjust to resolve_ref() clean-up.
symbolit-ref: fix resolve_ref conversion.
Add callback data to for_each_ref() family.
Tell between packed, unpacked and symbolic refs.
pack-refs: do not pack symbolic refs.
git-pack-refs --prune
pack-refs: fix git_path() usage.
lock_ref_sha1_basic: remove unused parameter "plen".
Clean-up lock-ref implementation
update-ref: -d flag and ref creation safety.
update a few Porcelain-ish for ref lock safety.
Teach receive-pack about ref-log
receive-pack: call setup_ident before git_config
ref locking: allow 'foo' when 'foo/bar' used to exist but not anymore.
refs: minor restructuring of cached refs data.
lock_ref_sha1(): do not sometimes error() and sometimes die().
lock_ref_sha1(): check D/F conflict with packed ref when creating.
delete_ref(): delete packed ref
git-branch: remove D/F check done by hand.
show-ref --hash=len, --abbrev=len, and --abbrev
git-fetch: adjust to packed-refs.
Fix refs.c;:repack_without_ref() clean-up path
git-fetch: do not look into $GIT_DIR/refs to see if a tag exists.
pack-refs: use lockfile as everybody else does.
pack-refs: call fflush before fsync.
ref-log: allow ref@{count} syntax.
core.logallrefupdates create new log file only for branch heads.
git-pack-refs --all
core.logallrefupdates thinko-fix
ref-log: fix D/F conflict coming from deleted refs.
sha1_name.c: avoid compilation warnings.
t3200: git-branch testsuite update
combine-diff: fix hunk_comment_line logic.
combine-diff: honour --no-commit-id
tests: merge-recursive is usable without Python
Documentation: fix git-format-patch mark-up and link it from git.txt
Surround "#define DEBUG 0" with "#ifndef DEBUG..#endif"
quote.c: ensure the same quoting across platforms.
revision traversal: --unpacked does not limit commit list anymore.
link_temp_to_file: don't leave the path truncated on
adjust_shared_perm failure
branch: work in subdirectories.
Lars Hjemli (2):
Make git-branch a builtin
Fix show-ref usagestring
Linus Torvalds (6):
Add "git show-ref" builtin command
Teach "git checkout" to use git-show-ref
Start handling references internally as a sorted in-memory list
Add support for negative refs
Make ref resolution saner
Enable the packed refs file format
Luben Tuikov (2):
git-revert with conflicts to behave as git-merge with conflicts
gitweb: esc_html() author in blame
Nicolas Pitre (1):
pack-objects doesn't create random pack names
Petr Baudis (3):
Fix broken sha1 locking
Fix buggy ref recording
gitweb: Fix up bogus $stylesheet declarations
Rene Scharfe (3):
Built-in cherry
Make git-cherry handle root trees
git-cherry: document limit and add diagram
Robin Rosenberg (2):
Mention that pull can work locally in the synopsis
Swap the porcelain and plumbing commands in the git man page
Sasha Khapyorsky (1):
git-svnimport: support for partial imports
Sergey Vlasov (2):
git-send-email: Document support for local sendmail instead of
SMTP server
git-send-email: Read the default SMTP server from the GIT config file
Shawn Pearce (1):
Move deny_non_fast_forwards handling completely into receive-pack.
* The 'next' branch, in addition, has these.
The largest one is "pickaxe"; I think it is ready for wider
testing if not for production use, and it is a new command so
it should be relatively safe to push it out anytime on "master".
Nico did a lot of work on index-pack and with help from Shawn
pushing many objects without exploding them into loose objects
at the other end is becoming reality. The latest part of
their series is not in "next" nor "pu" yet, though.
Linus pointed out that when merging a branch based on an older
codebase that used to have a path into your branch that does
not have that path tracked anymore triggers a bogus safety
valve; I've done both merge-resolve and merge-recursive to
handle this situation but the result needs to be sanity
checked. We are _loosening_ safety valve and need to be extra
cautious not to overloosen it.
Junio C Hamano (28):
upload-pack: stop the other side when they have more roots than we do.
git-pickaxe: blame rewritten.
git-pickaxe -M: blame line movements within a file.
git-pickaxe -C: blame cut-and-pasted lines.
git-pickaxe: pagenate output by default.
git-pickaxe: fix nth_line()
git-pickaxe: improve "best match" heuristics
git-pickaxe: introduce heuristics to avoid "trivial" chunks
git-pickaxe: do not keep commit buffer.
git-pickaxe: do not confuse two origins that are the same.
git-pickaxe: get rid of wasteful find_origin().
git-pickaxe: swap comparison loop used for -C
merge: loosen overcautious "working file will be lost" check.
merge-recursive: use abbreviated commit object name.
merge-recursive: make a few functions static.
merge-recursive: adjust to loosened "working file clobbered" check
t6022: ignoring untracked files by merge-recursive when they do not
matter
send-pack --keep: do not explode into loose objects on the receiving end.
git-pickaxe: WIP to refcount origin structure.
git-pickaxe: allow -Ln,m as well as -L n,m
git-pickaxe: refcount origin correctly in find_copy_in_parent()
git-pickaxe: tighten sanity checks.
Revert "send-pack --keep: do not explode into loose objects on the
receiving end."
git-pickaxe: split find_origin() into find_rename() and find_origin().
git-pickaxe: cache one already found path per commit.
Introduce a new revision set operator <rev>^!
Linus Torvalds (2):
Allow '-' in config variable names
git push: add verbose flag and allow overriding of default target
repository
Nicolas Pitre (8):
enable index-pack streaming capability
make index-pack able to complete thin packs.
add progress status to index-pack
mimic unpack-objects when --stdin is used with index-pack
enhance clone and fetch -k experience
index-pack: minor fixes to comment and function name
missing small substitution
make git-push a bit more verbose
Petr Baudis (1):
gitweb: Support for 'forks'
Shawn Pearce (4):
Allow short pack names to git-pack-objects --unpacked=.
Only repack active packs by skipping over kept packs.
Teach git-index-pack how to keep a pack file.
Remove unused variable in receive-pack.
* The 'pu' branch, in addition, has these.
Johannes's "shallow" was marked as "pu" material so I've based
the series on the tip of "next" (which means we cannot
directly merge that into "next" or "master" without rebasing
it to "master" first) and parked it in "pu". I have given
only a cursory look to it but it looks promising.
Nico's latest 6-series builds on top of what Shawn has here
(the first two from Nico are the same), but I haven't gotten
around to them yet.
Johannes Schindelin (6):
upload-pack: no longer call rev-list
support fetching into a shallow repository
allow cloning a repository "shallowly"
allow deepening of a shallow repository
add tests for shallow stuff
Build in shortlog
Junio C Hamano (4):
rev-list --left-right
git-diff/git-apply: make diff output a bit friendlier to GNU
patch (part 2)
para-walk: walk n trees, index and working tree in parallel
git-commit: show --summary after successful commit.
Shawn Pearce (2):
Allow pack header preprocessing before unpack-objects/index-pack.
Teach receive-pack how to keep pack files based on object count.
^ permalink raw reply [relevance 1%]
* Re: What's in git.git
@ 2006-11-08 4:13 2% ` David Lang
2006-11-08 16:40 1% ` Shallow clone [Was Re: What's in git.git ] Aneesh Kumar K.V
` (2 more replies)
0 siblings, 3 replies; 200+ results
From: David Lang @ 2006-11-08 4:13 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
On Tue, 7 Nov 2006, Junio C Hamano wrote:
> [pu]
>
> Johannes's shallow clone work now should rebase cleanly on top
> of 'master' although I haven't done so yet. As he said
> himself the series is waiting for people who have needs for
> such a feature to raise hands.
I haven't been watching this recently, but if this is what I understand it to be
(the ability to get a partial repository from upstream and work normally from
there with the result of data-mineing tools sometimes reporting 'that's part of
the truncated history' if they hit the cutoff) consider my hand raised.
there are a number of cases where I would be interested in following a project
as it moves forwards, but do not have the need to have the full history (even
with the good compression that a git pack provides, it's still a significant
amount of disk space and download time for large projects)
^ permalink raw reply [relevance 2%]
* Shallow clone [Was Re: What's in git.git ]
2006-11-08 4:13 2% ` David Lang
@ 2006-11-08 16:40 1% ` Aneesh Kumar K.V
2006-11-08 17:59 1% ` Aneesh Kumar K.V
2006-11-09 2:28 0% ` What's in git.git Horst H. von Brand
2006-11-12 22:25 3% ` Johannes Schindelin
2 siblings, 1 reply; 200+ results
From: Aneesh Kumar K.V @ 2006-11-08 16:40 UTC (permalink / raw)
Cc: git
David Lang wrote:
> On Tue, 7 Nov 2006, Junio C Hamano wrote:
>
>> [pu]
>>
>> Johannes's shallow clone work now should rebase cleanly on top
>> of 'master' although I haven't done so yet. As he said
>> himself the series is waiting for people who have needs for
>> such a feature to raise hands.
>
> I haven't been watching this recently, but if this is what I understand
> it to be (the ability to get a partial repository from upstream and work
> normally from there with the result of data-mineing tools sometimes
> reporting 'that's part of the truncated history' if they hit the cutoff)
> consider my hand raised.
>
> there are a number of cases where I would be interested in following a
> project as it moves forwards, but do not have the need to have the full
> history (even with the good compression that a git pack provides, it's
> still a significant amount of disk space and download time for large
> projects)
>
I am trying to test this feature. Is there a documentation .git/shallow some where. Atleast what those entries
mean ? I know in the mail johannes mentioned only core git will touch this file. But it should be ok to be
descriptive like other files. (FETCH_HEAD)
-aneesh
^ permalink raw reply [relevance 1%]
* Re: Shallow clone [Was Re: What's in git.git ]
2006-11-08 16:40 1% ` Shallow clone [Was Re: What's in git.git ] Aneesh Kumar K.V
@ 2006-11-08 17:59 1% ` Aneesh Kumar K.V
0 siblings, 1 reply; 200+ results
From: Aneesh Kumar K.V @ 2006-11-08 17:59 UTC (permalink / raw)
To: Aneesh Kumar K.V; +Cc: git
[-- Attachment #1: Type: text/plain, Size: 1291 bytes --]
Aneesh Kumar K.V wrote:
> David Lang wrote:
>> On Tue, 7 Nov 2006, Junio C Hamano wrote:
>>
>>> [pu]
>>>
>>> Johannes's shallow clone work now should rebase cleanly on top
>>> of 'master' although I haven't done so yet. As he said
>>> himself the series is waiting for people who have needs for
>>> such a feature to raise hands.
>>
>> I haven't been watching this recently, but if this is what I
>> understand it to be (the ability to get a partial repository from
>> upstream and work normally from there with the result of data-mineing
>> tools sometimes reporting 'that's part of the truncated history' if
>> they hit the cutoff) consider my hand raised.
>>
>> there are a number of cases where I would be interested in following a
>> project as it moves forwards, but do not have the need to have the
>> full history (even with the good compression that a git pack provides,
>> it's still a significant amount of disk space and download time for
>> large projects)
>>
>
> I am trying to test this feature. Is there a documentation .git/shallow
> some where. Atleast what those entries
> mean ? I know in the mail johannes mentioned only core git will touch
> this file. But it should be ok to be descriptive like other files.
> (FETCH_HEAD)
How about this
-aneesh
[-- Attachment #2: repository-layout.txt.diff --]
[-- Type: text/x-patch, Size: 537 bytes --]
diff --git a/Documentation/repository-layout.txt b/Documentation/repository-layout.txt
index 275d18b..03a6f77 100644
--- a/Documentation/repository-layout.txt
+++ b/Documentation/repository-layout.txt
@@ -141,3 +141,9 @@ logs/refs/heads/`name`::
logs/refs/tags/`name`::
Records all changes made to the tag named `name`.
+
+shallow::
+ Records the sha1 of the commits which is marked to have no
+ parents to represent a shallow repository.The commit object
+ will have the parent information present. It carry one
+ record per line.
^ permalink raw reply related [relevance 1%]
* Re: What's in git.git
2006-11-08 4:13 2% ` David Lang
2006-11-08 16:40 1% ` Shallow clone [Was Re: What's in git.git ] Aneesh Kumar K.V
@ 2006-11-09 2:28 0% ` Horst H. von Brand
2006-11-09 2:54 0% ` Junio C Hamano
2006-11-12 22:25 3% ` Johannes Schindelin
2 siblings, 1 reply; 200+ results
From: Horst H. von Brand @ 2006-11-09 2:28 UTC (permalink / raw)
To: David Lang; +Cc: Junio C Hamano, git
David Lang <dlang@digitalinsight.com> wrote:
> On Tue, 7 Nov 2006, Junio C Hamano wrote:
>
> > [pu]
> >
> > Johannes's shallow clone work now should rebase cleanly on top
> > of 'master' although I haven't done so yet. As he said
> > himself the series is waiting for people who have needs for
> > such a feature to raise hands.
>
> I haven't been watching this recently, but if this is what I
> understand it to be (the ability to get a partial repository from
> upstream and work normally from there with the result of data-mineing
> tools sometimes reporting 'that's part of the truncated history' if
> they hit the cutoff) consider my hand raised.
+1
--
Dr. Horst H. von Brand User #22616 counter.li.org
Departamento de Informatica Fono: +56 32 2654431
Universidad Tecnica Federico Santa Maria +56 32 2654239
Casilla 110-V, Valparaiso, Chile Fax: +56 32 2797513
^ permalink raw reply [relevance 0%]
* Re: What's in git.git
2006-11-09 2:28 0% ` What's in git.git Horst H. von Brand
@ 2006-11-09 2:54 0% ` Junio C Hamano
2006-11-09 3:45 0% ` Dave Dillow
0 siblings, 1 reply; 200+ results
From: Junio C Hamano @ 2006-11-09 2:54 UTC (permalink / raw)
To: Horst H. von Brand; +Cc: git
"Horst H. von Brand" <vonbrand@laptop13.inf.utfsm.cl> writes:
> David Lang <dlang@digitalinsight.com> wrote:
>> On Tue, 7 Nov 2006, Junio C Hamano wrote:
>>
>> > [pu]
>> >
>> > Johannes's shallow clone work now should rebase cleanly on top
>> > of 'master' although I haven't done so yet. As he said
>> > himself the series is waiting for people who have needs for
>> > such a feature to raise hands.
>>
>> I haven't been watching this recently, but if this is what I
>> understand it to be (the ability to get a partial repository from
>> upstream and work normally from there with the result of data-mineing
>> tools sometimes reporting 'that's part of the truncated history' if
>> they hit the cutoff) consider my hand raised.
>
> +1
What does that plus one mean? I do not know where people picked
up this annoying plus or minus one business, but could you all
stop that?
If you are volunteering to help debugging and feeding bugfixes
that is very much welcome and appreciated.
Thanks.
^ permalink raw reply [relevance 0%]
* Re: What's in git.git
2006-11-09 2:54 0% ` Junio C Hamano
@ 2006-11-09 3:45 0% ` Dave Dillow
0 siblings, 0 replies; 200+ results
From: Dave Dillow @ 2006-11-09 3:45 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Horst H. von Brand, git
On Wed, 2006-11-08 at 18:54 -0800, Junio C Hamano wrote:
> "Horst H. von Brand" <vonbrand@laptop13.inf.utfsm.cl> writes:
>
> > David Lang <dlang@digitalinsight.com> wrote:
> >> On Tue, 7 Nov 2006, Junio C Hamano wrote:
> >>
> >> > [pu]
> >> >
> >> > Johannes's shallow clone work now should rebase cleanly on top
> >> > of 'master' although I haven't done so yet. As he said
> >> > himself the series is waiting for people who have needs for
> >> > such a feature to raise hands.
> >>
> >> I haven't been watching this recently, but if this is what I
> >> understand it to be (the ability to get a partial repository from
> >> upstream and work normally from there with the result of data-mineing
> >> tools sometimes reporting 'that's part of the truncated history' if
> >> they hit the cutoff) consider my hand raised.
> >
> > +1
>
> What does that plus one mean? I do not know where people picked
> up this annoying plus or minus one business, but could you all
> stop that?
Horst can speak for himself, but I'd wager he's using the Apache voting
conventions:
^ permalink raw reply [relevance 0%]
* Re: Shallow clone
@ 2006-11-12 17:59 5% ` Sergey Vlasov
2006-11-12 21:59 1% ` Junio C Hamano
0 siblings, 1 reply; 200+ results
From: Sergey Vlasov @ 2006-11-12 17:59 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Alexandre Julliard, Aneesh Kumar K.V, git
[-- Attachment #1: Type: text/plain, Size: 2619 bytes --]
On Sun, 12 Nov 2006 00:16:40 -0800 Junio C Hamano wrote:
> Alexandre Julliard <julliard@winehq.org> writes:
>
> > There's also a problem with the packing, a clone --depth 1 currently
> > results in a pack that's about 3 times as large as it should be.
>
> That's interesting.
>
> : gitster; git clone -n --depth 1 git://127.0.0.1/git.git victim-001
[...]
> -r--r--r-- 1 junio src 9.5M 2006-11-11 23:52 pack-f5f88d83....pack
>
> Repacking immediately after cloning brings it down to what is
> expected.
>
> : gitster; git repack -a -d -f
[...]
> -rw-rw-r-- 1 junio src 2.6M 2006-11-11 23:53 pack-f5f88d83....pack
This is due to optimization in builtin-pack-objects.c:try_delta():
/*
* We do not bother to try a delta that we discarded
* on an earlier try, but only when reusing delta data.
*/
if (!no_reuse_delta && trg_entry->in_pack &&
trg_entry->in_pack == src_entry->in_pack)
return 0;
After removing this part the shallow pack after clone is 2.6M, as it
should be.
The problem with this optimization is that it is only valid if we are
repacking either the same set of objects as we did earlier, or its
superset. But if we are packing a subset of objects, there will be some
objects in that subset which were delta-compressed in the original pack,
but base objects for that deltas are not included in our subset -
therefore we will be unable to reuse existing deltas, and with that
optimization we will never try to use delta compression for these
objects. (The optimization assumes that if we will try to use delta
compression, we will try mostly the same base objects as we have tried
when we made the existing pack, and therefore will likely get the same
result - which is close to the truth when we are doing "repack -a", but
is badly wrong when we are doing "git-upload-pack" with a large number
of common commits, and therefore are excluding a lot of objects.)
So any partial fetch (shallow or not) from a mostly packed repository
currently results in a suboptimal pack. In fact, the fresh "repack -a
-d -f" is probably the worst case for subsequent fetch (not initial
clone) from that repository - objects for the most recent commit are
most likely to be stored without delta compression, and even if deltas
are used, they are likely in the wrong direction for someone who has an
older version and wants to update it.
> In any case, after this "shallow" stuff, repeated "fetch --depth
> 99" seems to fetch 0 object and 3400 objects alternately, and
> the shallow file alternates between 900 bytes and 11000 bytes.
I confirm this - different numbers, but the same problem...
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply [relevance 5%]
* Re: should git download missing objects?
@ 2006-11-12 19:41 2% ` Junio C Hamano
0 siblings, 0 replies; 200+ results
From: Junio C Hamano @ 2006-11-12 19:41 UTC (permalink / raw)
To: Anand Kumria; +Cc: git
"Anand Kumria" <wildfire@progsoc.org> writes:
> I did an initial clone of Linus' linux-2.6.git tree, via the git protocol,
> and then managed to accidently delete one of the .pack and
> corresponding .idx files.
>
> I thought that 'cg-fetch' would do the job of bring down the missing pack
> again, and all would be well. Alas this isn't the case.
>
> <http://pastebin.ca/246678>
>
> Pasky, on IRC, indicated that this might be because git-fetch-pack isn't
> downloading missing objects when the git:// protocol is being used.
There are the invariants between refs and objects:
- objects that its refs (files under .git/refs/ hierarchy that
record 40-byte hexadecimal object names) point at are never
missing, or the repository is corrupt.
- objects that are reachable via pointers in another object
that is not missing (a tag points at another object, a commit
points at its tree and its parent commits, and a tree points
at its subtrees and blobs) are never missing, or the repository
is corrupt.
Git tools first fetch missing objects and then update your refs
only when fetch succeeds completely, in order to maintain the
above invariants (a partial fetch does not update your refs).
And these invariants are why:
- fsck-objects start reachability check from the refs;
- commit walkers can stop at your existing refs;
- git native protocols only need to tell the other end what
refs you have, in order for the other end to exclude what you
already have from the set of objects it sends you.
What's missing needs to be determined in a reasonably efficient
manner, and the above invariants allow us not have to do the
equivalent of fsck-objects every time. Being able to trust refs
is fairly fundamental in the fetch operation of git.
I am not opposed to the idea of a new tool to fix a corrupted
repository that has broken the above invariants, perhaps caused
by accidental removal of objects and packs by end users. What
it needs to do would be:
- run fsck-objects to notice what are missing, by noting
"broken link from foo to bar" output messages. Object 'bar'
is what you _ought_ to have according to your refs but you
don't (because you removed the objects that should be there),
and everything that is reachable from it from the other side
needs to be retrieved. Because you do not have 'bar', your
end cannot determine what other objects you happen to have in
your object store are reachable from it and would result in
redundant download.
- run fetch-pack equivalent to get everything reachable
starting at the above missing objects, pretending you do not
have any object, because your refs are not trustworthy.
- run fsck-objects again to make sure that your refs can now be
trusted again.
To implement the second step above, you need to implement a
modified fetch-pack that does not trust any of your refs. It
also needs to ignore what are offered from the other end but
asks the objects you know are missing ('bar' in the above
example). This program needs to talk to a modified upload-pack
running at the other end (let's call it upload-pack-recover),
because usual upload-pack does not serve starting from a random
object that happen to be in its repository, but only starting
from objects that are pointed by its own set of refs to ensure
integrity.
The upload-pack-recover program would need to start traversal
from object 'bar' in the above example, and when it does so, it
should not just run 'rev-list --objects' starting at 'bar'. It
first needs to prove that its object store has everything that
is reachable from 'bar' (the recipient would still end up with
an incomplete repository if it didn't).
What this means is that it needs to prove some of its refs can
reach 'bar' (again, on the upstream end, only refs are trusted,
not mere existence of object is not enough) before sending
objects back. Usual upload-pack do not have to do it because it
refuses to serve starting from anything but what its refs point
at (and by the invariants, the objects pointed at by refs are
guaranteed to be complete [an object is "complete" if no object
that can be reachable is not missing]).
This is needed because the repository might have discarded
branch that used to reach 'bar', and while the object 'bar' was
in a pack but some of its ancestors or component trees and/or
blobs were loose and subsequent git-prune have removed the
latter without removing 'bar'. Mere existence of the object
'bar' does not mean 'bar' is complete.
So coming up with such a pair of programs is not a rocket
science, but it is fairly delicate. I would rather have them as
specialized commands, not a part of everyday commands, even if
you were to implement it.
Since this is not everyday anyway, a far easier way would be to
clone-pack from the upstream into a new repository, take the
pack you downloaded from that new repository and mv it into your
corrupt repository. You can run fsck-objects to see if you got
back everything you lost earlier.
^ permalink raw reply [relevance 2%]
* Re: Shallow clone
2006-11-12 17:59 5% ` Sergey Vlasov
@ 2006-11-12 21:59 1% ` Junio C Hamano
2006-11-13 5:29 1% ` Junio C Hamano
0 siblings, 1 reply; 200+ results
From: Junio C Hamano @ 2006-11-12 21:59 UTC (permalink / raw)
To: Sergey Vlasov; +Cc: Alexandre Julliard, Aneesh Kumar K.V, git
Sergey Vlasov <vsu@altlinux.ru> writes:
> This is due to optimization in builtin-pack-objects.c:try_delta():
>
> /*
> * We do not bother to try a delta that we discarded
> * on an earlier try, but only when reusing delta data.
> */
> if (!no_reuse_delta && trg_entry->in_pack &&
> trg_entry->in_pack == src_entry->in_pack)
> return 0;
>
> After removing this part the shallow pack after clone is 2.6M, as it
> should be.
>
> The problem with this optimization is that it is only valid if we are
> repacking either the same set of objects as we did earlier, or its
> superset. But if we are packing a subset of objects, there will be some
> objects in that subset which were delta-compressed in the original pack,
> but base objects for that deltas are not included in our subset -
> therefore we will be unable to reuse existing deltas, and with that
> optimization we will never try to use delta compression for these
> objects.
> ...
> So any partial fetch (shallow or not) from a mostly packed repository
> currently results in a suboptimal pack.
That is correct. How about something like this?
I think the determination of "repacking_superset" may need to be
tweaked because existing packs may have overlaps, and the patch
counts them once per pack.
diff --git a/builtin-pack-objects.c b/builtin-pack-objects.c
index 69e5dd3..fb25124 100644
--- a/builtin-pack-objects.c
+++ b/builtin-pack-objects.c
@@ -64,6 +64,7 @@ struct object_entry {
static unsigned char object_list_sha1[20];
static int non_empty;
static int no_reuse_delta;
+static int repacking_superset;
static int local;
static int incremental;
static int allow_ofs_delta;
@@ -1172,10 +1173,13 @@ static int try_delta(struct unpacked *tr
return -1;
/*
- * We do not bother to try a delta that we discarded
- * on an earlier try, but only when reusing delta data.
+ * When we are packing the superset of objects we have already
+ * packed, we do not bother to try a delta that we discarded
+ * on an earlier try. This heuristic of course should not
+ * kick in when we are not reusing delta, or we know we are
+ * sending a subset of objects from a repository.
*/
- if (!no_reuse_delta && trg_entry->in_pack &&
+ if (!no_reuse_delta && repacking_superset && trg_entry->in_pack &&
trg_entry->in_pack == src_entry->in_pack)
return 0;
@@ -1493,6 +1497,16 @@ static void get_object_list(int ac, cons
traverse_commit_list(&revs, show_commit, show_object);
}
+static int count_packed_objects(void)
+{
+ struct packed_git *p;
+ int cnt = 0;
+
+ for (p = packed_git; p; p = p->next)
+ cnt += num_packed_objects(p);
+ return cnt;
+}
+
int cmd_pack_objects(int argc, const char **argv, const char *prefix)
{
SHA_CTX ctx;
@@ -1631,6 +1645,8 @@ int cmd_pack_objects(int argc, const cha
if (non_empty && !nr_result)
return 0;
+ repacking_superset = count_packed_objects() < nr_result;
+
SHA1_Init(&ctx);
list = sorted_by_sha;
for (i = 0; i < nr_result; i++) {
^ permalink raw reply related [relevance 1%]
* Re: What's in git.git
2006-11-08 4:13 2% ` David Lang
2006-11-08 16:40 1% ` Shallow clone [Was Re: What's in git.git ] Aneesh Kumar K.V
2006-11-09 2:28 0% ` What's in git.git Horst H. von Brand
@ 2006-11-12 22:25 3% ` Johannes Schindelin
2 siblings, 0 replies; 200+ results
From: Johannes Schindelin @ 2006-11-12 22:25 UTC (permalink / raw)
To: David Lang; +Cc: Junio C Hamano, git
Hi,
On Tue, 7 Nov 2006, David Lang wrote:
> On Tue, 7 Nov 2006, Junio C Hamano wrote:
>
> > [pu]
> >
> > Johannes's shallow clone work now should rebase cleanly on top
> > of 'master' although I haven't done so yet. As he said
> > himself the series is waiting for people who have needs for
> > such a feature to raise hands.
>
> I haven't been watching this recently, but if this is what I understand it to
> be (the ability to get a partial repository from upstream and work normally
> from there with the result of data-mineing tools sometimes reporting 'that's
> part of the truncated history' if they hit the cutoff) consider my hand
> raised.
For now, it does not say "part of the truncated history". But yes, shallow
clones are partial copies of remote repositories, by making some commits
"shallow", i.e. grafting an empty set of parents onto them (thereby
pretending that these commits are root commits).
Telling the user that a commit is shallow should not be too hard.
Ciao,
Dscho
^ permalink raw reply [relevance 3%]
* Re: Shallow clone
2006-11-12 21:59 1% ` Junio C Hamano
@ 2006-11-13 5:29 1% ` Junio C Hamano
0 siblings, 0 replies; 200+ results
From: Junio C Hamano @ 2006-11-13 5:29 UTC (permalink / raw)
To: Sergey Vlasov; +Cc: git
Junio C Hamano <junkio@cox.net> writes:
> Sergey Vlasov <vsu@altlinux.ru> writes:
>
>> This is due to optimization in builtin-pack-objects.c:try_delta():
>>
>> /*
>> * We do not bother to try a delta that we discarded
>> * on an earlier try, but only when reusing delta data.
>> */
>> if (!no_reuse_delta && trg_entry->in_pack &&
>> trg_entry->in_pack == src_entry->in_pack)
>> return 0;
>>
>> After removing this part the shallow pack after clone is 2.6M, as it
>> should be.
>>
>> The problem with this optimization is that it is only valid if we are
>> repacking either the same set of objects as we did earlier, or its
>> superset. But if we are packing a subset of objects, there will be some
>> objects in that subset which were delta-compressed in the original pack,
>> but base objects for that deltas are not included in our subset -
>> therefore we will be unable to reuse existing deltas, and with that
>> optimization we will never try to use delta compression for these
>> objects.
>> ...
>> So any partial fetch (shallow or not) from a mostly packed repository
>> currently results in a suboptimal pack.
What we tried to avoid with the original heuristics in commit
51d1e83f was to avoid wasting time on undeltifiable blobs, and
they would be stored as base in the original packs, so I think
the following would fly better (the patch is for maint, for
master we would also check for OBJ_REF_DELTA as well).
---
diff --git a/builtin-pack-objects.c b/builtin-pack-objects.c
index 96c069a..84a8749 100644
--- a/builtin-pack-objects.c
+++ b/builtin-pack-objects.c
@@ -1101,7 +1101,8 @@ static int try_delta(struct unpacked *tr
* on an earlier try, but only when reusing delta data.
*/
if (!no_reuse_delta && trg_entry->in_pack &&
- trg_entry->in_pack == src_entry->in_pack)
+ trg_entry->in_pack == src_entry->in_pack &&
+ trg_entry->in_pack_type != OBJ_DELTA)
return 0;
/*
^ permalink raw reply related [relevance 1%]
* [ANNOUNCE] GIT 1.4.4
@ 2006-11-15 7:43 1% Junio C Hamano
0 siblings, 0 replies; 200+ results
From: Junio C Hamano @ 2006-11-15 7:43 UTC (permalink / raw)
To: git; +Cc: linux-kernel
The latest feature release GIT 1.4.4 is available at the usual
places:
http://www.kernel.org/pub/software/scm/git/
git-1.4.4.tar.{gz,bz2} (tarball)
git-htmldocs-1.4.4.tar.{gz,bz2} (preformatted docs)
git-manpages-1.4.4.tar.{gz,bz2} (preformatted docs)
RPMS/$arch/git-*-1.4.4-1.$arch.rpm (RPM)
Quite a lot of changes during the last month.
- pack-refs, along with a lot of internal clean-up of the code
that deal with refs, is in. A repository with many tags
would benefit from packing and pruning them. Currently dumb
transports are not capable of fetching from a repository that
has packed and pruned its refs, so please keep that in mind.
Hopefully we will get an update for dumb transports shortly.
- git native transport can now keep transferred packs without
exploding it into loose objects. Also "git repack" can be
told to keep "historical" packs from getting repacked by
marking them with .keep file. Docmentation update is
probably needed.
- git-blame can now detect line movements across files. No, it
is not called git-pickaxe.
- a lot of gitweb and git-svn updates.
----------------------------------------------------------------
Changes since v1.4.3 are as follows:
Alan Chandler:
Gitweb - provide site headers and footers
Alex Riesen:
merge-recursive implicitely depends on trust_executable_bit
Alexandre Julliard:
git.el: Added a function to open the current file in another window.
git.el: Added functions for moving to the next/prev unmerged file.
git.el: Include MERGE_MSG in the log-edit buffer even when not committing a merge.
git.el: Move point after the log message header when entering log-edit mode.
pack-refs: Store the full name of the ref even when packing only tags.
prune-packed: Fix uninitialized variable.
Andy Parkins:
git-clone documentation didn't mention --origin as equivalent of -o
Make filenames line up in git-status output
Minor grammar fixes for git-diff-index.txt
Remove uneccessarily similar printf() from print_ref_list() in builtin-branch
Andy Whitcroft:
cvsimport: move over to using git-for-each-ref to read refs.
git-for-each-ref: improve the documentation on scripting modes
Aneesh Kumar K.V:
gitweb: Remove extra "/" in path names for git_get_project_list
Christian Couder:
Add pack-refs and show-ref test cases.
Add [-s|--hash] option to Linus' show-ref.
Check that a tag exists using show-ref instead of looking for the ref file.
Clean up "git-branch.sh" and add remove recursive dir test cases.
Documentation: add git in /etc/services.
Documentation: add upload-archive service to git-daemon.
Document git-show-ref [-s|--hash] option.
Do not create tag leading directories since git update-ref does it.
Fix a remove_empty_dir_recursive problem.
Fix show-ref usage for --dereference.
Remove --syslog in git-daemon inetd documentation examples.
Uncomment test case: git branch c/d should barf if branch c exists.
Use git-update-ref to delete a tag instead of rm()ing the ref file.
Use Linus' show ref in "git-branch.sh".
When creating branch c/d check that branch c does not already exists.
Dennis Stosberg:
lock_ref_sha1_basic does not remove empty directories on BSD
Remove bashism from t3210-pack-refs.sh
Bash completion support for aliases
Dmitry V. Levin:
git-clone: define die() and use it.
Edgar Toernig:
Use memmove instead of memcpy for overlapping areas
Eric Wong:
git-send-email: do not pass custom Date: header
git-svn: avoid printing filenames of files we're not tracking
git-svn: don't die on rebuild when --upgrade is specified
git-svn: fix dcommit losing changes when out-of-date from svn
git-svn: fix symlink-to-file changes when using command-line svn 1.4.0
Gerrit Pape:
Set $HOME for selftests
J. Bruce Fields:
Make prune also run prune-packed
Documentation: updates to "Everyday GIT"
Jakub Narebski:
diff-format.txt: Combined diff format documentation supplement
diff-format.txt: Correct information about pathnames quoting in patch format
Documentation: Transplanting branch with git-rebase --onto
Documentation: Update information about <format> in git-for-each-ref
gitweb: Add "next" link to commitdiff view
gitweb: Add '..' (up directory) to tree view if applicable
gitweb: Better git-unquoting and gitweb-quoting of pathnames
gitweb: Better support for non-CSS aware web browsers
gitweb: Check git base URLs before generating URL from it
gitweb: Do not esc_html $basedir argument to git_print_tree_entry
gitweb: Filter out commit ID from @difftree in git_commit and git_commitdiff
gitweb: Get rid of git_print_simplified_log
gitweb: Improve git_print_page_path
gitweb: Move git_get_last_activity subroutine earlier
gitweb: New improved patchset view
gitweb: Output also empty patches in "commitdiff" view
gitweb: Print commit message without title in commitdiff only if there is any
gitweb: Secure against commit-ish/tree-ish with the same name as path
gitweb: Use character or octal escape codes (and add span.cntrl) in esc_path
gitweb: Use git-for-each-ref to generate list of heads and/or tags
gitweb: Use --no-commit-id in git_commit and git_commitdiff
gitweb: Use 's' regexp modifier to secure against filenames with LF
gitweb: Whitespace cleanup - tabs are for indent, spaces are for align (2)
Jan Harkes:
Continue traversal when rev-list --unpacked finds a packed commit.
Jeff King:
wt-status: use simplified resolve_ref to find current branch
gitignore: git-pack-refs is a generated file.
gitignore: git-show-ref is a generated file.
git-pickaxe: work properly in a subdirectory.
Fix git-runstatus for repositories containing a file named HEAD
Jim Meyering:
Don't use $author_name undefined when $from contains no /\s</.
git-clone: honor --quiet
xdiff/xemit.c (xdl_find_func): Elide trailing white space in a context header.
Johannes Schindelin:
Fix git-update-index --again
show-branch: mark active branch with a '*' again
Turn on recursive with --summary
link_temp_to_file: call adjust_shared_perm() only when we created the directory
Johannes Sixt:
test-lib.sh: A command dying due to a signal is an unexpected failure.
Catch errors when writing an index that contains invalid objects.
Jonas Fonseca:
Add man page for git-show-ref
git-update-index(1): fix use of quoting in section title
Junio C Hamano:
Add callback data to for_each_ref() family.
Add git-for-each-ref: helper for language bindings
adjust_shared_perm: chmod() only when needed.
apply: handle "traditional" creation/deletion diff correctly.
blame.c: move code to output metainfo into a separate function.
blame.c: whitespace and formatting clean-up.
blame: Document and add help text for -f, -n, and -p
branch: work in subdirectories.
cherry is built-in, do not ship git-cherry.sh
Clean-up lock-ref implementation
combine-diff: a few more finishing touches.
combine-diff: fix hunk_comment_line logic.
combine-diff: honour --no-commit-id
core.logallrefupdates create new log file only for branch heads.
core.logallrefupdates thinko-fix
daemon: do not die on older clients.
delete_ref(): delete packed ref
diff --numstat
Documentation: clarify refname disambiguation rules.
Documentation: fix git-format-patch mark-up and link it from git.txt
Documentation: move blame examples
Documentation: note about contrib/.
Documentation/SubmittingPatches: 3+1 != 6
Document git-pack-refs and link it to git(7).
Fix refs.c;:repack_without_ref() clean-up path
Fix t1400-update-ref test minimally
for-each-ref: "creator" and "creatordate" fields
fsck-objects: adjust to resolve_ref() clean-up.
GIT 1.4.3-rc1
GIT 1.4.4
GIT 1.4.4-rc2
git-annotate: fix -S on graft file with comments.
git-annotate: no need to exec blame; it is built-in now.
git-blame: add internal statistics to count read blobs.
git-blame --porcelain
git-blame: --show-name (and -f)
git-blame: --show-number (and -n)
git-branch: remove D/F check done by hand.
git-cvsserver: read from git with -z to get non-ASCII pathnames.
git-diff/git-apply: make diff output a bit friendlier to GNU patch (part 1)
git-fetch: adjust to packed-refs.
git-fetch: do not look into $GIT_DIR/refs to see if a tag exists.
git-pack-refs --all
git-pack-refs --prune
git-pickaxe: allow -Ln,m as well as -L n,m
git-pickaxe: allow "-L <something>,+N"
git-pickaxe: blame rewritten.
git-pickaxe: cache one already found path per commit.
git-pickaxe -C: blame cut-and-pasted lines.
git-pickaxe: do not confuse two origins that are the same.
git-pickaxe: do not keep commit buffer.
git-pickaxe: fix nth_line()
git-pickaxe: fix origin refcounting
git-pickaxe: get rid of wasteful find_origin().
git-pickaxe: improve "best match" heuristics
git-pickaxe: introduce heuristics to avoid "trivial" chunks
git-pickaxe: -L /regexp/,/regexp/
git-pickaxe -M: blame line movements within a file.
git-pickaxe: optimize by avoiding repeated read_sha1_file().
git-pickaxe: pagenate output by default.
git-pickaxe: refcount origin correctly in find_copy_in_parent()
git-pickaxe: rename detection optimization
git-pickaxe: re-scan the blob after making progress with -C
git-pickaxe: re-scan the blob after making progress with -M
git-pickaxe: retire pickaxe
git-pickaxe: simplify Octopus merges further
git-pickaxe: split find_origin() into find_rename() and find_origin().
git-pickaxe: swap comparison loop used for -C
git-pickaxe: tighten sanity checks.
git-pickaxe: WIP to refcount origin structure.
git-repack: repo.usedeltabaseoffset
git-send-email: do not drop custom headers the user prepared
git-send-email: real name with period need to be dq-quoted on From: line
git-status: quote LF in its output
gitweb: do not give blame link unconditionally in diff-tree view
gitweb: fix disabling of "forks"
gitweb: fix unmatched div in commitdiff
gitweb: make leftmost column of blame less cluttered.
gitweb: minimally fix "fork" support.
gitweb: prepare for repositories with packed refs.
gitweb: protect blob and diff output lines from controls.
gitweb: protect commit messages from controls.
gitweb: spell "blame --porcelain" with -p
gitweb: use blame --porcelain
gitweb: use for-each-ref to show the latest activity across branches
grep --all-match
Introduce a new revision set operator <rev>^!
link_temp_to_file: don't leave the path truncated on adjust_shared_perm failure
lock_ref_sha1_basic: remove unused parameter "plen".
lock_ref_sha1(): check D/F conflict with packed ref when creating.
lock_ref_sha1(): do not sometimes error() and sometimes die().
Make git-send-email detect mbox-style patches more readily
merge: loosen overcautious "working file will be lost" check.
merge-recursive: adjust to loosened "working file clobbered" check
merge-recursive: make a few functions static.
merge-recursive: use abbreviated commit object name.
pack-objects: document --delta-base-offset option
pack-refs: call fflush before fsync.
pack-refs: do not pack symbolic refs.
pack-refs: fix git_path() usage.
pack-refs: use lockfile as everybody else does.
pager: default to LESS=FRS
pager: default to LESS=FRSX not LESS=FRS
path-list: fix path-list-insert return value
quote.c: ensure the same quoting across platforms.
receive-pack: call setup_ident before git_config
Refer to git-rev-parse:Specifying Revisions from git.txt
ref locking: allow 'foo' when 'foo/bar' used to exist but not anymore.
ref-log: allow ref@{count} syntax.
ref-log: fix D/F conflict coming from deleted refs.
refs: minor restructuring of cached refs data.
Revert 954a6183756a073723a7c9fd8d2feb13132876b0
Revert "send-pack --keep: do not explode into loose objects on the receiving end."
revision traversal: --unpacked does not limit commit list anymore.
RPM package re-classification.
send-pack --keep: do not explode into loose objects on the receiving end.
sha1_name.c: avoid compilation warnings.
show-ref --hash=len, --abbrev=len, and --abbrev
Surround "#define DEBUG 0" with "#ifndef DEBUG..#endif"
symbolit-ref: fix resolve_ref conversion.
t3200: git-branch testsuite update
t6022: ignoring untracked files by merge-recursive when they do not matter
Teach receive-pack about ref-log
teach revision walker about --all-match.
Tell between packed, unpacked and symbolic refs.
tests: merge-recursive is usable without Python
update a few Porcelain-ish for ref lock safety.
Update cherry documentation.
update-ref: -d flag and ref creation safety.
Karl Hasselström:
git-vc: better installation instructions
ignore-errors requires cl
Lars Hjemli:
Fix typo in show-index.c
Fix usagestring for git-branch
Make git-branch a builtin
Fix show-ref usagestring
Linus Torvalds:
Add "git show-ref" builtin command
Teach "git checkout" to use git-show-ref
Start handling references internally as a sorted in-memory list
Add support for negative refs
Make ref resolution saner
Enable the packed refs file format
git-apply: prepare for upcoming GNU diff -u format change.
Allow '-' in config variable names
git push: add verbose flag and allow overriding of default target repository
Luben Tuikov:
gitweb: blame: print commit-8 on the leading row of a commit-block
gitweb: blame: Mouse-over commit-8 shows author and date
gitweb: blame porcelain: lineno and orig lineno swapped
git-revert with conflicts to behave as git-merge with conflicts
gitweb: esc_html() author in blame
Martin Waitz:
gitweb: start to generate PATH_INFO URLs.
gitweb: warn if feature cannot be overridden.
Matthew Wilcox:
Add --dry-run option to git-send-email
Nguyễn Thái Ngọc Duy:
Reject hexstring longer than 40-bytes in get_short_sha1()
Add revspec documentation for ':path', ':[0-3]:path' and git-describe
Nicolas Pitre:
introduce delta objects with offset to base
teach git-unpack-objects about deltas with offset to base
teach git-index-pack about deltas with offset to base
make git-pack-objects able to create deltas with offset to base
make pack data reuse compatible with both delta types
let the GIT native protocol use offsets to delta base when possible
zap a debug remnant
allow delta data reuse even if base object is a preferred base
index-pack: compare only the first 20-bytes of the key.
reduce delta head inflated size
add the capability for index-pack to read from a stream
enable index-pack streaming capability
make index-pack able to complete thin packs.
add progress status to index-pack
mimic unpack-objects when --stdin is used with index-pack
enhance clone and fetch -k experience
index-pack: minor fixes to comment and function name
missing small substitution
pack-objects doesn't create random pack names
make git-push a bit more verbose
Allow pack header preprocessing before unpack-objects/index-pack.
git-fetch can use both --thin and --keep with fetch-pack now
improve fetch-pack's handling of kept packs
have index-pack create .keep file more carefully
remove .keep pack lock files when done with refs update
git-pack-objects progress flag documentation and cleanup
OGAWA Hirofumi:
gitk: Fix nextfile() and add prevfile()
Petr Baudis:
Fix broken sha1 locking
Fix buggy ref recording
gitweb: Document features better
gitweb: Fix search form when PATH_INFO is enabled
bisect reset: Leave the tree in usable state if git-checkout failed
gitweb: Fix setting $/ in parse_commit()
gitweb: Restore object-named links in item lists
gitweb: Make search type a popup menu
gitweb: Do not automatically append " git" to custom site name
gitweb: Show project's README.html if available
xdiff: Match GNU diff behaviour when deciding hunk comment worthiness of lines
gitweb: Support for 'forks'
gitweb: Fix up bogus $stylesheet declarations
Nicer error messages in case saving an object to db goes wrong
Rene Scharfe:
git-archive --format=zip: use default version ID
git-archive --format=zip: add symlink support
git-merge: show usage if run without arguments
Built-in cherry
Make git-cherry handle root trees
git-cherry: document limit and add diagram
Robert Shearman:
git-rebase: Use --ignore-if-in-upstream option when executing git-format-patch.
git-rebase: Add a -v option to show a diffstat of the changes upstream at the start of a rebase.
git-rebase: Use --ignore-if-in-upstream option when executing git-format-patch.
Robin Rosenberg:
Mention that pull can work locally in the synopsis
Swap the porcelain and plumbing commands in the git man page
Rework cvsexportcommit to handle binary files for all cases.
Ryan Anderson:
Remove git-annotate.perl and create a builtin-alias for git-blame
Santi Béjar:
fetch: Misc output cleanup
merge and resolve: Output short hashes and .. in "Updating ..."
Documentation for the [remote] config
Sasha Khapyorsky:
git-svnimport.perl: copying directory from original SVN place
git-svnimport: support for partial imports
Sean Estabrooks:
Add --global option to git-repo-config.
Sergey Vlasov:
git-send-email: Document support for local sendmail instead of SMTP server
git-send-email: Read the default SMTP server from the GIT config file
Shawn Pearce:
Added completion support for git-branch.exe.
Added bash completion support for git-reset.
Use ULONG_MAX rather than implicit cast of -1.
Remove SIMPLE_PROGRAMS and make git-daemon a normal program.
Remove unsupported C99 style struct initializers in git-archive.
Added missing completions for show-branch and merge-base.
Only load .exe suffix'd completions on Cygwin.
Bash completion support for remotes in .git/config.
Take --git-dir into consideration during bash completion.
Support bash completion on symmetric difference operator.
Remove more sed invocations from within bash completion.
Use column indexes in git-cvsserver where necessary.
Allow short pack names to git-pack-objects --unpacked=.
Only repack active packs by skipping over kept packs.
Teach git-index-pack how to keep a pack file.
Remove unused variable in receive-pack.
Move deny_non_fast_forwards handling completely into receive-pack.
Teach receive-pack how to keep pack files based on object count.
Tero Roponen:
remove an unneeded test
Tuncer Ayaz:
git-fetch.sh printed protocol fix
^ permalink raw reply [relevance 1%]
* Re: Cleaning up git user-interface warts
@ 2006-11-15 20:51 2% ` Carl Worth
0 siblings, 0 replies; 200+ results
From: Carl Worth @ 2006-11-15 20:51 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, Andy Whitcroft, Petr Baudis
[-- Attachment #1: Type: text/plain, Size: 6788 bytes --]
On Tue, 14 Nov 2006 16:31:50 -0800, Junio C Hamano wrote:
> I do not think the Porcelain-ish UI that is shipped with git
> should be taken with the same degree of "authority" as git
> Plumbing.
I think we should fix this. "This is great technology with a crap
interface on top" really isn't a good story. I don't actually agree
with that---I don't think the git interface is really all that bad,
it's just got a few little things that tend to trip up new users in my
experience.
And what git does really well, (history exploring, allowing for
pipeline on-liners to iterate over revisions in A..B), are things that
don't even exist in other tools, nor even in the "alternate"
porcelains for git. This stuff is where git's interface is really
fantastic, and it would be a shame to write it off.
> I think
> single isolated developers, contributors and CVS style shared
> repository usage could be a lot improved because neither of us
> were concentrating in their workflows. This needs somebody
> motivated enough to improve things in that area. For example,
> StGIT with its 'float' command is a great improvement over what
> rebase does for people in the contributor role.
Yes, there are some specific workflow-oriented operations that git
doesn't handle as well as it could. Things like commit --amend are
certainly improvements. One that is still totally broken is "follow
all the development in another repository" where clone followed by
repeated fetch doesn't do the job as soon as the remote adds or
deletes a branch.
> But making it more usable for whom is a big question.
>
> Quite frankly, I do not think there can be _the_ single UI that
> would satisfy different types of workflows for some of the
> commands.
I strongly disagree. Or at least, I don't think we've tried hard
enough yet that we should give up on this.
I do agree that people in different roles will have different lists of
"most used operations" and that some operations won't appear on some
users lists at all, (someone who's just "watching" development won't
commit or merge, for example---[or so they thing when they start]).
But I really don't think that for any given operation that different
roles impose a different desire on the behavior of the operation. We
have different people with different background and disagreement on
names and silly things like that, but I don't think that's related to
the roles in which they are working with the tool.
> For example, fetching and merging from many places without
> necessarily having corresponding tracking branches is a great
...
I don't think we've ever had this right in git. The new
--use-separate-remotes stuff or similar will start to help as it
becomes the default. I don't see how this won't benefit everybody.
> For another example, having a commit command to commit
> everything by default is disastrous for people who allow their
> workflows to often be interrupted.
Workflow-interruption is an important thing to support, but separating
update-index and commit really doesn't address it nearly as much as I
would like. The lack of really good workflow-interruption support has
been one of my longest-running annoyances with git, (perhaps because I
have a problem with trying to do too many things at once). Git can
create and change branches fast enough that it really should be able
to help me better with this. The only missing piece is being able to
stash the dirty stuff on the current branch, to be able to come back
to it later. I've talked a bit about what I would like in this area
before, and I really just need to code it up.
> It is not just command line syntax and the defaults, but
> concepts as well. People in the integrator role often need to
> deal with merges and you would need to be aware of the role of
> the index and need to be able to manipulate the index, ...
Again, I think it's more that the specific operations bring in
concepts, (merge bringing in the index here). As such, someone never
doing a merge could easily get by not having to understand the index.
> A Porcelain that does a very similar thing in slightly different
> way is obviously a waste, but otherwise I do not think it is a
> problem to have different Porcelains. StGIT does not compete
> with the "sucky" Porcelain-ish shipped with git but makes the
> user's life a lot more pleasant by complementing what the sucky
> one does not do well. It is not very useful while I am playing
> the integrator role, but when I am doing my own thing it is a
> great addition to my toolchest.
But even here, there's a bunch of waste in StGit. For example, there
are a lot of commands in StGit whose only purpose is to translate back
and forth between the StGit and non-StGit views of the world, (init,
assimilate, commit, uncommit). Those could all be discarded if the
functionality of StGit were brought down into git itself. Then there
are a myriad of StGit commands which are basically just the same as
their git counterparts.
Now, StGit is a great tool, and I know that it works really well for
some people in the role of just maintaining a stack of changes against
some upstream, and can use StGit alone and never touch "git" the
command-line.
But for someone like me who already uses git regularly, and
occasionally just wants to pop back a few commits, amend it, and then
push again, StGit is not helpful, (the series of init, assimilate, and
uncommits just to get started is prohibitive compared to just working
out the awkward steps needed to make a temporary branch and
rebase). So I'd love to see just a couple of commands added to "git"
to support these kinds of operations more smoothly.
> I am from the camp that does _not_ want to hide the index, so
> obviously I do not see any value in its effort to hide the
> index. But other aspects of it, most notably being friendly to
> simpler workflows, is a very good thing.
I don't think "hide or not-to-hide" is the right way to frame the
discussion about the index. I regularly use update-index to stage
partial commits, and I find that very useful. And obviously the index
is involved in resolving merge conflicts.
But I don't think the user-interface for either of those operations
(partial commit, resolve conflicts), is ideal, and the current
requirement to use either "update-index <paths>" or "commit -a" after
modifying a file for the first time is demonstrably a hangup for a lot
of new users. So I really think it's possible to address both of these
at once.
Anyone, that's enough generic rambling from me without any specific
content. I'll try to keep future messages focused on specific
desirable operations that have problematic interfaces in git right
now, along with proposals for improving them.
-Carl
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply [relevance 2%]
* What's in git.git
@ 2006-11-25 10:12 3% Junio C Hamano
0 siblings, 0 replies; 200+ results
From: Junio C Hamano @ 2006-11-25 10:12 UTC (permalink / raw)
To: git; +Cc: linux-kernel
Executive Summary
=================
The 'maint' branch still has a handful more post v1.4.4.1
fixes.
Aside from the usual gitweb and git-svn updates, the 'master'
branch has one notable change that everybody should hopefully
welcome. separate-remote layout is now the default for newly
cloned repositories. We would be needing documentation updates
and probably some more minor fixes for fallout from this, but I
do not expect anything majorly broken.
Cooking in 'next' are handful topics:
* "git shortlog bottom..top" can be used instead of a pipeline
"git log bottom..top | git shortlog".
* "git merge -m message <commit>" is another natural way to
perform a local merge, in addition to the traditional
"git pull . <localbranch>". The former is more powerful in
that it can take arbitrary <committish>, not just a ref.
* The new "--depth $n" parameter to git clone/fetch tries to
limit the commit ancestry depth to $n. This still has known
issues (for example, shallowly cloning the git.git repository
and then deepening the result with large --depth parameter
later does not seem to make the resulting repository fully
connected, and fsck-objects reports corruption), so please
handle it with care.
* "git show-ref", especially the "-d" variant, is much more
efficient when used in a repository with pack-pruned refs.
* "git fetch" can fetch from a repository with pack-pruned refs
over dumb protocol transports.
* "git push $URL '':$ref" can be used to delete an existing ref
from the remote side.
* A glob pattern "Pull: refs/heads/*:refs/remotes/origin/*" is
allowed in the remotes file. The fetch can be forced by
prefixing the specification with a '+'.
Currently 'pu' does not have much to speak of.
This update has rather large impact so the kernel list is CC'ed.
----------------------------------------------------------------
* The 'maint' branch has these fixes since the last announcement.
Andy Parkins (1):
Increase length of function name buffer
Eric Wong (3):
git-svn: error out from dcommit on a parent-less commit
git-svn: correctly handle revision 0 in SVN repositories
git-svn: preserve uncommitted changes after dcommit
René Scharfe (1):
archive-zip: don't use sizeof(struct ...)
* The 'master' branch has these since the last announcement.
Andy Parkins (3):
Improve git-prune -n output
Add support to git-branch to show local and remote branches
Increase length of function name buffer
Eric Wong (6):
git-svn: error out from dcommit on a parent-less commit
git-svn: correctly handle revision 0 in SVN repositories
git-svn: preserve uncommitted changes after dcommit
git-svn: handle authentication without relying on cached tokens on disk
git-svn: correctly access repos when only given partial read permissions
git-svn: exit with status 1 for test failures
Iñaki Arenaza (1):
git-cvsimport: add support for CVS pserver method HTTP/1.x proxying
Jakub Narebski (8):
gitweb: Protect against possible warning in git_commitdiff
gitweb: Buffer diff header to deal with split patches + git_patchset_body refactoring
gitweb: Default to $hash_base or HEAD for $hash in "commit" and "commitdiff"
gitweb: New improved formatting of chunk header in diff
gitweb: Add an option to href() to return full URL
gitweb: Refactor feed generation, make output prettier, add Atom feed
gitweb: Finish restoring "blob" links in git_difftree_body
gitweb: Replace SPC with also in tag comment
Junio C Hamano (9):
upload-pack: stop the other side when they have more roots than we do.
apply --numstat: mark binary diffstat with - -, not 0 0
pack-objects: tweak "do not even attempt delta" heuristics
refs outside refs/{heads,tags} match less strongly.
Typefix builtin-prune.c::prune_object()
gitweb: (style) use chomp without parentheses consistently.
git-clone: stop dumb protocol from copying refs outside heads/ and tags/.
git-branch -D: make it work even when on a yet-to-be-born branch
git-fetch: exit with non-zero status when fast-forward check fails
Lars Hjemli (1):
Add -v and --abbrev options to git-branch
Peter Baumann (1):
config option log.showroot to show the diff of root commits
Petr Baudis (1):
Make git-clone --use-separate-remote the default
René Scharfe (1):
archive-zip: don't use sizeof(struct ...)
* The 'next' branch, in addition, has these.
Alexandre Julliard (6):
Shallow clone: do not ignore shallowness when following tags
fetch-pack: Properly remove the shallow file when it becomes empty.
upload-pack: Check for NOT_SHALLOW flag before sending a shallow to the client.
git-fetch: Reset shallow_depth before auto-following tags.
get_shallow_commits: Avoid memory leak if a commit has been reached already.
fetch-pack: Do not fetch tags for shallow clones.
Jakub Narebski (1):
gitweb: Do not use esc_html in esc_path
Johannes Schindelin (10):
Build in shortlog
shortlog: do not crash on parsing "[PATCH"
shortlog: read mailmap from ./.mailmap again
shortlog: handle email addresses case-insensitively
shortlog: fix "-n"
upload-pack: no longer call rev-list
support fetching into a shallow repository
allow cloning a repository "shallowly"
allow deepening of a shallow repository
add tests for shallow stuff
Junio C Hamano (19):
Store peeled refs in packed-refs file.
remove merge-recursive-old
git-merge: make it usable as the first class UI
merge: allow merging into a yet-to-be-born branch.
git-diff/git-apply: make diff output a bit friendlier to GNU patch (part 2)
Store peeled refs in packed-refs (take 2).
git-fetch: reuse ls-remote result.
git-fetch: fix dumb protocol transport to fetch from pack-pruned ref
git-fetch: allow glob pattern in refspec
Allow git push to delete remote ref.
We should make sure that the protocol is still extensible.
Why does it mean we do not have to register shallow if we have one?
Why didn't we mark want_obj as ~UNINTERESTING in the old code?
shallow clone: unparse and reparse an unshallowed commit
git-shortlog: fix common repository prefix abbreviation.
git-shortlog: make common repository prefix configurable with .mailmap
git-commit: show --summary after successful commit.
git-fetch: allow forcing glob pattern in refspec
fetch-pack: do not barf when duplicate re patterns are given
Nicolas Pitre (1):
builtin git-shortlog is broken
* The 'pu' branch, in addition, has these.
Junio C Hamano (4):
para-walk: walk n trees, index and working tree in parallel
rev-list --left-right
blame: --show-stats for easier optimization work.
gitweb: steal loadavg throttle from kernel.org
^ permalink raw reply [relevance 3%]
* [PATCH] (experimental) per-topic shortlog.
@ 2006-11-27 0:44 2% Junio C Hamano
0 siblings, 0 replies; 200+ results
From: Junio C Hamano @ 2006-11-27 0:44 UTC (permalink / raw)
To: git; +Cc: Johannes Schindelin
This implements an experimental "git log-fpc" command that shows
short-log style output sorted by topics.
A "topic" is identified by going through the first-parent
chains; this ignores the fast-forward case, but for a top-level
integrator it often is good enough.
For example, if the commit ancestry graph looks like this:
x---x---x---X---o---*---o---o---o HEAD
\ /
o---o---o---o---o
and the command line asks for
git log-fpc --no-merges X..
It first finds all the commits 'o'. Then it emits the four
commits on the upper line (assume the merge '*' has the commit
that is a child of X as its first parent in the picture). When
it does so, it the list of authors for these four commits on one
line, followed by the title of these commits. After that, it
does the same for the five commits on the lower line.
---
I initially wanted to do this inside Johannes's enhanced
shortlog, but ended up doing this as a pretty much independent
thing, because the shortlog implementation stringifies the
information from the commits too early to be easily enhanced for
this purpose.
If this turns out to be a better way to present shortlog,
however, this should become an option to git-shortlog.
A sample output from:
git log-fpc --no-merges v1.4.4.1..f64d7fd2
looks like this (f64d7fd2 was the tip of master when the last
"What's in" message was sent out). It shows that many "fixes"
and git-svn enhancements were directly done on "master" (that is
the first group), while many gitweb enhancements, changing the
output from "prune -n", "git branch" enhancements, etc. were
first cooked in separate topic branches and then later merged
into 'master'.
To this output, I can manually add a topic title to the
beginning of each group and it would make a better overview than
what I currently send out in "What's in" message which is
generated with shortlog.
----------------------------------------------------------------
Eric Wong (6), Junio C Hamano (5), Lars Hjemli, Jakub Narebski,
Iñaki Arenaza, Petr Baudis, Andy Parkins, and René Scharfe
git-fetch: exit with non-zero status when fast-forward check fails
git-svn: exit with status 1 for test failures
git-svn: correctly access repos when only given partial read permissions
git-branch -D: make it work even when on a yet-to-be-born branch
Add -v and --abbrev options to git-branch
git-clone: stop dumb protocol from copying refs outside heads/ and tags/.
gitweb: (style) use chomp without parentheses consistently.
gitweb: Replace SPC with also in tag comment
git-svn: handle authentication without relying on cached tokens on disk
git-cvsimport: add support for CVS pserver method HTTP/1.x proxying
Make git-clone --use-separate-remote the default
refs outside refs/{heads,tags} match less strongly.
Increase length of function name buffer
git-svn: preserve uncommitted changes after dcommit
git-svn: correctly handle revision 0 in SVN repositories
git-svn: error out from dcommit on a parent-less commit
archive-zip: don't use sizeof(struct ...)
Junio C Hamano and Andy Parkins
Typefix builtin-prune.c::prune_object()
Improve git-prune -n output
Peter Baumann
config option log.showroot to show the diff of root commits
Andy Parkins
Add support to git-branch to show local and remote branches
Jakub Narebski (7)
gitweb: Finish restoring "blob" links in git_difftree_body
gitweb: Refactor feed generation, make output prettier, add Atom feed
gitweb: Add an option to href() to return full URL
gitweb: New improved formatting of chunk header in diff
gitweb: Default to $hash_base or HEAD for $hash in "commit" and "commitdiff"
gitweb: Buffer diff header to deal with split patches + git_patchset_body refactoring
gitweb: Protect against possible warning in git_commitdiff
----------------------------------------------------------------
builtin-log.c | 177 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
builtin.h | 1 +
git.c | 1 +
3 files changed, 179 insertions(+), 0 deletions(-)
diff --git a/builtin-log.c b/builtin-log.c
index 7acf5d3..1c2838c 100644
--- a/builtin-log.c
+++ b/builtin-log.c
@@ -99,6 +99,183 @@ int cmd_log(int argc, const char **argv, const char *prefix)
return cmd_log_walk(&rev);
}
+/* bits #0..7 in revision.h, #8..11 in commit.c */
+#define FPC_RESULT (1u<<12)
+#define FPC_SHOWN (1u<<13)
+
+struct author_record {
+ char *name;
+ int count;
+};
+struct author_count {
+ int nr, alloc;
+ struct author_record **au;
+};
+
+static int cmp_count(const void *a_, const void *b_)
+{
+ struct author_record **a = (struct author_record **) a_;
+ struct author_record **b = (struct author_record **) b_;
+ return (*b)->count - (*a)->count;
+}
+
+static void add_author(struct commit *c, struct author_count *ac)
+{
+ const char *buf = c->buffer;
+ char *au = strstr(buf, "\nauthor ");
+ char *eon;
+ struct author_record *ar;
+ int i;
+
+ if (!au)
+ return; /* oops */
+ au += 7;
+ while (*au && isspace(*au))
+ au++;
+ if (!*au)
+ return; /* oops */
+ eon = strchr(au, '<');
+ if (!eon)
+ return; /* oops */
+ while (au < --eon && isspace(*eon))
+ ; /* back back back... */
+ eon++;
+ for (i = 0; i < ac->nr; i++)
+ if (!strncmp(ac->au[i]->name, au, eon-au) &&
+ strlen(ac->au[i]->name) == eon - au) {
+ /* found it */
+ ac->au[i]->count++;
+ return;
+ }
+ if (ac->alloc <= ac->nr) {
+ ac->alloc = alloc_nr(ac->alloc);
+ ac->au = xrealloc(ac->au, sizeof(struct author_record *) *
+ ac->alloc);
+ }
+ ar = xcalloc(1, sizeof(struct author_record));
+ ar->name = xmalloc(eon - au + 1);
+ memcpy(ar->name, au, eon - au);
+ ar->name[eon - au] = 0;
+ ar->count = 1;
+ ac->au[ac->nr++] = ar;
+}
+
+static void show_fpc(struct object_array *list)
+{
+ int i;
+ struct author_count ac;
+
+ if (!list->nr)
+ return;
+ memset(&ac, 0, sizeof(ac));
+ for (i = 0; i < list->nr; i++)
+ add_author((struct commit *) list->objects[i].item, &ac);
+ qsort(ac.au, ac.nr, sizeof(struct author_record *), cmp_count);
+
+ for (i = 0; i < ac.nr; i++) {
+ if (i) {
+ if (i < ac.nr - 1)
+ fputs(", ", stdout);
+ else if (ac.nr != 2)
+ fputs(", and ", stdout);
+ else
+ fputs(" and ", stdout);
+ }
+ if (ac.au[i]->count < 2)
+ printf("%s", ac.au[i]->name);
+ else
+ printf("%s (%d)", ac.au[i]->name, ac.au[i]->count);
+ free(ac.au[i]->name);
+ free(ac.au[i]);
+ }
+ free(ac.au);
+ putchar('\n');
+
+ for (i = 0; i < list->nr; i++) {
+ struct commit *c = (struct commit *) list->objects[i].item;
+ char *buf = c->buffer;
+ char *it = "<unnamed>";
+ int len = strlen(it);
+ buf = strstr(buf, "\n\n");
+ if (buf) {
+ char *lineend;
+ while (*buf && isspace(*buf))
+ buf++;
+ if (!*buf)
+ goto emit;
+ lineend = strchr(buf, '\n');
+ if (!lineend)
+ goto emit;
+ while (buf < lineend && isspace(*lineend))
+ lineend--;
+ len = lineend - buf + 1;
+ it = buf;
+ }
+ emit:
+ printf(" %.*s\n", len, it);
+ }
+ putchar('\n');
+}
+
+int cmd_log_fpc(int argc, const char **argv, const char *prefix)
+{
+ struct rev_info rev;
+ struct commit *c;
+ struct object_array result = { 0, 0, NULL };
+ int i;
+
+ git_config(git_log_config);
+ init_revisions(&rev, prefix);
+ rev.always_show_header = 1;
+ cmd_log_init(argc, argv, prefix, &rev);
+
+ prepare_revision_walk(&rev);
+ while ((c = get_revision(&rev)) != NULL)
+ add_object_array(&(c->object), NULL, &result);
+
+ /* clear flags and mark them "relevant" */
+ for (i = 0; i < result.nr; i++)
+ result.objects[i].item->flags |= FPC_RESULT;
+
+ for (;;) {
+ struct object_array current;
+
+ for (i = 0; i < result.nr; i++) {
+ if (!(result.objects[i].item->flags & FPC_SHOWN))
+ break;
+ }
+ if (i >= result.nr)
+ break;
+
+ memset(¤t, 0, sizeof(current));
+ c = (struct commit *) result.objects[i].item;
+ while (c) {
+ int flags = c->object.flags;
+
+ if ((flags & (FPC_RESULT|FPC_SHOWN)) == FPC_RESULT) {
+ add_object_array(&(c->object), NULL, ¤t);
+ c->object.flags |= FPC_SHOWN;
+ }
+ if (!c->object.parsed)
+ parse_object(c->object.sha1);
+ if (!c->parents)
+ break;
+ c = c->parents->item;
+ }
+
+ /* Finally, show the series. */
+ show_fpc(¤t);
+ }
+
+ /* free them */
+ for (i = 0; i < result.nr; i++) {
+ c = (struct commit *) result.objects[i].item;
+ free(c->buffer);
+ free_commit_list(c->parents);
+ }
+ return 0;
+}
+
static int istitlechar(char c)
{
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
diff --git a/builtin.h b/builtin.h
index 43fed32..a94540d 100644
--- a/builtin.h
+++ b/builtin.h
@@ -38,6 +38,7 @@ extern int cmd_grep(int argc, const char **argv, const char *prefix);
extern int cmd_help(int argc, const char **argv, const char *prefix);
extern int cmd_init_db(int argc, const char **argv, const char *prefix);
extern int cmd_log(int argc, const char **argv, const char *prefix);
+extern int cmd_log_fpc(int argc, const char **argv, const char *prefix);
extern int cmd_ls_files(int argc, const char **argv, const char *prefix);
extern int cmd_ls_tree(int argc, const char **argv, const char *prefix);
extern int cmd_mailinfo(int argc, const char **argv, const char *prefix);
diff --git a/git.c b/git.c
index 1aa07a5..65d98bd 100644
--- a/git.c
+++ b/git.c
@@ -243,6 +243,7 @@ static void handle_internal_command(int argc, const char **argv, char **envp)
{ "help", cmd_help },
{ "init-db", cmd_init_db },
{ "log", cmd_log, RUN_SETUP | USE_PAGER },
+ { "log-fpc", cmd_log_fpc, RUN_SETUP | USE_PAGER },
{ "ls-files", cmd_ls_files, RUN_SETUP },
{ "ls-tree", cmd_ls_tree, RUN_SETUP },
{ "mailinfo", cmd_mailinfo },
--
1.4.4.1.ge3fb
^ permalink raw reply related [relevance 2%]
* Re: [RFC] Submodules in GIT
@ 2006-12-01 22:26 4% ` Linus Torvalds
2006-12-01 22:55 1% ` Josef Weidendorfer
1 sibling, 2 replies; 200+ results
From: Linus Torvalds @ 2006-12-01 22:26 UTC (permalink / raw)
To: Josef Weidendorfer; +Cc: sf, git, Martin Waitz
On Fri, 1 Dec 2006, Josef Weidendorfer wrote:
> >
> > Well, I would actually argue that you may often want to have a supermodule
> > and then at least have the _option_ to decide to not fetch all the
> > submodules.
>
> If you want to allow this, you have to be able to cut off fetching the
> objects of the supermodule at borders to given submodules, the ones you
> do not want to track. With "border" I mean the submodule commit in some
> tree of the supermodule.
>
> This looks a little bit like a shallow clone
No.
I would say that it looks more like a "partial checkout" than a shallow
clone.
A shallow clone limits the data in "time" - we have _some_ data, but we
don't have all of the history of that data.
In contrast, a submodule that we don't fetch is an all-or-nothing
situation: we simply don't have the data at all, and it's really a matter
of simply not recursing into that submodule at all - much more like not
checking out a particular part of the tree.
So if a shallow clone is a "limit in time", a lack of a module (or a lack
of a checkout for a subtree in general - you could certainly imagine doing
the same thing even _within_ a git repository, and indeed, we did discuss
exactly that at one point in time) is more of a "limit in space".
^ permalink raw reply [relevance 4%]
* Re: [RFC] Submodules in GIT
@ 2006-12-01 22:40 2% ` Martin Waitz
0 siblings, 0 replies; 200+ results
From: Martin Waitz @ 2006-12-01 22:40 UTC (permalink / raw)
To: Josef Weidendorfer; +Cc: Linus Torvalds, sf, git
[-- Attachment #1: Type: text/plain, Size: 1218 bytes --]
hoi :)
On Fri, Dec 01, 2006 at 11:26:22PM +0100, Josef Weidendorfer wrote:
> It's not about checking out part of the tree, it's about fetching only
> part of the objects: If you have a slow modem and want to clone a
> supermodule, you are not interested in fetching all the objects from
> some submodules.
So when you want to suppress one submodule, how is this not about only
checking out part of the tree?
Ok, you also want to avoid downloading the submodule, but you first have
to solve the partial checkout.
> BTW: In your submodule implementation, is the user allowed to change the
> relative path of the root of some submodule, e.g. with "git-mv" ?
In principle: yes.
However there are some links between both repositories that have to be
updated manually (for the shared object repository and for ignoring
submodule files in the supermodule).
But I expect that much of this configuration stuff will vanish when
submodules are better integrated in git.
Rename detection for submodules would be another interesting thing to
have. It should be much easier as for files because we can simply check
for common ancestors and do not have to guess based on the diff.
--
Martin Waitz
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply [relevance 2%]
* Re: [RFC] Submodules in GIT
2006-12-01 22:26 4% ` Linus Torvalds
@ 2006-12-01 22:55 1% ` Josef Weidendorfer
1 sibling, 0 replies; 200+ results
From: Josef Weidendorfer @ 2006-12-01 22:55 UTC (permalink / raw)
To: Linus Torvalds; +Cc: sf, git, Martin Waitz
On Friday 01 December 2006 23:26, Linus Torvalds wrote:
>
> On Fri, 1 Dec 2006, Josef Weidendorfer wrote:
> > >
> > > Well, I would actually argue that you may often want to have a supermodule
> > > and then at least have the _option_ to decide to not fetch all the
> > > submodules.
> >
> > If you want to allow this, you have to be able to cut off fetching the
> > objects of the supermodule at borders to given submodules, the ones you
> > do not want to track. With "border" I mean the submodule commit in some
> > tree of the supermodule.
> >
> > This looks a little bit like a shallow clone
>
> No.
>
> I would say that it looks more like a "partial checkout" than a shallow
> clone.
>
> A shallow clone limits the data in "time" - we have _some_ data, but we
> don't have all of the history of that data.
>
> In contrast, a submodule that we don't fetch is an all-or-nothing
> situation: we simply don't have the data at all, and it's really a matter
> of simply not recursing into that submodule at all - much more like not
> checking out a particular part of the tree.
OK.
I still think it should be about "limit in space" regarding the
objects in the local repository.
For a project containing "gcc" as submodule, and I am not
interested in this submodule, there should be a way to not need
to fetch all the objects from the gcc submodule at clone time.
What about my other argument for a submodule namespace:
You want to be able to move the relative root path of a submodule
inside of your supermodule, but yet want to have a unique name
for the submodule:
- to be able to just clone a submodule without having to know
the current position in HEAD
- more practically, e.g. to be able to name a submodule
independent from any current commit you are on in the supermodule,
e.g. to be able to store some meta information about a submodule:
- "Where is the official upstream of this submodule?"
- "Should git allow to commit rewind actions of this submodule
in the supermodule?" (which, AFAICS, exactly has the same
problems as publishing a rewound branch: you will get into
merge hell when you want to pull upstream changes into the
supermodule)
- "Should this submodule be checked out?"
and so on.
^ permalink raw reply [relevance 1%]
* Re: [RFC] Submodules in GIT
@ 2006-12-01 23:49 3% ` sf
2006-12-02 18:57 1% ` Torgil Svensson
0 siblings, 1 reply; 200+ results
From: sf @ 2006-12-01 23:49 UTC (permalink / raw)
To: Linus Torvalds; +Cc: sf, git, Martin Waitz
Linus Torvalds wrote:
>
> On Fri, 1 Dec 2006, sf wrote:
>> Linus Torvalds wrote:
>> ...
>>> In contrast, a submodule that we don't fetch is an all-or-nothing
>>> situation: we simply don't have the data at all, and it's really a matter
>>> of simply not recursing into that submodule at all - much more like not
>>> checking out a particular part of the tree.
>> If you do not want to fetch all of the supermodule then do not fetch the
>> supermodule.
>
> So why do you want to limit it? There's absolutely no cost to saying "I
> want to see all the common shared infrastructure, but I'm actually only
> interested in this one submodule that I work with".
If you need a common infrastructure to be able to work with the
submodule, then the submodule is not independent of of the supermodule.
I see a contradiction in your requirements.
> Also, anybody who works on just the build infrastructure simply may not
> care about all the submodules. The submodules may add up to hundreds of
> gigs of stuff. Not everybody wants them. But you may still want to get the
> common build infrastructure.
See above.
> In other words, your "all or nothing" approach is
> (a) not friendly
> and
> (b) has no real advantages anyway, since modules have to be independent
> enough that you _can_ split them off for other reasons anyway.
>
> So forcing that "you have to take everything" mentality onyl has
> negatives, and no positives. Why do it?
(There have been lots of use cases for shallow clones but for a long
time git did not support them).
If you can extend this partial fetch feature to the non-subproject case
I would agree with your reasoning. What makes the subprojects so special
in this regard. Do I have to turn a plain tree into a subproject to be
able to ignore it? Once you can restrict fetches to parts of the
contents you get the ability to restrict fetches to the "common
infrastructure" and selected submodules for free.
Regards
Stephan
^ permalink raw reply [relevance 3%]
* Re: [RFC] Submodules in GIT
2006-12-01 23:49 3% ` sf
@ 2006-12-02 18:57 1% ` Torgil Svensson
0 siblings, 1 reply; 200+ results
From: Torgil Svensson @ 2006-12-02 18:57 UTC (permalink / raw)
To: sf-gmane, Linus Torvalds, sf, git, Martin Waitz
> If you need a common infrastructure to be able to work with the
> submodule, then the submodule is not independent of of the supermodule.
> I see a contradiction in your requirements.
Here's an real-world example that doesn't contradict:
http://amarok.kde.org/wiki/Installation_HowTo#From_Anonymous_SVN
"svn co -N svn://anonsvn.kde.org/home/kde/trunk/extragear/multimedia
cd multimedia
svn co svn://anonsvn.kde.org/home/kde/branches/KDE/3.5/kde-common/admin
svn up amarok
To compile the sources (from the multimedia directory):"
and there's probably very few people that want to clone the entire KDE
multimedia sub&super-module in this case.
//Torgil
On 12/2/06, sf <sf-gmane@stephan-feder.de> wrote:
> Linus Torvalds wrote:
> >
> > On Fri, 1 Dec 2006, sf wrote:
> >> Linus Torvalds wrote:
> >> ...
> >>> In contrast, a submodule that we don't fetch is an all-or-nothing
> >>> situation: we simply don't have the data at all, and it's really a matter
> >>> of simply not recursing into that submodule at all - much more like not
> >>> checking out a particular part of the tree.
> >> If you do not want to fetch all of the supermodule then do not fetch the
> >> supermodule.
> >
> > So why do you want to limit it? There's absolutely no cost to saying "I
> > want to see all the common shared infrastructure, but I'm actually only
> > interested in this one submodule that I work with".
>
> If you need a common infrastructure to be able to work with the
> submodule, then the submodule is not independent of of the supermodule.
> I see a contradiction in your requirements.
>
> > Also, anybody who works on just the build infrastructure simply may not
> > care about all the submodules. The submodules may add up to hundreds of
> > gigs of stuff. Not everybody wants them. But you may still want to get the
> > common build infrastructure.
>
> See above.
>
> > In other words, your "all or nothing" approach is
> > (a) not friendly
> > and
> > (b) has no real advantages anyway, since modules have to be independent
> > enough that you _can_ split them off for other reasons anyway.
> >
> > So forcing that "you have to take everything" mentality onyl has
> > negatives, and no positives. Why do it?
>
> (There have been lots of use cases for shallow clones but for a long
> time git did not support them).
>
> If you can extend this partial fetch feature to the non-subproject case
> I would agree with your reasoning. What makes the subprojects so special
> in this regard. Do I have to turn a plain tree into a subproject to be
> able to ignore it? Once you can restrict fetches to parts of the
> contents you get the ability to restrict fetches to the "common
> infrastructure" and selected submodules for free.
>
> Regards
>
> Stephan
>
> -
> To unsubscribe from this list: send the line "unsubscribe git" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [relevance 1%]
* Re: [RFC] Submodules in GIT
@ 2006-12-03 17:54 3% ` Linus Torvalds
0 siblings, 0 replies; 200+ results
From: Linus Torvalds @ 2006-12-03 17:54 UTC (permalink / raw)
To: Torgil Svensson; +Cc: sf-gmane, sf, git, Martin Waitz
On Sun, 3 Dec 2006, Torgil Svensson wrote:
>
> On 12/2/06, Linus Torvalds <torvalds@osdl.org> wrote:
> >
> > In other words, I don't think people expect or want something hugely more
> > complicated than the CVS/modules kind of file.
>
> What about the case when you want _everything_, do you then have to
> know the names of all submodules, present and past?
Afaik, the way people do this historically is simply:
- often have an alias for "everything" (eg "all" or "src" or "world"),
and if you want everything, you basically ask for it by checking out
the "src" module.
Ie this is the "upstream" way to let downstream check out everything.
- if you're downstream, and you have a partial repo, and you realize that
you want everything else, you just look at gitweb (assuming it is
extended to show module information, of course ;) or the .gitmodules
(or whatever it would be called) file to get the other pieces manually.
But hey, I also think it would be fine to have "git clone --allmodules" or
something ("fetch" too). I think this whole question will depend more on
how people end up _using_ module support than on any technical issues per
se. Again, I suspect the people who now set up modules in CVS are likely
to have a better idea than I do about how they usually do it (and why).
> If you have an old irrelevant submodule in the history that happens to
> have the same name as one of them you are interested in, do you get
> this as well?
I dunno. Details, details. I'm also not sure this is hugely important.
It could be "solved" by simply having the requirement that all modules
need to be named differently (notice that "module name" is _not_ the same
thing as "the directory name where the module shows up". That's not the
case even in CVS modules, and with a "link" type in the git tree object,
the directory where a module shows up would basically be totally
independent of the "name" of the module).
> During a debugging session it might be convenient to do a "all but X"
> kind of fetch if you have a project dependent on several small modules
> and one of them is the big black sheep.
I suspect it's more common to name the modules you want to fetch
explicitly, rather than make it a "negative" choice, but that sounds
largely like just an interface issue.
^ permalink raw reply [relevance 3%]
* Re: [RFC] Submodules in GIT
@ 2006-12-05 11:09 5% ` Jakub Narebski
0 siblings, 0 replies; 200+ results
From: Jakub Narebski @ 2006-12-05 11:09 UTC (permalink / raw)
To: git
Andreas Ericsson wrote:
> Torgil Svensson wrote:
>> On 12/4/06, Linus Torvalds <torvalds@osdl.org> wrote:
>>>
>>> So yeah, it's a bit hacky, but for the reasons I've tried to outline, I
>>> actually think that users _want_ hacky. Exactly because "deep
>>> integration"
>>> ends up having so many _bad_ features, so it's better to have a thin and
>>> simple layer that you can actually see past if you want to.
>>
>> Thin and simple sounds very good. Let's try it with an example. Lets
>> say we have one apllication App1 and three librarys (Lib1, Lib2, Lib3)
>> with the following dependency-graph:
>>
>> App1
>> / \
>> / \
>> Lib1 Lib2
>> \ /
>> \ /
>> Lib3 (don't really needed for this example but looks nice)
>>
>> All components can be used individually and have their own upstream,
>> maintainer etc.
>>
>> To compile App1 however, I need some files from both Lib1 and Lib2
>> specifying it's API. To satisfy these dependencies, It sounds
>> reasonable to link Lib2 and Lib3 submodules from App1. In your
>> concept, can I construct a modules file to fetch the API files and
>> their history without checking out the whole Lib1 and Lib2 source?
>
> I think not. Then it wouldn't be a submodule anymore, but just some
> random sources from an upstream project. Not that it's an uncommon
> workflow or anything, but it's sort of akin to just importing the SHA1
> implementation (a few source-files with no real interest in the history
> of those source-files) from openssl into a different project rather than
> actually using the entire openssl lib (which would be nice to have as a
> submodule).
Note that this is what partial checkouts (another great idea nobody
implemented yet[*1*]; you can do partial checkout but there is no UI for
this, and working with partial checkouts is bit hard) is about, although it
would buy you only working area space, and not repository (object database
storage) space.
For now, you can imitate this by having in in Lib1 and Lib2 the 'includes'
branch which would contain only the API (and which you would have to keep
up to date with 'master', but it should be fairly easy: just merge changes
into 'includes', perhaps with help of git-rerere, or [nonexisting]
git-rerere2).
[*1*] Although with our track[*2*] I guess it is reasonable to think it
would get implemented soon.
[*2*] Out of four "great ideas": shallow clone / sparse clone, submodules
support, lazy clone / remote alternates, two are in example-implementation
(submodules support) and beta work (shallow clone is in 'next').
--
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git
^ permalink raw reply [relevance 5%]
* Re: [RFC] Two conceptually distinct commit commands
@ 2006-12-06 23:29 1% ` Carl Worth
0 siblings, 0 replies; 200+ results
From: Carl Worth @ 2006-12-06 23:29 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, Johannes Schindelin
[-- Attachment #1: Type: text/plain, Size: 12087 bytes --]
On Wed, 06 Dec 2006 10:31:21 -0800, Junio C Hamano wrote:
> I am not sure what needs to be commented on at this point, since
> it is not yet clear to me where you want your proposal to lead
> us.
Thanks for the comments you made here---that's the kind of thing I was
looking for.
As for where I'm trying to lead us, what I really want to do is to
help improve the learnability of git. A big part of that is about
improving the set of "use-oriented" documentation, (which describes
how to achieve tasks, as opposed to what might be termed "technically
oriented" documentation which describes how individual tools work). I
think too much of the existing documentation falls into the second
class.
A parallel thread is already talking about some of the important
organizational aspects of use-oriented documentation. And I agree with
that thread is that the short "attention span" is a primary
consideration for this kind of documentation. The user has a task to
be accomplish, and any text or concepts that aren't contributing to
the solution of that task should be eliminated.
Note that when I talk about eliminating unnecessary concepts, I do not
mean lying to the user about the underlying model or any concepts. We
can't have a sugar-coated tutorial that says one thing, and then
expect users to "unlearn" that if they go deeper into the reference
manual. That's a recipe for disaster.
Also, when I say "use-oriented" I'm not suggesting that the
documentation be shallow. It can go as deep as any workflow we care to
document and introduce whatever concepts of git are necessary to
support that workflow. (There is, though a level at which "technically
oriented" documentation is all that's needed, or even desired, and
that's when the documentation is targeting authors of interfaces that
build on top of git---not users trying to use git to get work done at
the command line).
OK, so if my concern is all about documentation, then what am I doing
proposing new commands or new ways of thinking about existing commands
rather than just sending documentation patches? The problem is that
the current semantics of the following variations of "git commit":
git commit
git commit -a
git commit paths...
defeat the goal of writing good, clean use-oriented documentation. So
there's some adjustment that should be made first. And I don't even
care what the adjustment is, (for example, it doesn't have to be
"commit -a by default"), but please recognize the problem and help me
come up with an acceptable way to fix it.
To demonstrate, let's take the simplest of use cases and try to
document it in as clear a way as possible. Let's imagine we're in a
tutorial where we've just guided the user to making modifications to
several existing, tracked files, (starting from an initial clone, not
an init-db), and the next task to teach the user commit for the first
time. We would like to document both "commit a single modified file"
and "commit all modified files". Here are two approaches that I can
come up with:
1. Any commit involves first "add"ing together new content, and then
committing the result. For example to commit a single file:
git add file # add new content from file
git commit # commit the result
As a shortcut, "commit -a", (or --all) can be used to automatically
"add" the content of all tracked files before the commit. So the
common case of committing all tracked files is as easy as:
git commit -a # commit content of all tracked files
2. The new content of modified files can be committed by naming the
files on the "git commit" command line. For example:
git commit file # commit new content of file
As a shortcut, "commit -a", (or --all) can be used to commit the
content of all tracked files:
git commit -a # commit content of all tracked files
Neither of the above is totally satisfactory.
In (1) the user is not presented with a framework that will make sense
of "git commit files...". The expansion of "-a" as "--all" could
easily give the user the impression that "git commit files..." is a
shortcut for "git add files...; git commit", but that's wrong and
could lead to unexpected results and confusion.
In (2) the user is not presented with a framework that will make sense
of "git commit" with no arguments. The user is left to wonder about
why the --all is needed and what it means exactly, (particularly since
"git commit" also commits the content of all tracked files.
Various fixes have been proposed for these potential confusions. For
example, making "git commit files..." default to the behavior of
--include instead of --only would eliminate the confusion I described
for (1). And making -a the default for "git commit" would eliminate
the confusion I described for (2).
However, actually implementing either of those fixes would then break
the initial "commit one file" example from the other approach. Because
of that, the conversation has often fallen into debate over whether
(1) or (2) is the "one true way" to describe git, and which one leads
the user to have an incorrect mental model.
But I think that debate is misguided since both descriptions are
worthwhile and valid. (1) is based around an explanation of what "git
commit" does, and (2) is based around an explanation of what "git
commit files..." does. And both of these commands are very useful
exactly how they are.
It's almost coincidental that "commit -a" fits in logically with
either description.
So what I was trying to get across in this latest thread is that git's
command-line interface already has two slightly different models for
what's going on in a commit. You don't agree with me on that point
yet, (more on that below in my reply).
I really don't care what the final fix is, but I would love to see
documentation with no more complexity than the above that accurately
captures the useful functionality.
And I don't actually have a concrete proposal for a fix yet---I was
just offering the commit-index-content and commit-working-tree-content
ideas as ways to think about the issue. Maybe the two documentation
blurbs above capture it in a better way.
Do you feel like you have a better understanding of what I'm trying to
do now?
> I do not agree with your "three commands" or "two semantics"
> characterization of the current way "git commit" works. "git
> commit" without any optional argument already acts as if a
> sensible default arguments are given, that is "no funny business
> with additional paths, commit just what the user has staged
> already."
I agree that "git commit" does nothing funny by default. What I was
pointing out is that "git commit" and "git commit paths..." do not
have the same semantics. There's really nothing to debate about
there. There is no argument you can substitute for <paths...> to give
you identical behavior as "git commit". That's a fact.
> "git commit" is primarily about committing what has been staged
> in the index, and "--all" is just a type-saver short-hand (just
> like "--include" is) to perform update-index the last minute and
> nothing more. In other words, "--all" is a variant of the
> pathname-less form "git commit". It is not a variant of "git
> commit --only paths..." form, as you characterized.
I hope the documentation blurbs (1) and (2) above show how "commit -a"
can be seen as a variant of either "commit" or "commit files...",
(which themselves are both useful semantics, but demonstrably
distinct).
> The pathname form (the "--only" variant) on the surface seem to
> work differently, but when you think about it, it is not all
> that different from the normal commit. We explain that it
> ignores index, but in the bigger picture, it does not really.
No, it really is different.
> the first commit does "jump" the changes already made to the
> index, but after it makes the commit, the index has the same
> contents as if you did "git update-index a b" where you ran that
> "git commit". In other words, it is just a handy short-hand to
> pretend as if you did the above sequence in this order instead:
How could you document "git commit files..." as a shorthand? A
shorthand for what exactly? A shorthand for pretending you didn't just
type the commands you did type that got the index into its current
state, but had instead typed different commands before the commit and
other commands afterwards?
That's crazy. That's not a shorthand. That's just plain different
semantics. The current "git commit files..." command never does commit
the contents of "the" index as a concept presented by "git
commit". (This is independent of the fact that the implementation of
"git commit files..." certainly does use an index file somewhere and
uses it to create a commit object in the same way that "git commit"
uses "the" index).
> So I actually think it is a mistake to stress the fact that "git
> commit --only paths..." seems to act differently from the normal
> "git commit" too much.
I think that would be lying to the users and setting them up to get
confused later. I discussed this above as the confusion that can
result with the explanation of (1). If you teach "git commit" as
commiting "the" index, and de-emphasize that "git commit files..."
is semantically distinct, then how is a user ever supposed to learn
what it is that "git commit files..." is actually doing?
> In short, while I understand that your "proposal" shows your own
> way to summarize the semantics of "git commit", I am not seeing
> what it buys us, and I do not see the need to come up with a
> pair of new two commands for making commits (if that is what the
> proposal is about, that is, but it is not clear to me if that is
> what you are driving at). I think it would only confuse users.
Forgive me again for being obtuse. I don't think we should necessarily
add two new commands. I was trying to illustrate a problem in the
existing command set, and propose a new way of thinking about the
tasks that the current commands help a user to perform, (committing
content from the working tree or committing content from the index). I
don't actually have a concrete proposal for how to take that way of
thinking and map it to a command set, (and one that would disrupt
current git users as little as possible). I'd love to have some help
with that part.
> Is it just me who finds the above a very much made-up example?
Fine. We can ignore that example.
> In any case, I should clarify my aversion to partial commits a
> bit. What is more important is to notice that, while you cannot
> compile-and-run test what is in the index in isolation (without
> a fuse that exports the index contents as a virtual filesystem
> -- anybody interested?), you _can_ preview and verify the text
> that is going to be committed by comparing the index and the
> HEAD. And for that, your "staging" action (i.e. Nico's "git
> add") needs to be a separate step from your "committing" action.
Yes, I often use the index as a place to preview things. And it is
true that I find myself using update-index when I could have used
"commit paths..." precisely because I can preview it once more. But I
do use the "commit paths..." form at times as well. If I have just
reviewed things in "git diff" and there are _really_ obviously
separable pieces I will commit them alone with staging into the index
and reviewing again.
It's probably the case that I skip the explicit staging and extra
preview when I can use a single pathname as the argument to "git
commit".
> In other words, I would even love Johannes's "per hunk commit"
> idea, at least if it had an option to preview the whole thing
> just one more time before committing, and I would love it better
> if it had an option for not committing but just updating.
Yes! I've wanted tools to help with per-hunk separation before, but
since I'm so likely to make mistakes while doing that I would only
want that to go into the index so that I could review it before
committing. I guess I might need a per-hunk way to fix up my mistakes
too if I put a hunk into the index that I didn't want to be there.
-Carl
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply [relevance 1%]
* globs in partial checkout?
@ 2006-12-10 20:00 4% ` Michael S. Tsirkin
2006-12-10 20:13 3% ` Linus Torvalds
0 siblings, 1 reply; 200+ results
From: Michael S. Tsirkin @ 2006-12-10 20:00 UTC (permalink / raw)
To: Git Mailing List, Junio C Hamano
I'm trying to checkout some files after doing "clone -n".
Should using globs there work? It doesn't:
st@mst-lt:~/scm/wireless-dev$ git checkout master 'include/net/ieee80211*.h'
error: pathspec 'include/net/ieee80211*.h' did not match any file(s) known to
git.
Did you forget to 'git add'?
mst@mst-lt:~/scm/wireless-dev$ git ls-tree master -- include/net/ | grep iee
100644 blob b174ebb277a96668f058e469b0753503c34f164b include/net/ieee80211.h
100644 blob eb476414fd726701d032e9e517751b9d3f7e38df include/net/ieee80211_crypt.h
100644 blob 429b73892a5fc62f91e4a4b05da40859604fa791 include/net/ieee80211_radiotap.h
100644 blob 617b672b1132e7fa3ff5f9c940b1692520dc8483 include/net/ieee80211softmac.h
100644 blob 4ee3ad57283fa3370bd2d1f71cd6ae559b556dbc include/net/ieee80211softmac_wx.h
mst@mst-lt:~/scm/wireless-dev$ git checkout master include/net/ieee80211.h
include/net/ieee80211_crypt.h include/net/ieee80211_radiotap.h
include/net/ieee80211softmac.h include/net/ieee80211softmac_wx.h
--
^ permalink raw reply [relevance 4%]
* Re: globs in partial checkout?
2006-12-10 20:00 4% ` globs in partial checkout? Michael S. Tsirkin
@ 2006-12-10 20:13 3% ` Linus Torvalds
0 siblings, 0 replies; 200+ results
From: Linus Torvalds @ 2006-12-10 20:13 UTC (permalink / raw)
To: Michael S. Tsirkin; +Cc: Git Mailing List, Junio C Hamano
On Sun, 10 Dec 2006, Michael S. Tsirkin wrote:
>
> I'm trying to checkout some files after doing "clone -n".
> Should using globs there work? It doesn't:
Not historically at all. "git checkout" needed exact filenames in older
versions.
However, since about 1.4.4.1 or so, it now does the same filename
expansion as "git add" etc does, which means that you can give it a
directory name and it will check out everything under that directory, or
you can give it a pattern, and it should glob it. But it sounds like you
may have a slightly older version of git (the pathname matching really is
fairly recent).
^ permalink raw reply [relevance 3%]
* Re: [RFC] Submodules in GIT
@ 2006-12-16 9:57 2% ` Jakub Narebski
2006-12-16 15:05 2% ` Torgil Svensson
0 siblings, 1 reply; 200+ results
From: Jakub Narebski @ 2006-12-16 9:57 UTC (permalink / raw)
To: git
<opublikowany i wysłany>
Torgil Svensson wrote:
> On 12/16/06, Jakub Narebski <jnareb@gmail.com> wrote:
>>> Now it doesn't looks like trees/blobs anymore so maybe a link object
>>> is handy:
>>> README
>>> 100644 blob <sha1 of blob> REPORTING-BUGS
>>> 100644 link <sha1 of link> AUTHORS
>>> 040000 tree <sha1 of tree> arch
>>> 040000 tree <sha1 of tree> block
>>> 040000 link <sha1 of link> misc
This would be (using the submodule original proposal)
140000 link <sha1 of link> misc
>>> link-object:
>>> <sha1 of commit>
>>> <sha1 of tree/blob>
>>
>> What do you need <sha1 of tree/blob> for in link-object? Wouldn't you
>> use usually the sha1 of top tree of a commit, which is uniquely defined
>> by commit object, so you need only <sha1 of commit>?
>>
>
> 1. "Sparse" repository's - In my example, I want to cherry-pick
> header-files or binary-files from different projects without fetching
> all, potentially huge, submodules in their entirety. Imaging having X,
> kernel, gcc, gtk and libc6 as sub-projects and you really only care
> about some header files.
>
> 2. Super-module directory-hierarchy independent from submodules.
> Super-project want to have the header-files and binaries it's own way.
> This also gives version controlled file-collections, the "release
> case" in my example - collecting different binaries and header-files
> from different submodules together in a new directory-structure, add
> some documentation and configuration files and get the whole thing
> under strong version-control down to the beginning of time for each
> little component.
All fine, but this does not and I think cannot protect us from the
fact that we can have <sha1 of tree/blob> which doesn't match
<sha1 of commit>.
I think it would be better to have sparse/partial checkout first.
But that is just my idea. Because with <sha1 of tree/blob> which
is not sha1 of commit tree you might loose (I think) the ability
to merge, for example your changes to submodule with upstream.
> 3. Super-module development independent of submodules - If we have the
> tree/blob-object with all it contents in the database many
> git-operations can act as the link (commit) wasn't there since we have
> access to all relevant data to work with. This makes it easy to clone
> the super-project and work on it seamlessly without having to care
> about submodules or mapping up submodule repository's (unless you want
> to modify the links or the data underneath it of course).
This is I think irrelevant to the fact if we have only <sha1 of commit>,
or link object and also <sha1 of tree/blob>
--
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git
^ permalink raw reply [relevance 2%]
* Re: [RFC] Submodules in GIT
2006-12-16 9:57 2% ` Jakub Narebski
@ 2006-12-16 15:05 2% ` Torgil Svensson
0 siblings, 0 replies; 200+ results
From: Torgil Svensson @ 2006-12-16 15:05 UTC (permalink / raw)
To: Jakub Narebski; +Cc: Josef Weidendorfer, R. Steve McKown, git, Linus Torvalds
On 12/16/06, Jakub Narebski <jnareb@gmail.com> wrote:
> All fine, but this does not and I think cannot protect us from the
> fact that we can have <sha1 of tree/blob> which doesn't match
> <sha1 of commit>.
True, that will be a real problem. Unless we have a bug in git, do you
see a scenario in which this is likely to happen?
> I think it would be better to have sparse/partial checkout first.
> But that is just my idea. Because with <sha1 of tree/blob> which
> is not sha1 of commit tree you might loose (I think) the ability
> to merge, for example your changes to submodule with upstream.
That's correct. I also want a sparse/partial checkout but I don't want
the full submodule path. I'm also perfectly fine (for my current
use-cases) with not being able to merge upstream unless we're tracking
the commit tree (here, we might not want to specify the tree SHA1).
I'm not trying to impose a technically fragile solution here [I don't
believe it is, but I'm not the most competent to say that either], I'm
trying to find solutions for my use cases and I had problems adapting
them to the current suggestion.
> > 3. Super-module development independent of submodules - If we have the
> > tree/blob-object with all it contents in the database many
> > git-operations can act as the link (commit) wasn't there since we have
> > access to all relevant data to work with. This makes it easy to clone
> > the super-project and work on it seamlessly without having to care
> > about submodules or mapping up submodule repository's (unless you want
> > to modify the links or the data underneath it of course).
>
> This is I think irrelevant to the fact if we have only <sha1 of commit>,
> or link object and also <sha1 of tree/blob>
^ permalink raw reply [relevance 2%]
* Re: git-fetch fails with error code 128
@ 2006-12-16 22:12 5% ` Andy Parkins
0 siblings, 0 replies; 200+ results
From: Andy Parkins @ 2006-12-16 22:12 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Nicolas Pitre
On Friday 2006, December 15 21:55, Junio C Hamano wrote:
> Thanks --- very much appreciated. When it comes to
> inter-repository object transfer, we take compatibility very
> seriously.
Okay. Before I started bisecting I thought I'd do some other experiments.
Having tested fetch from remote and a fetch from local and finding the same
results, I've done all the tests locally.
So; here goes. I've got these directories:
linux-partial/ (this is every patch from v1.0.0 to v2.1.63)
linux-full/ (this is every patch from v1.0.0 to v2.5.75)
linux-partial/ is the one I reported the original error on, later I confirmed
that the same error happened with a local fetch from linux-full. I cloned
both of these.
linux-partial-clone/ (made with git clone linux-partial linux-partial-clone)
linux-full-clone/ (made with git clone linux-full linux-full-clone)
Tests:
- A fetch from linux-full to linux-partial, this one failed with error 128
- A fetch from linux-full-clone to linux-partial, this one failed with
error 128
- A fetch from linux-full to linux-partial-clone, this one succeeded
- A fetch from linux-full-clone to linux-partial-clone, this one succeeded
(unsurprisingly)
Next I ran git-prune in linux-partial. The fetch then succeeded. Bizarre.
So, the strange result is that it is a difference in the destination directory
that is triggering the error, and whatever that fault is is fixed by
git-cloning that destination repository, or git-pruning the destination.
Unfortunately I've now lost my test case, because the prune fixed it. Bah.
Oh well, this fault can be marked "on hold until I get it to fail again".
Andy
--
Dr Andrew Parkins, M Eng (Hons), AMIEE
^ permalink raw reply [relevance 5%]
* Re: Subprojects tasks
@ 2006-12-17 13:01 3% ` Jakub Narebski
2006-12-17 13:48 0% ` Martin Waitz
0 siblings, 1 reply; 200+ results
From: Jakub Narebski @ 2006-12-17 13:01 UTC (permalink / raw)
To: Martin Waitz; +Cc: Josef Weidendorfer, git, Junio C Hamano
Martin Waitz wrote:
> On Sun, Dec 17, 2006 at 01:01:09AM +0100, Josef Weidendorfer wrote:
>> IMHO it simply is added flexibility to allow a checkout to be separate from
>> the .git/ directory, same as explicitly setting $GIT_DIR would do.
>> So this .gitlink file is on the one hand one kind of convenience for users
>> which want to keep their repository separate, yet do not want to specify
>> $GIT_DIR all the time in front of git commands.
>> The .gitlink file simply makes the linkage to the separate repository
>> persistent.
>
> I can see the reason for wanting to use another object database,
> but HEAD and index should always be stored together with the
> checked out directory. So perhaps we just need some smart way to
> search for the object database, but keep the .git directory.
Well, in the .gitlink proposal you could specify GIT_DIR for checkout,
or separately: GIT_OBJECT_DIRECTORY, GIT_INDEX_FILE, GIT_REFS_DIRECTORY
(does not exist yet), GIT_HEAD_FILE (does not exist yet, and I suppose
it wouldn't be easy to implement it). By the way, that's why I'm for
.gitlink name for the file, not .git -- this way .gitlink can "shadow"
what's in .git, for example specifying in a smart way where to search
(where to find) object database, but HEAD and index would be stored
together with the checked out directory in .git
By the way, I'm rather partial to supermodule following HEAD in submodule,
not specified branch. First, I think it is easier from implementation
point of view: you don't have to remember which branch supermodule should
take submodule commits from; and this cannot be fixed branch name like
'master'. For example 'maint' branch of supermodule could track 'maint'
branch of submodule, 'master' branch of supermodule track 'master'
branch of submodule, 'next' branch of supermodule tranck 'master' (!)
branch of submodule, 'pu' branch of supermodule track 'next' (!) branch
of submodule.
Second, if you want to do some independent work on the module not related
to work on submodule you should really clone (clone -l -s) submodule
and work in separate checkout; the complaint that with tracking HEAD
you can check-in wrong version of submodule to supermodule commit
doesn't hold, because you still would have problem that _tree_
of supermodule would have wrong version of submodule. And moving to
using single defined branch of submodule brings multitude of other
problems: for example you might usually track 'master' version of
submodule, but for a short time need to track 'next' branch because
it has functionality you need; and another time you need to move
to 'maint' branch or even your own branch because 'master' version
breaks something in supermodule.
Hmmm... I wonder how planned allowing to checking out tags, non-head
branches (e.g. tracking/remote branches) and arbitrary commits but
forbidding committing when HEAD is not a refs/heads/ branch would
affect submodules / subprojects...
--
Jakub Narebski
^ permalink raw reply [relevance 3%]
* Re: Subprojects tasks
2006-12-17 13:01 3% ` Jakub Narebski
@ 2006-12-17 13:48 0% ` Martin Waitz
0 siblings, 0 replies; 200+ results
From: Martin Waitz @ 2006-12-17 13:48 UTC (permalink / raw)
To: Jakub Narebski; +Cc: Josef Weidendorfer, git, Junio C Hamano
[-- Attachment #1: Type: text/plain, Size: 6154 bytes --]
hoi :)
On Sun, Dec 17, 2006 at 02:01:09PM +0100, Jakub Narebski wrote:
> Well, in the .gitlink proposal you could specify GIT_DIR for checkout,
> or separately: GIT_OBJECT_DIRECTORY, GIT_INDEX_FILE, GIT_REFS_DIRECTORY
> (does not exist yet), GIT_HEAD_FILE (does not exist yet, and I suppose
> it wouldn't be easy to implement it). By the way, that's why I'm for
> .gitlink name for the file, not .git -- this way .gitlink can "shadow"
> what's in .git, for example specifying in a smart way where to search
> (where to find) object database, but HEAD and index would be stored
> together with the checked out directory in .git
What about .git/link or something?
(Obviously without the capability to change GIT_DIR)
> By the way, I'm rather partial to supermodule following HEAD in submodule,
> not specified branch. First, I think it is easier from implementation
> point of view: you don't have to remember which branch supermodule should
> take submodule commits from; and this cannot be fixed branch name like
> 'master'. For example 'maint' branch of supermodule could track 'maint'
> branch of submodule, 'master' branch of supermodule track 'master'
> branch of submodule, 'next' branch of supermodule tranck 'master' (!)
> branch of submodule, 'pu' branch of supermodule track 'next' (!) branch
> of submodule.
The version tracked by the supermodule is completely independent from
any branches you define in your submodule.
It is of course possible to use different versions of your submodule in
different branches of your supermodule. But the supermodule does not
know the name of these branches.
In the setup you described a git-checkout in the supermodule would have
to switch to a different branch in the submodule, depending on the
branchname which would have to be stored in the supermodule.
This a lot more complex.
Your scenario can also be solved in this way:
cd supermodule
(cd sub && git-reset --hard origin/master)
git add sub && git commit -m "track master of sub"
git checkout next
(cd sub && git-reset --hard origin/master)
git add sub && git commit -m "track master of sub"
git checkout pu
(cd sub && git-reset --hard origin/next)
git add sub && git commit -m "track next of sub"
git checkout maint
(cd sub && git-reset --hard origin/maint)
git add sub && git commit -m "track maint of sub"
You only store a link to the commit of the current submodule version,
just like a normal ref. The reference stored in the supermodule really
is equivalent to a normal ref, just that it is stored and updated
slightly different to a normal one.
So whenever you checkout a different version of the supermodule, the
submodule ref automatically gets the correct version. In the example
above, when you checkout supermodules pu, your submodules branch will be
reset to its origin/next (to be more precise: to the commit which was at
the tip of origin/next at the time it was stored in the supermodule).
The fact that the reference to the current submodule commit does not
only exist in the supermodule tree but also as a physical ref in the
submodule is very similiar to normal files: you have one version stored
in the object database, one in the index and one as a real file in the
working directory (and this working file is the equivalent of the
submodule ref which is stored in submodule/.git/refs/whatever)
The reference in the submodule is just a way to be able to work on
the submodule. Because well, refs are the kind of thing that is changed
by a commit. And these submodule commits are exactly the kind of work
you want to store in the supermodule. So the equivalent to a working
file is not the HEAD of the submodule, but the ref which gets all
changes which are intended for the supermodule.
The fact that the submodule repository still supports other branches has
nothing to do with submodule support. These branches are totally
independent from the supermodule.
> Second, if you want to do some independent work on the module not related
> to work on submodule you should really clone (clone -l -s) submodule
> and work in separate checkout;
Yes.
But I really like the possibility to switch one module to a branch which
is not tracked by the parent, because it perhaps contains some debugging
code which is needed to debug some other submodule. You can't move it
out because you need the common build infrastructure but you don't want
to branch the entire toplevel project because you don't want your
debugging changes to ever become visible at that level.
So by switching to a different branch you can effectivly say: this is
temporary, not meant for the superproject.
If you change your mind later you can always merge the submodule branch
back to master.
> the complaint that with tracking HEAD you can check-in wrong version
> of submodule to supermodule commit doesn't hold, because you still
> would have problem that _tree_ of supermodule would have wrong version
> of submodule.
Sorry, I don't understand you here.
> And moving to using single defined branch of submodule brings
> multitude of other problems: for example you might usually track
> 'master' version of submodule, but for a short time need to track
> 'next' branch because it has functionality you need; and another time
> you need to move to 'maint' branch or even your own branch because
> 'master' version breaks something in supermodule.
That is no problem.
The supermodule can track whatever _version_ it wants. You can set
it to any version which is available in the repository, including all
those well known external branches.
But the supermodule itself does not know (and should not know) about
"maint" / "next" / whatever branch names in the submodule.
> Hmmm... I wonder how planned allowing to checking out tags, non-head
> branches (e.g. tracking/remote branches) and arbitrary commits but
> forbidding committing when HEAD is not a refs/heads/ branch would
> affect submodules / subprojects...
It only affects submodules if you really track HEAD directly.
--
Martin Waitz
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply [relevance 0%]
* Draft v1.5.0 release notes
@ 2007-01-02 0:08 3% Junio C Hamano
0 siblings, 0 replies; 200+ results
From: Junio C Hamano @ 2007-01-02 0:08 UTC (permalink / raw)
To: git
The latest draft is kept as 'todo:v1.5.0.txt'. Since I've
merged the shallow clone changes, I've added a few sentences for
the series as well.
--
GIT v1.5.0 Release Notes
========================
Old news
--------
This section is for people who are upgrading from ancient
versions of git. Although all of the changes in this section
happened before the current v1.4.4 release, they are summarized
here in the v1.5.0 release notes for people who skipped earlier
versions.
In general, you should not have to worry about incompatibility,
and there is no need to perform "repository conversion" if you
are updating to v1.5.0. However, some of the changes are
one-way street upgrades; once you use them your repository
can no longer be used with ancient git.
- There is a configuration variable core.legacyheaders that
changes the format of loose objects so that they are more
efficient to pack and to send out of the repository over git
native protocol, since v1.4.2. However, this format cannot
be read by git older than that version; people fetching from
your repository using older clients over dumb transports
(e.g. http) using older versions of git will also be
affected. This is not enabled by default.
- Since v1.4.3, configuration repack.usedeltabaseoffset allows
packfile to be created in more space efficient format, which
cannot be read by git older than that version. This is not
enabled by default.
- 'git pack-refs' appeared in v1.4.4; this command allows tags
to be accessed much more efficiently than the traditional
'one-file-per-tag' format. Older git-native clients can
still fetch from a repository that packed and pruned refs
(the server side needs to run the up-to-date version of git),
but older dumb transports cannot. Packing of refs is done by
an explicit user action, either by use of "git pack-refs
--prune" command or by use of "git gc" command.
- 'git -p' to paginate anything -- many commands do pagination
by default on a tty. Introduced between v1.4.1 and v1.4.2;
this may surprise old timers.
- 'git archive' superseded 'git tar' in v1.4.3;
- 'git cvsserver' was new invention in v1.3.0;
- 'git repo-config', 'git grep', 'git rebase' and 'gitk' were
seriously enhanced during v1.4.0 timeperiod.
- 'gitweb' became part of git.git during v1.4.0 timeperiod and
seriously modified since then.
- reflog is an v1.4.0 invention. This alows you to name a
revision that a branch used to be at (e.g. "git diff
master@{yesterday} master" allows you to see changes since
yesterday's tip of the branch).
Updates in v1.5.0 since v1.4.4 series
-------------------------------------
* Index manipulation
- git-add is to add contents to the index (aka "staging area"
for the next commit), whether the file the contents happen to
be is an existing one or a newly created one.
- git-add without any argument does not add everything
anymore. Use 'git-add .' instead. Also you can add
otherwise ignored files with an -f option.
- git-add tries to be more friendly to users by offering an
interactive mode.
- git-commit <path> used to refuse to commit if <path> was
different between HEAD and the index (i.e. update-index was
used on it earlier). This check was removed.
- git-rm is much saner and safer. It is used to remove paths
from both the index file and the working tree, and makes sure
you are not losing any local modification before doing so.
- git-reset <tree> <paths>... can be used to revert index
entries for selected paths.
- git-update-index is much less visible.
* Repository layout and objects transfer
- The data for origin repository is stored in the configuration
file $GIT_DIR/config, not in $GIT_DIR/remotes/, for newly
created clones. The latter is still supported and there is
no need to convert your existing repository if you are
already comfortable with your workflow with the layout.
- git-clone always uses what is known as "separate remote"
layout for a newly created repository with a working tree;
i.e. tracking branches in $GIT_DIR/refs/remotes/origin/ are
used to track branches from the origin. New branches that
appear on the origin side after a clone is made are also
tracked automatically.
- git-branch and git-show-branch know remote tracking branches.
- git-push can now be used to delete a remote branch or a tag.
This requires the updated git on the remote side.
- git-push more agressively keeps the transferred objects
packed. Earlier we recommended to monitor amount of loose
objects and repack regularly, but you should repack when you
accumulated too many small packs this way as well. Updated
git-count-objects helps you with this.
* Reflog
- Reflog records the history of where the tip of each branch
was at each moment. This facility is enabled by default for
repositories with working trees, and can be accessed with the
"branch@{time}" and "branch@{Nth}" notation.
- "git show-branch" learned showing the reflog data with the
new --reflog option.
- The commits referred to by reflog entries are now protected
against pruning. The new command "git reflog expire" can be
used to truncate older reflog entries and entries that refer
to commits that have been pruned away previously with older
versions of git.
Existing repositories that have been using reflog may get
complaints from fsck-objects; please run "git reflog expire
--all" first to remove reflog entries that refer to commits
that are no longer in the repository before attempting to
repack it.
- git-branch knows how to rename branches and moves existing
reflog data from the old branch to the new one.
* Packed refs
- Repositories with hundreds of tags have been paying large
overhead, both in storage and in runtime. A new command,
git-pack-refs, can be used to "pack" them in more efficient
representation.
- Clones and fetches over dumb transports are now aware of
packed refs and can download from repositories that use
them.
* Configuration
- configuration related to colorize setting are consolidated
under color.* namespace (older diff.color.*, status.color.*
are still supported).
* Less external dependency
- We no longer require the "merge" program from the RCS suite.
All 3-way file-level merges are now done internally.
- The original implementation of git-merge-recursive which was
in Python has been removed; we have C implementation of it
now.
- git-shortlog is no longer a Perl script. It no longer
requires output piped from git-log; it can accept revision
parameters directly on the command line.
* I18n
- We have always encouraged the commit message to be encoded in
UTF-8, but the users are allowed to use legacy encoding as
appropriate for their projects. This will continue to be the
case. However, a non UTF-8 commit encoding _must_ be
explicitly set with i18n.commitencoding in the repository
where a commit is made; otherwise git-commit-tree will
complain if the log message does not look like a valid UTF-8
string.
- The value of i18n.commitencoding in the originating
repository is recorded in the commit object on the "encoding"
header, if it is not UTF-8. git-log and friends notice this,
and reencodes the message to the log output encoding when
displaying, if they are different. The log output encoding
is determined by "git log --encoding=<encoding>",
i18n.logoutputencoding configuration, or i18n.commitencoding
configuration, in the decreasing order of preference, and
defaults to UTF-8.
* Foreign SCM interfaces
- git-svn now requires the Perl SVN:: libraries, the
command-line backend was too slow and limited.
- the 'commit' command has been renamed to 'set-tree', and
'dcommit' is the recommended replacement for day-to-day
work.
* User support
- Quite a lot of documentation updates.
- Bash completion scripts have been updated heavily.
- Better error messages for often used Porcelainish commands.
* Shallow clones
- There is a partial support for 'shallow' repositories that
keeps only recent history now. A 'shallow clone' is created
by specifying how deep that truncated history should be.
Currently a shallow repository has number of limitations:
- Cloning and fetching _from_ a shallow clone are not
supported (nor tested -- so they might work by accident but
they are not expected to).
- Pushing from nor into a shallow clone are not expected to
work.
- Merging inside a shallow repository would work as long as a
merge base is found in the recent history, but otherwise it
will be like merging unrelated histories and may result in
huge conflicts.
but this would be more than adequate for people who want to
look at near the tip of a big project with a deep history and
send patches in e-mail format.
^ permalink raw reply [relevance 3%]
* Re: An early draft of v1.5.0 release notes (3rd ed)
@ 2007-01-10 7:58 6% ` Junio C Hamano
0 siblings, 0 replies; 200+ results
From: Junio C Hamano @ 2007-01-10 7:58 UTC (permalink / raw)
To: git
Instead of sending the full text, I'll send out the diff against
the one I sent out on the 27th last month.
Highlights:
* Introductory notes have been reworded heavily;
* I intend to merge bare repository support and detached HEAD
before v1.5.0, so a section each for them has been added;
* Sliding mmap and shallow clone are also mentioned.
The full text is available as v1.5.0.txt in 'todo' branch.
--
v1.5.0.txt | 180 +++++++++++++++++++++++++++++++++++++++++++++++++----------
1 files changed, 149 insertions(+), 31 deletions(-)
diff --git a/v1.5.0.txt b/v1.5.0.txt
index 671c14b..9bbe825 100644
--- a/v1.5.0.txt
+++ b/v1.5.0.txt
@@ -1,37 +1,54 @@
-Major changes that are not news
--------------------------------
+GIT v1.5.0 Release Notes
+========================
-There were a handful big changes that happened before this major
-release.
+Old news
+--------
This section is for people who are upgrading from ancient
-versions. Some of them are one-way street upgrades -- once you
-use the feature your repository cannot be used with ancient git.
-
- - There is a new configuration variable core.legacyheaders that
- changes the format of loose objects to more efficient to pack
- and send out of the repository over git native protocol.
- However, this format cannot be read by git older than v1.4.2;
- people fetching from your repository using older clients over
- dumb transports (e.g. http) will also be affected. This is
- not enabled by default.
-
- - Another configuration repack.usedeltabaseoffset further
- allows packfile to be created in more space efficient format,
- which cannot be read by git older than v1.4.3. This is not
- enabled by default.
+versions of git. Although all of the changes in this section
+happened before the current v1.4.4 release, they are summarized
+here in the v1.5.0 release notes for people who skipped earlier
+versions.
+
+In general, you should not have to worry about incompatibility,
+and there is no need to perform "repository conversion" if you
+are updating to v1.5.0. However, some of the changes are
+one-way street upgrades; once you use them your repository
+can no longer be used with ancient git.
+
+ - There is a configuration variable core.legacyheaders that
+ changes the format of loose objects so that they are more
+ efficient to pack and to send out of the repository over git
+ native protocol, since v1.4.2. However, loose objects
+ written in the new format cannot be read by git older than
+ that version; people fetching from your repository using
+ older clients over dumb transports (e.g. http) using older
+ versions of git will also be affected.
+
+ - Since v1.4.3, configuration repack.usedeltabaseoffset allows
+ packfile to be created in more space efficient format, which
+ cannot be read by git older than that version.
+
+The above two are not enabled by default and you explicitly have
+to ask for them, because these two features make repositories
+unreadable by older versions of git, and in v1.5.0 we still do
+not enable them by default for the same reason. We will change
+this default probably 1 year after 1.4.2's release, when it is
+reasonable to expect everybody to have new enough version of
+git.
- 'git pack-refs' appeared in v1.4.4; this command allows tags
to be accessed much more efficiently than the traditional
- 'one-file-per-tag' format. Older git-native client can fetch
- from a repository that packed its tags, but older dumb
- transports cannot. This is done by an explicit user action,
- either by use of "git pack-refs --prune" command or by use of
- "git gc" command.
+ 'one-file-per-tag' format. Older git-native clients can
+ still fetch from a repository that packed and pruned refs
+ (the server side needs to run the up-to-date version of git),
+ but older dumb transports cannot. Packing of refs is done by
+ an explicit user action, either by use of "git pack-refs
+ --prune" command or by use of "git gc" command.
- 'git -p' to paginate anything -- many commands do pagination
by default on a tty. Introduced between v1.4.1 and v1.4.2;
- this may surprise old timer users.
+ this may surprise old timers.
- 'git archive' superseded 'git tar' in v1.4.3;
@@ -43,7 +60,10 @@ use the feature your repository cannot be used with ancient git.
- 'gitweb' became part of git.git during v1.4.0 timeperiod and
seriously modified since then.
- - reflog is an v1.4.0 invention.
+ - reflog is an v1.4.0 invention. This allows you to name a
+ revision that a branch used to be at (e.g. "git diff
+ master@{yesterday} master" allows you to see changes since
+ yesterday's tip of the branch).
Updates in v1.5.0 since v1.4.4 series
@@ -80,7 +100,9 @@ Updates in v1.5.0 since v1.4.4 series
- The data for origin repository is stored in the configuration
file $GIT_DIR/config, not in $GIT_DIR/remotes/, for newly
- created clones (the latter is still supported).
+ created clones. The latter is still supported and there is
+ no need to convert your existing repository if you are
+ already comfortable with your workflow with the layout.
- git-clone always uses what is known as "separate remote"
layout for a newly created repository with a working tree;
@@ -100,6 +122,26 @@ Updates in v1.5.0 since v1.4.4 series
accumulated too many small packs this way as well. Updated
git-count-objects helps you with this.
+ - A new command, git-remote, can help you manage your remote
+ tracking branch definitions.
+
+
+* Bare repositories
+
+ - Certain commands change their behaviour in a bare repository
+ (i.e. a repository without associated working tree). We use
+ a fairly conservative heuristic (if $GIT_DIR is ".git", or
+ ends with "/.git", the repository is not bare) to decide if a
+ repository is bare, but "core.bare" configuration variable
+ can be used to override the heuristic when it misidentifies
+ your repository.
+
+ - git-fetch used to complain updating the current branch but
+ this is now allowed for a bare repository.
+
+ - NEEDSWORK: We should disable Porcelain-ish commands that
+ require a working tree in a bare repository.
+
* Reflog
@@ -118,15 +160,42 @@ Updates in v1.5.0 since v1.4.4 series
versions of git.
Existing repositories that have been using reflog may get
- complaints from fsck-objects; please run "git reflog expire
- --all" first to remove reflog entries that refer to commits
- that are no longer in the repository before attempting to
- repack it.
+ complaints from fsck-objects and may not be able to run
+ git-repack; please run "git reflog expire --all" first to
+ remove reflog entries that refer to commits that are no
+ longer in the repository when that happens.
- git-branch knows how to rename branches and moves existing
reflog data from the old branch to the new one.
+* Detached HEAD
+
+ - You can give non-branch to "git checkout" now. This will
+ dissociate your HEAD from any of your branches. A typical
+ use of this feature is to "look around". E.g.
+
+ $ git checkout v2.6.16
+ ... compile, test, etc.
+ $ git checkout v2.6.17
+ ... compile, test, etc.
+
+ - After detaching your HEAD, you can go back to an existing
+ branch with usual "git checkout $branch". Also you can
+ start a new branch using "git checkout -b $newbranch".
+
+ - You can even pull from other repositories, make merges and
+ commits while your HEAD is detached. Also you can use "git
+ reset" to jump to arbitrary commit.
+
+ Going back to undetached state by "git checkout $branch" can
+ lose the current stat you arrived in these ways, and "git
+ checkout" refuses when the detached HEAD is not pointed by
+ any existing ref (an existing branch, a remote tracking
+ branch or a tag). This safety can be overriden with "git
+ checout -f".
+
+
* Packed refs
- Repositories with hundreds of tags have been paying large
@@ -181,6 +250,24 @@ Updates in v1.5.0 since v1.4.4 series
configuration, in the decreasing order of preference, and
defaults to UTF-8.
+ - Tools for e-mailed patch application now default to -u
+ behaviour; i.e. it always re-codes from the e-mailed encoding
+ to the encoding specified with i18n.commitencoding. This
+ unfortunately forces projects that have happily using a
+ legacy encoding without setting i18n.commitencoding, but
+ taken with other improvement, please excuse us for this very
+ minor one-time inconvenience.
+
+
+* Foreign SCM interfaces
+
+ - git-svn now requires the Perl SVN:: libraries, the
+ command-line backend was too slow and limited.
+
+ - the 'commit' subcommand of git-svn has been renamed to
+ 'set-tree', and 'dcommit' is the recommended replacement for
+ day-to-day work.
+
* User support
@@ -191,4 +278,35 @@ Updates in v1.5.0 since v1.4.4 series
- Better error messages for often used Porcelainish commands.
+* Sliding mmap
+
+ - We used to assume that we can mmap the whole packfile while
+ in use, but with a large project this consumes huge virtual
+ memory space and truly huge ones would not fit in the
+ userland address space on 32-bit platforms. We now mmap huge
+ packfile in pieces to avoid this problem.
+
+
+* Shallow clones
+
+ - There is a partial support for 'shallow' repositories that
+ keeps only recent history now. A 'shallow clone' is created
+ by specifying how deep that truncated history should be.
+
+ Currently a shallow repository has number of limitations:
+
+ - Cloning and fetching _from_ a shallow clone are not
+ supported (nor tested -- so they might work by accident but
+ they are not expected to).
+
+ - Pushing from nor into a shallow clone are not expected to
+ work.
+
+ - Merging inside a shallow repository would work as long as a
+ merge base is found in the recent history, but otherwise it
+ will be like merging unrelated histories and may result in
+ huge conflicts.
+ but this would be more than adequate for people who want to
+ look at near the tip of a big project with a deep history and
+ send patches in e-mail format.
^ permalink raw reply related [relevance 6%]
* [PATCH] some doc updates
@ 2007-01-15 3:44 6% Nicolas Pitre
0 siblings, 0 replies; 200+ results
From: Nicolas Pitre @ 2007-01-15 3:44 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
1) talk about "git merge" instead of "git pull ."
2) suggest "git repo-config" instead of directly editing config files
3) echo "URL: blah" > .git/remotes/foo is obsolete and should be
"git repo-config remote.foo.url blah"
4) support for partial URL prefix has been removed (see commit
ea560e6d64374ec1f6c163c276319a3da21a1345) so drop mention of it.
Signed-off-by: Nicolas Pitre <nico@cam.org>
---
diff --git a/Documentation/core-tutorial.txt b/Documentation/core-tutorial.txt
index 0cd33fb..51dd6c6 100644
--- a/Documentation/core-tutorial.txt
+++ b/Documentation/core-tutorial.txt
@@ -1129,46 +1129,26 @@ juggle multiple lines of development simultaneously. Of
course, you will pay the price of more disk usage to hold
multiple working trees, but disk space is cheap these days.
-[NOTE]
-You could even pull from your own repository by
-giving '.' as <remote-repository> parameter to `git pull`. This
-is useful when you want to merge a local branch (or more, if you
-are making an Octopus) into the current branch.
-
It is likely that you will be pulling from the same remote
repository from time to time. As a short hand, you can store
-the remote repository URL in a file under .git/remotes/
-directory, like this:
-
-------------------------------------------------
-$ mkdir -p .git/remotes/
-$ cat >.git/remotes/linus <<\EOF
-URL: http://www.kernel.org/pub/scm/git/git.git/
-EOF
-------------------------------------------------
-
-and use the filename to `git pull` instead of the full URL.
-The URL specified in such file can even be a prefix
-of a full URL, like this:
+the remote repository URL in the local repository's config file
+like this:
------------------------------------------------
-$ cat >.git/remotes/jgarzik <<\EOF
-URL: http://www.kernel.org/pub/scm/linux/git/jgarzik/
-EOF
+$ git repo-config remote.linus.url http://www.kernel.org/pub/scm/git/git.git/
------------------------------------------------
+and use the "linus" keyword with `git pull` instead of the full URL.
Examples.
. `git pull linus`
. `git pull linus tag v0.99.1`
-. `git pull jgarzik/netdev-2.6.git/ e100`
the above are equivalent to:
. `git pull http://www.kernel.org/pub/scm/git/git.git/ HEAD`
. `git pull http://www.kernel.org/pub/scm/git/git.git/ tag v0.99.1`
-. `git pull http://www.kernel.org/pub/.../jgarzik/netdev-2.6.git e100`
How does the merge work?
@@ -1546,7 +1526,8 @@ on that project and has an own "public repository" goes like this:
1. Prepare your work repository, by `git clone` the public
repository of the "project lead". The URL used for the
- initial cloning is stored in `.git/remotes/origin`.
+ initial cloning is stored in the remote.origin.url
+ configuration variable.
2. Prepare a public repository accessible to others, just like
the "project lead" person does.
@@ -1586,14 +1567,15 @@ like this:
1. Prepare your work repository, by `git clone` the public
repository of the "project lead" (or a "subsystem
maintainer", if you work on a subsystem). The URL used for
- the initial cloning is stored in `.git/remotes/origin`.
+ the initial cloning is stored in the remote.origin.url
+ configuration variable.
2. Do your work in your repository on 'master' branch.
3. Run `git fetch origin` from the public repository of your
upstream every once in a while. This does only the first
half of `git pull` but does not merge. The head of the
- public repository is stored in `.git/refs/heads/origin`.
+ public repository is stored in `.git/refs/remotes/origin/master`.
4. Use `git cherry origin` to see which ones of your patches
were accepted, and/or use `git rebase origin` to port your
@@ -1681,11 +1663,11 @@ $ git reset --hard master~2
You can make sure 'git show-branch' matches the state before
those two 'git merge' you just did. Then, instead of running
-two 'git merge' commands in a row, you would pull these two
+two 'git merge' commands in a row, you would merge these two
branch heads (this is known as 'making an Octopus'):
------------
-$ git pull . commit-fix diff-fix
+$ git merge commit-fix diff-fix
$ git show-branch
! [commit-fix] Fix commit message normalization.
! [diff-fix] Fix rename detection.
@@ -1701,7 +1683,7 @@ $ git show-branch
Note that you should not do Octopus because you can. An octopus
is a valid thing to do and often makes it easier to view the
-commit history if you are pulling more than two independent
+commit history if you are merging more than two independent
changes at the same time. However, if you have merge conflicts
with any of the branches you are merging in and need to hand
resolve, that is an indication that the development happened in
diff --git a/Documentation/everyday.txt b/Documentation/everyday.txt
index 4e83994..ca36a76 100644
--- a/Documentation/everyday.txt
+++ b/Documentation/everyday.txt
@@ -148,8 +148,7 @@ modification will be caught if you do `git commit -a` later.
<8> redo the commit undone in the previous step, using the message
you originally wrote.
<9> switch to the master branch.
-<10> merge a topic branch into your master branch. You can also use
-`git pull . alsa-audio`, i.e. pull from the local repository.
+<10> merge a topic branch into your master branch.
<11> review commit logs; other forms to limit output can be
combined and include `\--max-count=10` (show 10 commits),
`\--until=2005-12-10`, etc.
diff --git a/Documentation/git-pull.txt b/Documentation/git-pull.txt
index 13be992..a90b764 100644
--- a/Documentation/git-pull.txt
+++ b/Documentation/git-pull.txt
@@ -52,7 +52,8 @@ git pull origin next::
git pull . fixes enhancements::
Bundle local branch `fixes` and `enhancements` on top of
- the current branch, making an Octopus merge.
+ the current branch, making an Octopus merge. This `git pull .`
+ syntax is equivalent to `git merge`.
git pull -s ours . obsolete::
Merge local branch `obsolete` into the current branch,
diff --git a/Documentation/git-rerere.txt b/Documentation/git-rerere.txt
index b57a72b..08a0557 100644
--- a/Documentation/git-rerere.txt
+++ b/Documentation/git-rerere.txt
@@ -81,7 +81,7 @@ One way to do it is to pull master into the topic branch:
------------
$ git checkout topic
- $ git pull . master
+ $ git merge master
o---*---o---+ topic
/ /
@@ -103,10 +103,10 @@ in which case the final commit graph would look like this:
------------
$ git checkout topic
- $ git pull . master
+ $ git merge master
$ ... work on both topic and master branches
$ git checkout master
- $ git pull . topic
+ $ git merge topic
o---*---o---+---o---o topic
/ / \
@@ -126,11 +126,11 @@ top of the tip before the test merge:
------------
$ git checkout topic
- $ git pull . master
+ $ git merge master
$ git reset --hard HEAD^ ;# rewind the test merge
$ ... work on both topic and master branches
$ git checkout master
- $ git pull . topic
+ $ git merge topic
o---*---o-------o---o topic
/ \
diff --git a/Documentation/tutorial.txt b/Documentation/tutorial.txt
index d2bf0b9..8325c5e 100644
--- a/Documentation/tutorial.txt
+++ b/Documentation/tutorial.txt
@@ -11,15 +11,13 @@ diff" with:
$ man git-diff
------------------------------------------------
-It is a good idea to introduce yourself to git before doing any
-operation. The easiest way to do so is:
+It is a good idea to introduce yourself to git with your name and
+public email address before doing any operation. The easiest
+way to do so is:
------------------------------------------------
-$ cat >~/.gitconfig <<\EOF
-[user]
- name = Your Name Comes Here
- email = you@yourdomain.example.com
-EOF
+$ git repo-config --global user.name "Your Name Comes Here"
+$ git repo-config --global user.email you@yourdomain.example.com
------------------------------------------------
@@ -211,7 +209,7 @@ at this point the two branches have diverged, with different changes
made in each. To merge the changes made in experimental into master, run
------------------------------------------------
-$ git pull . experimental
+$ git merge experimental
------------------------------------------------
If the changes don't conflict, you're done. If there are conflicts,
@@ -316,14 +314,14 @@ shows a list of all the changes that Bob made since he branched from
Alice's master branch.
After examining those changes, and possibly fixing things, Alice
-could pull the changes into her master branch:
+could merge the changes into her master branch:
-------------------------------------
$ git checkout master
-$ git pull . bob-incoming
+$ git merge bob-incoming
-------------------------------------
-The last command is a pull from the "bob-incoming" branch in Alice's
+The last command is a merge from the "bob-incoming" branch in Alice's
own repository.
Alice could also perform both steps at once with:
^ permalink raw reply related [relevance 6%]
* Re: Rebasing stgit stacks
@ 2007-01-16 22:42 4% ` Catalin Marinas
2007-01-16 23:17 1% ` Yann Dirson
0 siblings, 1 reply; 200+ results
From: Catalin Marinas @ 2007-01-16 22:42 UTC (permalink / raw)
To: Yann Dirson; +Cc: git, Guilhem Bonnefille
On 15/01/07, Yann Dirson <ydirson@altern.org> wrote:
> On Mon, Jan 15, 2007 at 10:46:37PM +0000, Catalin Marinas wrote:
> > >I have started work on implementing "stg pull --to <newbase>", but I'm
> > >facing some issues.
> >
> > I think the combination of 'pull' and '--to' is confusing (at least to
> > me) if you think of there English meaning.
>
> That's possible, I'm not a native english speater :)
I'm not either :-)
> The idea is that we pull our stack from one place (current base) to
> another. Another possiblity would have been "stg rebase", but I'm not
> very keen on adding another command to do a very similar job.
Can you give a typical example of what <newbase> argument for --to is
and what you repository looks like? I just want make sure I correctly
understand the problem.
I see the 'pull' command as a way to fetch the latest remote changes
and merge them into the current branch (which would usually be a
fast-forward). This command was meant as a stgit-aware 'git pull'.
> > As Petr suggested at the OLS last year, I added the possibility to
> > configure the 'git pull' command so that people use whatever script
> > they like.
>
> Right. Maybe different workflows should have this option set to
> different values in different repos ? I'm merely trying to get the
> best default :)
But you want to replace the call to 'git pull' with 'git fetch'. I
think this is fine with my workflow but some people might actually
rely on calling 'git pull' (or cg-pull).
> > I was working on a set of patches (mainly picking from other
> > branches and minor modifications) and just committing them when
> > finishing. Further updates from kernel.org triggered full merges
> > with the base.
>
> But doing this means that you can end with a base that is not any more
> on the parent branch, but on a local merge, right ? I'm not sure it
> is an easy thing to work with.
Yes, indeed, but this is probably the only way you can publish a
branch and still partially manage it with StGIT.
> On the StGIT front, we could have "stg clone" look at
> patches/<branch>/current or so, and then modify the
> remote.<name>.fetch entry accordingly. Or do you think of any
> workflow that would break under this change ?
Currently, 'stg clone' just calls 'git clone' and initializes the
master branch. There is no patches/<branch>/current file as there is
no current patch.
> Even if we would not need it here, it would be good to have those 2
> parameters set when we can infer them. That reminds me that "stg
> clone" does not appear to allow selecting a specific branch in the
> parent repo (which explains why the .merge parameter is not so
> crucially needed yet: we always clone the main branch).
I haven't looked at 'git clone' recently, can you select a specific branch?
--
Catalin
^ permalink raw reply [relevance 4%]
* Re: Rebasing stgit stacks
2007-01-16 22:42 4% ` Catalin Marinas
@ 2007-01-16 23:17 1% ` Yann Dirson
0 siblings, 0 replies; 200+ results
From: Yann Dirson @ 2007-01-16 23:17 UTC (permalink / raw)
To: Catalin Marinas; +Cc: git, Guilhem Bonnefille
On Tue, Jan 16, 2007 at 10:42:17PM +0000, Catalin Marinas wrote:
> >The idea is that we pull our stack from one place (current base) to
> >another. Another possiblity would have been "stg rebase", but I'm not
> >very keen on adding another command to do a very similar job.
>
> Can you give a typical example of what <newbase> argument for --to is
> and what you repository looks like? I just want make sure I correctly
> understand the problem.
My example is quite similar to the one given by Guilhem: I had a git
branch coming from git-cvsimport, and my stgit stack forked atop that
branch. At some point git-cvsimport fucked something, and I
regenerated a new mirror branch using it in a fresh repo. Then I
wanted to rebase my stack on that new branch.
> I see the 'pull' command as a way to fetch the latest remote changes
> and merge them into the current branch (which would usually be a
> fast-forward). This command was meant as a stgit-aware 'git pull'.
Do you have an example of use where we would need a non-fast-forward
pull (supposing we have the "pull --to" functionality already, since I
shall find time to finish soon).
> >> As Petr suggested at the OLS last year, I added the possibility to
> >> configure the 'git pull' command so that people use whatever script
> >> they like.
> >
> >Right. Maybe different workflows should have this option set to
> >different values in different repos ? I'm merely trying to get the
> >best default :)
>
> But you want to replace the call to 'git pull' with 'git fetch'. I
> think this is fine with my workflow but some people might actually
> rely on calling 'git pull' (or cg-pull).
Right, it may be possible (and I'd be interested in seeing such a
workflow). Maybe we could keep support for git-pull as an
alternative.
This could be done, eg. by letting the user use "pullcmd=git-pull" and
introduce a new option like "fastforward=<bool>" triggering the
fast-forward needed after git-fetch, with the default being "true",
and the current behaviour being obtained by changing it to "false".
That would not add too much complexity, while setting the default to
what I believe to match the most common workflows, and allow anyone
relying on the current behaviour to get it back.
> >> I was working on a set of patches (mainly picking from other
> >> branches and minor modifications) and just committing them when
> >> finishing. Further updates from kernel.org triggered full merges
> >> with the base.
> >
> >But doing this means that you can end with a base that is not any more
> >on the parent branch, but on a local merge, right ? I'm not sure it
> >is an easy thing to work with.
>
> Yes, indeed, but this is probably the only way you can publish a
> branch and still partially manage it with StGIT.
Well, I'd think that automatic rebasing would be a more elegant
solution.
> >On the StGIT front, we could have "stg clone" look at
> >patches/<branch>/current or so, and then modify the
> >remote.<name>.fetch entry accordingly. Or do you think of any
> >workflow that would break under this change ?
>
> Currently, 'stg clone' just calls 'git clone' and initializes the
> master branch. There is no patches/<branch>/current file as there is
> no current patch.
I meant, the patches/<branch>/current in the remote repo. If that one
exist, then we should pull it with "+" as we should do for any
rebasing remote branch.
> >Even if we would not need it here, it would be good to have those 2
> >parameters set when we can infer them. That reminds me that "stg
> >clone" does not appear to allow selecting a specific branch in the
> >parent repo (which explains why the .merge parameter is not so
> >crucially needed yet: we always clone the main branch).
>
> I haven't looked at 'git clone' recently, can you select a specific branch?
I had assumed so without looking, but it looks like you cannot select
much. When using separate remotes, the HEAD in the clone is taken
from the HEAD in the remote, and bears the same name. It is the only
ref created under heads/.
Would there be some missing functionnality in git-clone, or am I just
missing something obvious ?
Best regards,
--
Yann.
^ permalink raw reply [relevance 1%]
* Re: [Announce] GIT v1.5.0-rc2
@ 2007-01-21 11:20 2% ` Junio C Hamano
2007-01-21 19:46 0% ` Horst H. von Brand
2007-01-22 18:08 1% ` Carl Worth
0 siblings, 2 replies; 200+ results
From: Junio C Hamano @ 2007-01-21 11:20 UTC (permalink / raw)
To: git; +Cc: linux-kernel
BTW, as the upcoming v1.5.0 release will introduce quite a bit of
surface changes (although at the really core it still is the old
git and old ways should continue to work), I am wondering if it
would help people to try out and find wrinkles before the real
thing for me to cut a tarball and a set of RPM packages.
Comments?
Also, in the same spirit of giving the release an early
exposure, here is the current draft of 1.5.0 release notes.
-- >8 -- cut here -- >8 --
GIT v1.5.0 Release Notes (draft)
================================
Old news
--------
This section is for people who are upgrading from ancient
versions of git. Although all of the changes in this section
happened before the current v1.4.4 release, they are summarized
here in the v1.5.0 release notes for people who skipped earlier
versions.
In general, you should not have to worry about incompatibility,
and there is no need to perform "repository conversion" if you
are updating to v1.5.0. However, some of the changes are
one-way street upgrades; once you use them your repository
can no longer be used with ancient git.
- There is a configuration variable core.legacyheaders that
changes the format of loose objects so that they are more
efficient to pack and to send out of the repository over git
native protocol, since v1.4.2. However, loose objects
written in the new format cannot be read by git older than
that version; people fetching from your repository using
older clients over dumb transports (e.g. http) using older
versions of git will also be affected.
- Since v1.4.3, configuration repack.usedeltabaseoffset allows
packfile to be created in more space efficient format, which
cannot be read by git older than that version.
The above two are not enabled by default and you explicitly have
to ask for them, because these two features make repositories
unreadable by older versions of git, and in v1.5.0 we still do
not enable them by default for the same reason. We will change
this default probably 1 year after 1.4.2's release, when it is
reasonable to expect everybody to have new enough version of
git.
- 'git pack-refs' appeared in v1.4.4; this command allows tags
to be accessed much more efficiently than the traditional
'one-file-per-tag' format. Older git-native clients can
still fetch from a repository that packed and pruned refs
(the server side needs to run the up-to-date version of git),
but older dumb transports cannot. Packing of refs is done by
an explicit user action, either by use of "git pack-refs
--prune" command or by use of "git gc" command.
- 'git -p' to paginate anything -- many commands do pagination
by default on a tty. Introduced between v1.4.1 and v1.4.2;
this may surprise old timers.
- 'git archive' superseded 'git tar-tree' in v1.4.3;
- 'git cvsserver' was new invention in v1.3.0;
- 'git repo-config', 'git grep', 'git rebase' and 'gitk' were
seriously enhanced during v1.4.0 timeperiod.
- 'gitweb' became part of git.git during v1.4.0 timeperiod and
seriously modified since then.
- reflog is an v1.4.0 invention. This allows you to name a
revision that a branch used to be at (e.g. "git diff
master@{yesterday} master" allows you to see changes since
yesterday's tip of the branch).
Updates in v1.5.0 since v1.4.4 series
-------------------------------------
* Index manipulation
- git-add is to add contents to the index (aka "staging area"
for the next commit), whether the file the contents happen to
be is an existing one or a newly created one.
- git-add without any argument does not add everything
anymore. Use 'git-add .' instead. Also you can add
otherwise ignored files with an -f option.
- git-add tries to be more friendly to users by offering an
interactive mode.
- git-commit <path> used to refuse to commit if <path> was
different between HEAD and the index (i.e. update-index was
used on it earlier). This check was removed.
- git-rm is much saner and safer. It is used to remove paths
from both the index file and the working tree, and makes sure
you are not losing any local modification before doing so.
- git-reset <tree> <paths>... can be used to revert index
entries for selected paths.
- git-update-index is much less visible.
* Repository layout and objects transfer
- The data for origin repository is stored in the configuration
file $GIT_DIR/config, not in $GIT_DIR/remotes/, for newly
created clones. The latter is still supported and there is
no need to convert your existing repository if you are
already comfortable with your workflow with the layout.
- git-clone always uses what is known as "separate remote"
layout for a newly created repository with a working tree;
i.e. tracking branches in $GIT_DIR/refs/remotes/origin/ are
used to track branches from the origin.
- New branches that appear on the origin side after a clone is
made are also tracked automatically. This is done with an
wildcard refspec "refs/heads/*:refs/remotes/origin/*", which
older git does not understand, so if you clone with 1.5.0,
you would need to downgrade remote.*.fetch in the
configuration file to specify each branch you are interested
in individually if you plan to fetch into the repository with
older versions of git (but why would you?).
- git-branch and git-show-branch know remote tracking branches.
- git-push can now be used to delete a remote branch or a tag.
This requires the updated git on the remote side.
- git-push more agressively keeps the transferred objects
packed. Earlier we recommended to monitor amount of loose
objects and repack regularly, but you should repack when you
accumulated too many small packs this way as well. Updated
git-count-objects helps you with this.
- A new command, git-remote, can help you manage your remote
tracking branch definitions.
* Bare repositories
- Certain commands change their behaviour in a bare repository
(i.e. a repository without associated working tree). We use
a fairly conservative heuristic (if $GIT_DIR is ".git", or
ends with "/.git", the repository is not bare) to decide if a
repository is bare, but "core.bare" configuration variable
can be used to override the heuristic when it misidentifies
your repository.
- git-fetch used to complain updating the current branch but
this is now allowed for a bare repository. So is the use of
'git-branch -f' to update the current branch.
- Porcelain-ish commands that require a working tree refuses to
work in a bare repository.
* Reflog
- Reflog records the history of where the tip of each branch
was at each moment. This facility is enabled by default for
repositories with working trees, and can be accessed with the
"branch@{time}" and "branch@{Nth}" notation.
- "git show-branch" learned showing the reflog data with the
new --reflog option. "git log" has --walk-reflogs option to
view reflog entries in a more verbose manner.
- git-branch knows how to rename branches and moves existing
reflog data from the old branch to the new one.
- The commits referred to by reflog entries are now protected
against pruning. The new command "git reflog expire" can be
used to truncate older reflog entries and entries that refer
to commits that have been pruned away previously with older
versions of git.
Existing repositories that have been using reflog may get
complaints from fsck-objects and may not be able to run
git-repack, if you had run git-prune from older git; please
run "git reflog expire --stale-fix --all" first to remove
reflog entries that refer to commits that are no longer in
the repository when that happens.
* Crufts removal
- We used to say "old commits are retrievable using reflog and
'master@{yesterday}' syntax as long as you haven't run
git-prune". We no longer have to say the latter half of the
above sentence, as git-prune does not remove things reachable
from reflog entries.
- 'git-prune' by default does not remove _everything_
unreachable, as there is a one-day grace period built-in.
- There is a toplevel garbage collector script, 'git-gc', that
is an easy way to run 'git-repack -a -d', 'git-reflog gc',
and 'git-prune'.
* Detached HEAD
- You can give non-branch to "git checkout" now. This will
dissociate your HEAD from any of your branches. A typical
use of this feature is to "look around". E.g.
$ git checkout v2.6.16
... compile, test, etc.
$ git checkout v2.6.17
... compile, test, etc.
- After detaching your HEAD, you can go back to an existing
branch with usual "git checkout $branch". Also you can
start a new branch using "git checkout -b $newbranch".
- You can even pull from other repositories, make merges and
commits while your HEAD is detached. Also you can use "git
reset" to jump to arbitrary commit.
Going back to undetached state by "git checkout $branch" can
lose the current stat you arrived in these ways, and "git
checkout" refuses when the detached HEAD is not pointed by
any existing ref (an existing branch, a remote tracking
branch or a tag). This safety can be overriden with "git
checkout -f $branch".
* Packed refs
- Repositories with hundreds of tags have been paying large
overhead, both in storage and in runtime, due to the
traditional one-ref-per-file format. A new command,
git-pack-refs, can be used to "pack" them in more efficient
representation.
- Clones and fetches over dumb transports are now aware of
packed refs and can download from repositories that use
them.
* Configuration
- configuration related to color setting are consolidated under
color.* namespace (older diff.color.*, status.color.* are
still supported).
* Less external dependency
- We no longer require the "merge" program from the RCS suite.
All 3-way file-level merges are now done internally.
- The original implementation of git-merge-recursive which was
in Python has been removed; we have C implementation of it
now.
- git-shortlog is no longer a Perl script. It no longer
requires output piped from git-log; it can accept revision
parameters directly on the command line.
* I18n
- We have always encouraged the commit message to be encoded in
UTF-8, but the users are allowed to use legacy encoding as
appropriate for their projects. This will continue to be the
case. However, a non UTF-8 commit encoding _must_ be
explicitly set with i18n.commitencoding in the repository
where a commit is made; otherwise git-commit-tree will
complain if the log message does not look like a valid UTF-8
string.
- The value of i18n.commitencoding in the originating
repository is recorded in the commit object on the "encoding"
header, if it is not UTF-8. git-log and friends notice this,
and reencodes the message to the log output encoding when
displaying, if they are different. The log output encoding
is determined by "git log --encoding=<encoding>",
i18n.logoutputencoding configuration, or i18n.commitencoding
configuration, in the decreasing order of preference, and
defaults to UTF-8.
- Tools for e-mailed patch application now default to -u
behaviour; i.e. it always re-codes from the e-mailed encoding
to the encoding specified with i18n.commitencoding. This
unfortunately forces projects that have happily been using a
legacy encoding without setting i18n.commitencoding to set
the configuration, but taken with other improvement, please
excuse us for this very minor one-time inconvenience.
* e-mailed patches
- See the above I18n section.
- git-format-patch now enables --binary without being asked.
git-am does _not_ default to it, as sending binary patch via
e-mail is unusual and is harder to review than textual
patches and it is prudent to require the person who is
applying the patch to explicitly ask for it.
- The default suffix for git-format-patch output is now ".patch",
not ".txt". This can be changed with --suffix=.txt option,
or "format.suffix = .txt" in the configuration.
* Foreign SCM interfaces
- git-svn now requires the Perl SVN:: libraries, the
command-line backend was too slow and limited.
- the 'commit' subcommand of git-svn has been renamed to
'set-tree', and 'dcommit' is the recommended replacement for
day-to-day work.
* User support
- Quite a lot of documentation updates.
- Bash completion scripts have been updated heavily.
- Better error messages for often used Porcelainish commands.
* Sliding mmap
- We used to assume that we can mmap the whole packfile while
in use, but with a large project this consumes huge virtual
memory space and truly huge ones would not fit in the
userland address space on 32-bit platforms. We now mmap huge
packfile in pieces to avoid this problem.
* Shallow clones
- There is a partial support for 'shallow' repositories that
keeps only recent history. A 'shallow clone' is created by
specifying how deep that truncated history should be.
Currently a shallow repository has number of limitations:
- Cloning and fetching _from_ a shallow clone are not
supported (nor tested -- so they might work by accident but
they are not expected to).
- Pushing from nor into a shallow clone are not expected to
work.
- Merging inside a shallow repository would work as long as a
merge base is found in the recent history, but otherwise it
will be like merging unrelated histories and may result in
huge conflicts.
but this would be more than adequate for people who want to
look at near the tip of a big project with a deep history and
send patches in e-mail format.
^ permalink raw reply [relevance 2%]
* Re: [Announce] GIT v1.5.0-rc2
2007-01-21 11:20 2% ` Junio C Hamano
@ 2007-01-21 19:46 0% ` Horst H. von Brand
2007-01-22 18:08 1% ` Carl Worth
1 sibling, 0 replies; 200+ results
From: Horst H. von Brand @ 2007-01-21 19:46 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, linux-kernel
Junio C Hamano <junkio@cox.net> wrote:
> BTW, as the upcoming v1.5.0 release will introduce quite a bit of
> surface changes (although at the really core it still is the old
> git and old ways should continue to work), I am wondering if it
> would help people to try out and find wrinkles before the real
> thing for me to cut a tarball and a set of RPM packages.
>
> Comments?
>
> Also, in the same spirit of giving the release an early
> exposure, here is the current draft of 1.5.0 release notes.
>
> -- >8 -- cut here -- >8 --
>
> GIT v1.5.0 Release Notes (draft)
> ================================
>
> Old news
> --------
[...]
> - There is a configuration variable core.legacyheaders that
> changes the format of loose objects so that they are more
> efficient to pack and to send out of the repository over git
> native protocol, since v1.4.2. However, loose objects
> written in the new format cannot be read by git older than
> that version; people fetching from your repository using
> older clients over dumb transports (e.g. http) using older
> versions of git will also be affected.
Huh?
What are possible values of that variable? What happens if it is set/unset?
I'd suppose that if it is set, you get the old format, but that isn't clear.
> - Since v1.4.3, configuration repack.usedeltabaseoffset allows
> packfile to be created in more space efficient format, which
> cannot be read by git older than that version.
Same as above.
> The above two are not enabled by default and you explicitly have
> to ask for them, because these two features make repositories
> unreadable by older versions of git, and in v1.5.0 we still do
> not enable them by default for the same reason. We will change
> this default probably 1 year after 1.4.2's release, when it is
> reasonable to expect everybody to have new enough version of
> git.
I don't see an upgrade path here that doesn't involve keeping cruft "new
feature is on" variables around indefinitely... Why not just a repository
version?
[...]
> Updates in v1.5.0 since v1.4.4 series
> -------------------------------------
>
> * Index manipulation
[...]
> - git-add without any argument does not add everything
> anymore. Use 'git-add .' instead. Also you can add
> otherwise ignored files with an -f option.
I suppose "git add ." works for 'adding everything' only at the top?
> - git-add tries to be more friendly to users by offering an
> interactive mode.
Why not tell about "git add -i"?
[...]
> * Detached HEAD
[...]
> - After detaching your HEAD, you can go back to an existing
> branch with usual "git checkout $branch". Also you can
> start a new branch using "git checkout -b $newbranch".
Where is such a branch rooted?
> - You can even pull from other repositories, make merges and
> commits while your HEAD is detached. Also you can use "git
> reset" to jump to arbitrary commit.
Does this leave you on that branch, or still in limbo?
> Going back to undetached state by "git checkout $branch" can
s/undetached/attached/
> lose the current stat you arrived in these ways, and "git
> checkout" refuses when the detached HEAD is not pointed by
> any existing ref (an existing branch, a remote tracking
> branch or a tag). This safety can be overriden with "git
> checkout -f $branch".
What happens if there are changes in the tracked files?
[...]
> * Shallow clones
>
> - There is a partial support for 'shallow' repositories that
> keeps only recent history. A 'shallow clone' is created by
> specifying how deep that truncated history should be.
A bit of detail on how to specify shallowness would be nice here...
Very nice work, thanks!
--
Dr. Horst H. von Brand User #22616 counter.li.org
Departamento de Informatica Fono: +56 32 2654431
Universidad Tecnica Federico Santa Maria +56 32 2654239
Casilla 110-V, Valparaiso, Chile Fax: +56 32 2797513
^ permalink raw reply [relevance 0%]
* Re: [Announce] GIT v1.5.0-rc2
2007-01-21 11:20 2% ` Junio C Hamano
2007-01-21 19:46 0% ` Horst H. von Brand
@ 2007-01-22 18:08 1% ` Carl Worth
1 sibling, 0 replies; 200+ results
From: Carl Worth @ 2007-01-22 18:08 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 4897 bytes --]
On Sun, 21 Jan 2007 03:20:06 -0800, Junio C Hamano wrote:
> Also, in the same spirit of giving the release an early
> exposure, here is the current draft of 1.5.0 release notes.
Thanks, these are very good and really show how much great progress
has gone into git recently. Congratulations to everyone who has helped
with this!
A few comments:
> In general, you should not have to worry about incompatibility,
> and there is no need to perform "repository conversion" if you
> are updating to v1.5.0. However, some of the changes are
> one-way street upgrades; once you use them your repository
> can no longer be used with ancient git.
This "one-way street upgrades" sentence makes the upgrade to 1.5 sound
scarier than it really is. It's only after two more paragraphs of
fairly dense technical content that the reader is told that none of
this stuff is enabled by default yet.
Maybe replace the second sentence with something like:
As of git v1.5.0 there are some optional changes to the
repository that allow data to be stored and transferred more
efficiently. These changes are not enabled by default as they
will make the repository unusable with git versions before
v1.4.2. Specifically the available options are:
or something along those lines.
> - git-update-index is much less visible.
It's not clear what this sentence means. Perhaps add something like:
, (many mentions of update-index in git output and
documentation have now been replaced by simpler commands such
as "git add" or "git rm").
> - git-clone always uses what is known as "separate remote"
> layout for a newly created repository with a working tree;
> i.e. tracking branches in $GIT_DIR/refs/remotes/origin/ are
> used to track branches from the origin.
This change has some workflow impact that is not at all obvious from
the above description. For example, after cloning git.git, things that
used to work like "git checkout -b my-next next" now no longer work,
(needing to use "origin/next" instead). And these branches also won't
appear in "git branch" output, (without the new -r option).
I think the release notes should spend a little more attention on an
issue like this. Maybe a separate section on changes to existing
interfaces, (as opposed to most of the other changes which are
improvements in the implementation of existing interfaces or just
plain new interfaces such as "git remote", "git gc", etc.)
If there is a new section, the previous paragraphs describing the move
of cloned origin information from .git/remotes/origin to .git/config
might belong there as well, (depending on whether you consider those
file contents a user-visible interface or not).
> - git-branch and git-show-branch know remote tracking branches.
Should mention "-r" here.
> - git-push can now be used to delete a remote branch or a tag.
> This requires the updated git on the remote side.
What's the syntax for this? I know you don't want to turn the release
notes into a user manual, but it'd be nice to have brief mentions of
the new interfaces, (like the nice mention of "git add -i" for
example). Even with a quick skim through the git-push documentation,
I'm not immediately seeing how to delete a remote branch or tag.
> - There is a toplevel garbage collector script, 'git-gc', that
> is an easy way to run 'git-repack -a -d', 'git-reflog gc',
> and 'git-prune'.
I think it's definitely worthwhile to note the fix of race conditions,
etc. here. It would be nice to have some short rule such as:
"git gc" is free from any known race conditions with
simultaneous git processes modifying the repository. So it's
perfectly safe to run "git gc" from a cron job.
Or a similarly succinct rule that's actually true, (I think the recent
thread suggested "git gc" would only be safe with an extra
option---I'd much rather see it be safe by default and make the user
ask for extra unsafe pruning with an option).
> - You can give non-branch to "git checkout" now.
Rather than "non-branch" I think it would be nice to say something
that mentioned tags. Maybe something like:
You can now use 'git checkout' to checkout tags or any other
revision, rather than just named branches."
> - Repositories with hundreds of tags have been paying large
> overhead, both in storage and in runtime, due to the
> traditional one-ref-per-file format. A new command,
> git-pack-refs, can be used to "pack" them in more efficient
> representation.
Is git-gc doing this housekeeping? If not, should it be? If so, should
it be mentioned here (and in the description of git-gc above)?
> - There is a partial support for 'shallow' repositories that
> keeps only recent history. A 'shallow clone' is created by
> specifying how deep that truncated history should be.
Here's another description that could definitely benefit from a very
short example command.
-Carl
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply [relevance 1%]
* [PATCH] Hash name is SHA-1
@ 2007-01-25 12:50 1% ` Horst H. von Brand
0 siblings, 0 replies; 200+ results
From: Horst H. von Brand @ 2007-01-25 12:50 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, Horst H. von Brand
From: Horst H. von Brand <vonbrand@inf.utfsm.cl> - unquoted
Signed-off-by: Horst H. von Brand <vonbrand@inf.utfsm.cl>
---
Documentation/git-receive-pack.txt | 14 ++++++------
Documentation/git-rev-parse.txt | 8 +++---
Documentation/git-show-branch.txt | 4 +-
Documentation/git-show-index.txt | 2 +-
Documentation/git-show-ref.txt | 4 +-
Documentation/git-svn.txt | 6 ++--
Documentation/git-tag.txt | 2 +-
Documentation/git-unpack-file.txt | 2 +-
Documentation/git-update-index.txt | 14 ++++++------
Documentation/git-verify-pack.txt | 4 +-
Documentation/git-verify-tag.txt | 2 +-
Documentation/git.txt | 4 +-
Documentation/glossary.txt | 8 +++---
Documentation/pretty-formats.txt | 16 +++++++-------
Documentation/tutorial-2.txt | 16 +++++++-------
builtin-apply.c | 18 ++++++++++------
builtin-blame.c | 20 ++++++++++++------
builtin-cat-file.c | 5 ++-
builtin-commit-tree.c | 3 +-
builtin-describe.c | 3 +-
builtin-diff-tree.c | 9 ++++---
builtin-diff.c | 6 +++-
builtin-for-each-ref.c | 6 +++-
builtin-init-db.c | 2 +-
builtin-log.c | 5 ++-
builtin-name-rev.c | 2 +-
builtin-pack-objects.c | 21 +++++++++++--------
builtin-prune.c | 2 +-
builtin-push.c | 4 ++-
builtin-read-tree.c | 6 ++++-
builtin-reflog.c | 3 +-
builtin-rev-list.c | 6 +++-
builtin-rm.c | 8 ++++--
builtin-shortlog.c | 2 +-
builtin-show-branch.c | 19 ++++++++++++-----
builtin-show-ref.c | 8 +++++-
builtin-unpack-objects.c | 2 +-
builtin-update-index.c | 37 +++++++++++++++++++++++------------
builtin-update-ref.c | 4 +-
builtin-write-tree.c | 3 +-
cache-tree.c | 9 +++++--
cache.h | 2 +-
combine-diff.c | 2 +-
commit.c | 2 +-
connect.c | 3 +-
convert-objects.c | 6 ++--
csum-file.c | 8 +++---
csum-file.h | 2 +-
diff-lib.c | 6 +++-
diff.c | 35 ++++++++++++++++++++++-----------
diffcore-break.c | 3 +-
diffcore.h | 6 +++-
fetch-pack.c | 3 +-
fetch.h | 4 +-
fsck-objects.c | 4 +-
git-archimport.perl | 4 +-
git-merge-one-file.sh | 6 ++--
git-svn.perl | 6 ++--
http-fetch.c | 8 ++++--
http-push.c | 7 +++--
index-pack.c | 22 ++++++++++----------
merge-tree.c | 8 +++---
mktag.c | 6 ++--
mktree.c | 7 +++--
object.c | 2 +-
pack-check.c | 8 +++---
patch-id.c | 2 +-
read-cache.c | 6 ++--
receive-pack.c | 2 +-
refs.c | 2 +-
setup.c | 2 +-
sha1_file.c | 16 +++++++-------
sha1_name.c | 2 +-
upload-pack.c | 4 +-
74 files changed, 303 insertions(+), 222 deletions(-)
diff --git a/Documentation/git-receive-pack.txt b/Documentation/git-receive-pack.txt
index 10e8c46..2fafc79 100644
--- a/Documentation/git-receive-pack.txt
+++ b/Documentation/git-receive-pack.txt
@@ -20,7 +20,7 @@ The UI for the protocol is on the 'git-send-pack' side, and the
program pair is meant to be used to push updates to remote
repository. For pull operations, see 'git-fetch-pack'.
-The command allows for creation and fast forwarding of sha1 refs
+The command allows for creation and fast forwarding of SHA-1 refs
(heads/tags) on the remote end (strictly speaking, it is the
local end receive-pack runs, but to the user who is sitting at
the send-pack end, it is updating the remote. Confused?)
@@ -30,12 +30,12 @@ and executable, it is called with three parameters:
$GIT_DIR/hooks/update refname sha1-old sha1-new
-The refname parameter is relative to $GIT_DIR; e.g. for the
-master head this is "refs/heads/master". Two sha1 are the
-object names for the refname before and after the update. Note
-that the hook is called before the refname is updated, so either
-sha1-old is 0{40} (meaning there is no such ref yet), or it
-should match what is recorded in refname.
+The refname parameter is relative to $GIT_DIR; e.g. for the master
+head this is "refs/heads/master". The two sha1 are the object names
+for the refname before and after the update. Note that the hook is
+called before the refname is updated, so either sha1-old is 0{40}
+(meaning there is no such ref yet), or it should match what is
+recorded in refname.
The hook should exit with non-zero status if it wants to
disallow updating the named ref. Otherwise it should exit with
diff --git a/Documentation/git-rev-parse.txt b/Documentation/git-rev-parse.txt
index aeb37b6..9363257 100644
--- a/Documentation/git-rev-parse.txt
+++ b/Documentation/git-rev-parse.txt
@@ -59,7 +59,7 @@ OPTIONS
one.
--symbolic::
- Usually the object names are output in SHA1 form (with
+ Usually the object names are output in SHA-1 form (with
possible '{caret}' prefix); this option makes them output in a
form as close to the original input as possible.
@@ -90,7 +90,7 @@ OPTIONS
Show `$GIT_DIR` if defined else show the path to the .git directory.
--short, --short=number::
- Instead of outputting the full SHA1 values of object names try to
+ Instead of outputting the full SHA-1 values of object names try to
abbreviate them to a shorter unique name. When no length is specified
7 is used. The minimum length is 4.
@@ -110,12 +110,12 @@ SPECIFYING REVISIONS
--------------------
A revision parameter typically, but not necessarily, names a
-commit object. They use what is called an 'extended SHA1'
+commit object. They use what is called an 'extended SHA-1'
syntax. Here are various ways to spell object names. The
ones listed near the end of this list are to name trees and
blobs contained in a commit.
-* The full SHA1 object name (40-byte hexadecimal string), or
+* The full SHA-1 object name (40-byte hexadecimal string), or
a substring of such that is unique within the repository.
E.g. dae86e1950b1277e545cee180551750029cfe735 and dae86e both
name the same commit object if there are no other object in
diff --git a/Documentation/git-show-branch.txt b/Documentation/git-show-branch.txt
index 529f3a6..5807884 100644
--- a/Documentation/git-show-branch.txt
+++ b/Documentation/git-show-branch.txt
@@ -29,7 +29,7 @@ no <rev> nor <glob> is given on the command line.
OPTIONS
-------
<rev>::
- Arbitrary extended SHA1 expression (see `git-rev-parse`)
+ Arbitrary extended SHA-1 expression (see `git-rev-parse`)
that typically names a branch HEAD or a tag.
<glob>::
@@ -119,7 +119,7 @@ displayed, indented N places. If a commit is on the I-th
branch, the I-th indentation character shows a `+` sign;
otherwise it shows a space. Merge commits are denoted by
a `-` sign. Each commit shows a short name that
-can be used as an extended SHA1 to name that commit.
+can be used as an extended SHA-1 to name that commit.
The following example shows three branches, "master", "fixes"
and "mhf":
diff --git a/Documentation/git-show-index.txt b/Documentation/git-show-index.txt
index be09b62..04f1d22 100644
--- a/Documentation/git-show-index.txt
+++ b/Documentation/git-show-index.txt
@@ -18,7 +18,7 @@ git-pack-objects command, and dumps its contents.
The information it outputs is subset of what you can get from
'git-verify-pack -v'; this command only shows the packfile
-offset and SHA1 of each object.
+offset and SHA-1 of each object.
Author
diff --git a/Documentation/git-show-ref.txt b/Documentation/git-show-ref.txt
index 5973a82..85aa106 100644
--- a/Documentation/git-show-ref.txt
+++ b/Documentation/git-show-ref.txt
@@ -42,8 +42,8 @@ OPTIONS
-s, --hash::
- Only show the SHA1 hash, not the reference name. When also using
- --dereference the dereferenced tag will still be shown after the SHA1.
+ Only show the SHA-1 hash, not the reference name. When also using
+ --dereference the dereferenced tag will still be shown after the SHA-1.
--verify::
diff --git a/Documentation/git-svn.txt b/Documentation/git-svn.txt
index b95ff1d..b4aeb5b 100644
--- a/Documentation/git-svn.txt
+++ b/Documentation/git-svn.txt
@@ -82,7 +82,7 @@ manually joining branches on commit.
New features:
- --show-commit - shows the git commit sha1, as well
+ --show-commit - shows the git commit SHA-1, as well
--oneline - our version of --pretty=oneline
Any other arguments are passed directly to `git log'
@@ -191,7 +191,7 @@ This can allow you to make partial mirrors when running fetch.
Only used with the 'set-tree' command.
Read a list of commits from stdin and commit them in reverse
-order. Only the leading sha1 is read from each line, so
+order. Only the leading SHA-1 is read from each line, so
git-rev-list --pretty=oneline output can be used.
--rmdir::
@@ -450,7 +450,7 @@ This is for advanced users, most users should ignore this section.
Unfetched SVN revisions may be imported as children of existing commits
by specifying additional arguments to 'fetch'. Additional parents may
-optionally be specified in the form of sha1 hex sums at the
+optionally be specified in the form of SHA-1 hex sums at the
command-line. Unfetched SVN revisions may also be tied to particular
git commits with the following syntax:
diff --git a/Documentation/git-tag.txt b/Documentation/git-tag.txt
index 13c7aef..d3e01fe 100644
--- a/Documentation/git-tag.txt
+++ b/Documentation/git-tag.txt
@@ -25,7 +25,7 @@ creates a 'tag' object, and requires the tag message. Unless
`-m <msg>` is given, an editor is started for the user to type
in the tag message.
-Otherwise just the SHA1 object name of the commit object is
+Otherwise just the SHA-1 object name of the commit object is
written (i.e. a lightweight tag).
A GnuPG signed tag object will be created when `-s` or `-u
diff --git a/Documentation/git-unpack-file.txt b/Documentation/git-unpack-file.txt
index 213dc81..c7b3be1 100644
--- a/Documentation/git-unpack-file.txt
+++ b/Documentation/git-unpack-file.txt
@@ -13,7 +13,7 @@ SYNOPSIS
DESCRIPTION
-----------
-Creates a file holding the contents of the blob specified by sha1. It
+Creates a file holding the contents of the blob specified by SHA-1. It
returns the name of the temporary file in the following format:
.merge_file_XXXXX
diff --git a/Documentation/git-update-index.txt b/Documentation/git-update-index.txt
index 5bbae42..9244460 100644
--- a/Documentation/git-update-index.txt
+++ b/Documentation/git-update-index.txt
@@ -129,7 +129,7 @@ OPTIONS
Using --refresh
---------------
-'--refresh' does not calculate a new sha1 file or bring the index
+'--refresh' does not calculate a new SHA-1 file or bring the index
up-to-date for mode/content changes. But what it *does* do is to
"re-match" the stat information of a file with the index, so that you
can refresh the index for a file that hasn't been changed but where
@@ -144,10 +144,10 @@ Using --cacheinfo or --info-only
current working directory. This is useful for minimum-checkout
merging.
-To pretend you have a file with mode and sha1 at path, say:
+To pretend you have a file with mode and SHA-1 at path, say:
----------------
-$ git-update-index --cacheinfo mode sha1 path
+$ git-update-index --cacheinfo mode SHA-1 path
----------------
'--info-only' is used to register files without placing them in the object
@@ -167,19 +167,19 @@ Using --index-info
multiple entry definitions from the standard input, and designed
specifically for scripts. It can take inputs of three formats:
- . mode SP sha1 TAB path
+ . mode SP SHA-1 TAB path
+
The first format is what "git-apply --index-info"
reports, and used to reconstruct a partial tree
that is used for phony merge base tree when falling
back on 3-way merge.
- . mode SP type SP sha1 TAB path
+ . mode SP type SP SHA-1 TAB path
+
The second format is to stuff git-ls-tree output
into the index file.
- . mode SP sha1 SP stage TAB path
+ . mode SP SHA-1 SP stage TAB path
+
This format is to put higher order stages into the
index file and matches git-ls-files --stage output.
@@ -205,7 +205,7 @@ $ git update-index --index-info
------------
The first line of the input feeds 0 as the mode to remove the
-path; the SHA1 does not matter as long as it is well formatted.
+path; the SHA-1 does not matter as long as it is well formatted.
Then the second and third line feeds stage 1 and stage 2 entries
for that path. After the above, we would end up with this:
diff --git a/Documentation/git-verify-pack.txt b/Documentation/git-verify-pack.txt
index 7a6132b..8eb8226 100644
--- a/Documentation/git-verify-pack.txt
+++ b/Documentation/git-verify-pack.txt
@@ -32,11 +32,11 @@ OUTPUT FORMAT
-------------
When specifying the -v option the format used is:
- SHA1 type size offset-in-packfile
+ SHA-1 type size offset-in-packfile
for objects that are not deltified in the pack, and
- SHA1 type size offset-in-packfile depth base-SHA1
+ SHA-1 type size offset-in-packfile depth base-SHA-1
for objects that are deltified.
diff --git a/Documentation/git-verify-tag.txt b/Documentation/git-verify-tag.txt
index 0f9bdb5..d610a8b 100644
--- a/Documentation/git-verify-tag.txt
+++ b/Documentation/git-verify-tag.txt
@@ -16,7 +16,7 @@ Validates the gpg signature created by git-tag.
OPTIONS
-------
<tag>::
- SHA1 identifier of a git tag object.
+ SHA-1 identifier of a git tag object.
Author
------
diff --git a/Documentation/git.txt b/Documentation/git.txt
index 9761de3..f359cf1 100644
--- a/Documentation/git.txt
+++ b/Documentation/git.txt
@@ -272,7 +272,7 @@ git so take care if using Cogito etc.
'GIT_OBJECT_DIRECTORY'::
If the object storage directory is specified via this
- environment variable then the sha1 directories are created
+ environment variable then the SHA-1 directories are created
underneath - otherwise the default `$GIT_DIR/objects`
directory is used.
@@ -317,7 +317,7 @@ where:
<old|new>-file:: are files GIT_EXTERNAL_DIFF can use to read the
contents of <old|new>,
- <old|new>-hex:: are the 40-hexdigit SHA1 hashes,
+ <old|new>-hex:: are the 40-hexdigit SHA-1 hashes,
<old|new>-mode:: are the octal representation of the file modes.
+
diff --git a/Documentation/glossary.txt b/Documentation/glossary.txt
index d20eb62..9cf8b19 100644
--- a/Documentation/glossary.txt
+++ b/Documentation/glossary.txt
@@ -163,7 +163,7 @@ merge::
object::
The unit of storage in git. It is uniquely identified by
- the SHA1 of its contents. Consequently, an object can not
+ the SHA-1 of its contents. Consequently, an object can not
be changed.
object database::
@@ -247,7 +247,7 @@ rebase::
changes from that branch.
ref::
- A 40-byte hex representation of a SHA1 or a name that denotes
+ A 40-byte hex representation of a SHA-1 or a name that denotes
a particular object. These may be stored in `$GIT_DIR/refs/`.
refspec::
@@ -283,7 +283,7 @@ rewind::
SCM::
Source code management (tool).
-SHA1::
+SHA-1::
Synonym for object name.
shallow repository::
@@ -299,7 +299,7 @@ shallow repository::
history can be later deepened with gitlink:git-fetch[1].
symref::
- Symbolic reference: instead of containing the SHA1 id itself, it
+ Symbolic reference: instead of containing the SHA-1 id itself, it
is of the format 'ref: refs/some/thing' and when referenced, it
recursively dereferences to this reference. 'HEAD' is a prime
example of a symref. Symbolic references are manipulated with
diff --git a/Documentation/pretty-formats.txt b/Documentation/pretty-formats.txt
index fb0b0b9..563f935 100644
--- a/Documentation/pretty-formats.txt
+++ b/Documentation/pretty-formats.txt
@@ -5,7 +5,7 @@
If the commit is a merge, and if the pretty-format
is not 'oneline', 'email' or 'raw', an additional line is
inserted before the 'Author:' line. This line begins with
- "Merge: " and the sha1s of ancestral commits are printed,
+ "Merge: " and the SHA-1s of ancestral commits are printed,
separated by spaces. Note that the listed commits may not
necessarily be the list of the *direct* parent commits if you
have limited your view of history: for example, if you are
@@ -14,20 +14,20 @@
* 'oneline'
- <sha1> <title line>
+ <SHA-1> <title line>
+
This is designed to be as compact as possible.
* 'short'
- commit <sha1>
+ commit <SHA-1>
Author: <author>
<title line>
* 'medium'
- commit <sha1>
+ commit <SHA-1>
Author: <author>
Date: <date>
@@ -37,7 +37,7 @@ This is designed to be as compact as possible.
* 'full'
- commit <sha1>
+ commit <SHA-1>
Author: <author>
Commit: <committer>
@@ -47,7 +47,7 @@ This is designed to be as compact as possible.
* 'fuller'
- commit <sha1>
+ commit <SHA-1>
Author: <author>
AuthorDate: <date & time>
Commit: <committer>
@@ -60,7 +60,7 @@ This is designed to be as compact as possible.
* 'email'
- From <sha1> <date>
+ From <SHA-1> <date>
From: <author>
Date: <date & time>
Subject: [PATCH] <title line>
@@ -71,7 +71,7 @@ This is designed to be as compact as possible.
* 'raw'
+
The 'raw' format shows the entire commit exactly as
-stored in the commit object. Notably, the SHA1s are
+stored in the commit object. Notably, the SHA-1s are
displayed in full, regardless of whether --abbrev or
--no-abbrev are used, and 'parents' information show the
true parent commits, without taking grafts nor history
diff --git a/Documentation/tutorial-2.txt b/Documentation/tutorial-2.txt
index f363d17..4b3f42d 100644
--- a/Documentation/tutorial-2.txt
+++ b/Documentation/tutorial-2.txt
@@ -33,14 +33,14 @@ What are the 40 digits of hex that git responded to the commit with?
We saw in part one of the tutorial that commits have names like this.
It turns out that every object in the git history is stored under
-such a 40-digit hex name. That name is the SHA1 hash of the object's
+such a 40-digit hex name. That name is the SHA-1 hash of the object's
contents; among other things, this ensures that git will never store
-the same data twice (since identical data is given an identical SHA1
+the same data twice (since identical data is given an identical SHA-1
name), and that the contents of a git object will never change (since
that would change the object's name as well).
It is expected that the content of the commit object you created while
-following the example above generates a different SHA1 hash than
+following the example above generates a different SHA-1 hash than
the one shown above because the commit object records the time when
it was created and the name of the person performing the commit.
@@ -64,14 +64,14 @@ A tree can refer to one or more "blob" objects, each corresponding to
a file. In addition, a tree can also refer to other tree objects,
thus creating a directory hierarchy. You can examine the contents of
any tree using ls-tree (remember that a long enough initial portion
-of the SHA1 will also work):
+of the SHA-1 will also work):
------------------------------------------------
$ git ls-tree 92b8b694
100644 blob 3b18e512dba79e4c8300dd08aeb37f8e728b8dad file.txt
------------------------------------------------
-Thus we see that this tree has one file in it. The SHA1 hash is a
+Thus we see that this tree has one file in it. The SHA-1 hash is a
reference to that file's data:
------------------------------------------------
@@ -90,7 +90,7 @@ Note that this is the old file data; so the object that git named in
its response to the initial tree was a tree with a snapshot of the
directory state that was recorded by the first commit.
-All of these objects are stored under their SHA1 names inside the git
+All of these objects are stored under their SHA-1 names inside the git
directory:
------------------------------------------------
@@ -126,7 +126,7 @@ ref: refs/heads/master
As you can see, this tells us which branch we're currently on, and it
tells us this by naming a file under the .git directory, which itself
-contains a SHA1 name referring to a commit object, which we can
+contains a SHA-1 name referring to a commit object, which we can
examine with cat-file:
------------------------------------------------
@@ -192,7 +192,7 @@ project's history:
Note, by the way, that lots of commands take a tree as an argument.
But as we can see above, a tree can be referred to in many different
-ways--by the SHA1 name for that tree, by the name of a commit that
+ways--by the SHA-1 name for that tree, by the name of a commit that
refers to the tree, by the name of a branch whose head refers to that
tree, etc.--and most such commands can accept any of these names.
diff --git a/builtin-apply.c b/builtin-apply.c
index 3fefdac..814f78f 100644
--- a/builtin-apply.c
+++ b/builtin-apply.c
@@ -1800,8 +1800,9 @@ static int apply_binary(struct buffer_desc *desc, struct patch *patch)
const char *name = patch->old_name ? patch->old_name : patch->new_name;
unsigned char sha1[20];
- /* For safety, we require patch index line to contain
- * full 40-byte textual SHA1 for old and new, at least for now.
+ /*
+ * For safety, we require patch index line to contain
+ * full 40-byte textual SHA-1 for old and new, at least for now.
*/
if (strlen(patch->old_sha1_prefix) != 40 ||
strlen(patch->new_sha1_prefix) != 40 ||
@@ -1811,7 +1812,8 @@ static int apply_binary(struct buffer_desc *desc, struct patch *patch)
"without full index line", name);
if (patch->old_name) {
- /* See if the old one matches what the patch
+ /*
+ * See if the old one matches what the patch
* applies to.
*/
hash_sha1_file(desc->buffer, desc->size, blob_type, sha1);
@@ -1850,7 +1852,8 @@ static int apply_binary(struct buffer_desc *desc, struct patch *patch)
desc->alloc = desc->size = size;
}
else {
- /* We have verified desc matches the preimage;
+ /*
+ * We have verified desc matches the preimage;
* apply the patch data to it, which is stored
* in the patch->fragments->{patch,size}.
*/
@@ -2074,8 +2077,9 @@ static void show_index_list(struct patch *list)
{
struct patch *patch;
- /* Once we start supporting the reverse patch, it may be
- * worth showing the new sha1 prefix, but until then...
+ /*
+ * Once we start supporting the reverse patch, it may be
+ * worth showing the new SHA-1 prefix, but until then...
*/
for (patch = list; patch; patch = patch->next) {
const unsigned char *sha1_ptr;
@@ -2086,7 +2090,7 @@ static void show_index_list(struct patch *list)
if (0 < patch->is_new)
sha1_ptr = null_sha1;
else if (get_sha1(patch->old_sha1_prefix, sha1))
- die("sha1 information is lacking or useless (%s).",
+ die("SHA-1 information is lacking or useless (%s).",
name);
else
sha1_ptr = sha1;
diff --git a/builtin-blame.c b/builtin-blame.c
index 4a1accf..9120b08 100644
--- a/builtin-blame.c
+++ b/builtin-blame.c
@@ -19,7 +19,7 @@ static char blame_usage[] =
"git-blame [-c] [-l] [-t] [-f] [-n] [-p] [-L n,m] [-S <revs-file>] [-M] [-C] [-C] [commit] [--] file\n"
" -c, --compatibility Use the same output mode as git-annotate (Default: off)\n"
" -b Show blank SHA-1 for boundary commits (Default: off)\n"
-" -l, --long Show long commit SHA1 (Default: off)\n"
+" -l, --long Show long commit SHA-1 (Default: off)\n"
" --root Do not treat root commits as boundaries (Default: off)\n"
" -t, --time Show raw timestamp (Default: off)\n"
" -f, --show-name Show original filename (Default: auto)\n"
@@ -244,7 +244,8 @@ static struct origin *find_origin(struct scoreboard *sb,
const char *paths[2];
if (parent->util) {
- /* This is a freestanding copy of origin and not
+ /*
+ * This is a freestanding copy of origin and not
* refcounted.
*/
struct origin *cached = parent->util;
@@ -259,7 +260,8 @@ static struct origin *find_origin(struct scoreboard *sb,
parent->util = NULL;
}
- /* See if the origin->path is different between parent
+ /*
+ * See if the origin->path is different between parent
* and origin first. Most of the time they are the
* same and diff-tree is fairly efficient about this.
*/
@@ -278,7 +280,8 @@ static struct origin *find_origin(struct scoreboard *sb,
"", &diff_opts);
diffcore_std(&diff_opts);
- /* It is either one entry that says "modified", or "created",
+ /*
+ * It is either one entry that says "modified", or "created",
* or nothing.
*/
if (!diff_queued_diff.nr) {
@@ -879,7 +882,8 @@ static int find_copy_in_parent(struct scoreboard *sb,
if (diff_setup_done(&diff_opts) < 0)
die("diff-setup");
- /* Try "find copies harder" on new path if requested;
+ /*
+ * Try "find copies harder" on new path if requested;
* we do not want to use diffcore_rename() actually to
* match things up; find_copies_harder is set only to
* force diff_tree_sha1() to feed all filepairs to diff_queue,
@@ -1205,7 +1209,8 @@ static void get_commit_info(struct commit *commit,
static char committer_buf[1024];
static char summary_buf[1024];
- /* We've operated without save_commit_buffer, so
+ /*
+ * We've operated without save_commit_buffer, so
* we now need to populate them for output.
*/
if (!commit->buffer) {
@@ -1863,7 +1868,8 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
add_pending_object(&revs, &(sb.final->object), "HEAD");
}
- /* If we have bottom, this will mark the ancestors of the
+ /*
+ * If we have bottom, this will mark the ancestors of the
* bottom commits we would reach while traversing as
* uninteresting.
*/
diff --git a/builtin-cat-file.c b/builtin-cat-file.c
index 6c16bfa..088cebf 100644
--- a/builtin-cat-file.c
+++ b/builtin-cat-file.c
@@ -66,7 +66,8 @@ static void pprint_tag(const unsigned char *sha1, const char *buf, unsigned long
/* end of header */
break;
}
- /* At this point, we have copied out the header up to the end of
+ /*
+ * At this point, we have copied out the header up to the end of
* the tagger line and cp points at one past \n. It could be the
* next header line after the tagger line, or it could be another
* \n that marks the end of the headers. We need to copy out the
@@ -86,7 +87,7 @@ int cmd_cat_file(int argc, const char **argv, const char *prefix)
git_config(git_default_config);
if (argc != 3)
- usage("git-cat-file [-t|-s|-e|-p|<type>] <sha1>");
+ usage("git-cat-file [-t|-s|-e|-p|<type>] <SHA-1>");
if (get_sha1(argv[2], sha1))
die("Not a valid object name %s", argv[2]);
diff --git a/builtin-commit-tree.c b/builtin-commit-tree.c
index 0651e59..8375395 100644
--- a/builtin-commit-tree.c
+++ b/builtin-commit-tree.c
@@ -63,7 +63,8 @@ static void check_valid(unsigned char *sha1, const char *expect)
#define MAXPARENT (16)
static unsigned char parent_sha1[MAXPARENT][20];
-static const char commit_tree_usage[] = "git-commit-tree <sha1> [-p <sha1>]* < changelog";
+static const char commit_tree_usage[] =
+ "git-commit-tree <sha1> [-p <sha1>]* < changelog";
static int new_parent(int idx)
{
diff --git a/builtin-describe.c b/builtin-describe.c
index e7b8f95..e2f97d6 100644
--- a/builtin-describe.c
+++ b/builtin-describe.c
@@ -48,7 +48,8 @@ static int get_name(const char *path, const unsigned char *sha1, int flag, void
if (!commit)
return 0;
object = parse_object(sha1);
- /* If --all, then any refs are used.
+ /*
+ * If --all, then any refs are used.
* If --tags, then any tags are used.
* Otherwise only annotated tags are used.
*/
diff --git a/builtin-diff-tree.c b/builtin-diff-tree.c
index 24cb2d7..339a1ff 100644
--- a/builtin-diff-tree.c
+++ b/builtin-diff-tree.c
@@ -53,10 +53,11 @@ static int diff_tree_stdin(char *line)
}
static const char diff_tree_usage[] =
-"git-diff-tree [--stdin] [-m] [-c] [--cc] [-s] [-v] [--pretty] [-t] [-r] [--root] "
-"[<common diff options>] <tree-ish> [<tree-ish>] [<path>...]\n"
-" -r diff recursively\n"
-" --root include the initial commit as diff against /dev/null\n"
+ "git-diff-tree [--stdin] [-m] [-c] [--cc] [-s] [-v] "
+ "[--pretty] [-t] [-r] [--root] "
+ "[<common diff options>] <tree-ish> [<tree-ish>] [<path>...]\n"
+ " -r diff recursively\n"
+ " --root include the initial commit as diff against /dev/null\n"
COMMON_DIFF_OPTIONS_HELP;
int cmd_diff_tree(int argc, const char **argv, const char *prefix)
diff --git a/builtin-diff.c b/builtin-diff.c
index a659020..c1a5f05 100644
--- a/builtin-diff.c
+++ b/builtin-diff.c
@@ -13,7 +13,8 @@
#include "log-tree.h"
#include "builtin.h"
-/* NEEDSWORK: struct object has place for name but we _do_
+/*
+ * NEEDSWORK: struct object has place for name but we _do_
* know mode when we extracted the blob out of a tree, which
* we currently lose.
*/
@@ -164,7 +165,8 @@ static int builtin_diff_tree(struct rev_info *revs,
if (argc > 1)
usage(builtin_diff_usage);
- /* We saw two trees, ent[0] and ent[1].
+ /*
+ * We saw two trees, ent[0] and ent[1].
* if ent[1] is uninteresting, they are swapped
*/
if (ent[1].item->flags & UNINTERESTING)
diff --git a/builtin-for-each-ref.c b/builtin-for-each-ref.c
index af72a12..ddaa95c 100644
--- a/builtin-for-each-ref.c
+++ b/builtin-for-each-ref.c
@@ -579,7 +579,8 @@ static void populate_value(struct refinfo *ref)
*/
tagged = ((struct tag *)obj)->tagged->sha1;
- /* NEEDSWORK: This derefs tag only once, which
+ /*
+ * NEEDSWORK: This derefs tag only once, which
* is good to deal with chains of trust, but
* is not consistent with what deref_tag() does
* which peels the onion to the core.
@@ -645,7 +646,8 @@ static int grab_single_ref(const char *refname, const unsigned char *sha1, int f
return 0;
}
- /* We do not open the object yet; sort may only need refname
+ /*
+ * We do not open the object yet; sort may only need refname
* to do its job and the resulting list may yet to be pruned
* by maxcount logic.
*/
diff --git a/builtin-init-db.c b/builtin-init-db.c
index 8e7540b..a169b4f 100644
--- a/builtin-init-db.c
+++ b/builtin-init-db.c
@@ -267,7 +267,7 @@ static const char init_db_usage[] =
/*
* If you want to, you can share the DB area with any number of branches.
- * That has advantages: you can save space by sharing all the SHA1 objects.
+ * That has advantages: you can save space by sharing all the SHA-1 objects.
* On the other hand, it might just make lookup slower and messier. You
* be the judge. The default case is to have one DB per managed directory.
*/
diff --git a/builtin-log.c b/builtin-log.c
index 503cd1e..55d6a13 100644
--- a/builtin-log.c
+++ b/builtin-log.c
@@ -396,7 +396,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
/*
* Parse the arguments before setup_revisions(), or something
* like "git fmt-patch -o a123 HEAD^.." may fail; a123 is
- * possibly a valid SHA1.
+ * possibly a valid SHA-1.
*/
for (i = 1, j = 1; i < argc; i++) {
if (!strcmp(argv[i], "--stdout"))
@@ -547,7 +547,8 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
free(commit->buffer);
commit->buffer = NULL;
- /* We put one extra blank line between formatted
+ /*
+ * We put one extra blank line between formatted
* patches and this flag is used by log-tree code
* to see if it needs to emit a LF before showing
* the log; when using one file per patch, we do
diff --git a/builtin-name-rev.c b/builtin-name-rev.c
index b4f15cc..c46eaf1 100644
--- a/builtin-name-rev.c
+++ b/builtin-name-rev.c
@@ -165,7 +165,7 @@ int cmd_name_rev(int argc, const char **argv, const char *prefix)
}
if (get_sha1(*argv, sha1)) {
- fprintf(stderr, "Could not get sha1 for %s. Skipping.\n",
+ fprintf(stderr, "Could not get SHA-1 for %s. Skipping.\n",
*argv);
continue;
}
diff --git a/builtin-pack-objects.c b/builtin-pack-objects.c
index 3824ee3..35d6bee 100644
--- a/builtin-pack-objects.c
+++ b/builtin-pack-objects.c
@@ -91,14 +91,14 @@ static int object_ix_hashsz;
* corresponding pack file where each object's data starts, but the entries
* do not store the size of the compressed representation (uncompressed
* size is easily available by examining the pack entry header). It is
- * also rather expensive to find the sha1 for an object given its offset.
+ * also rather expensive to find the SHA-1 for an object given its offset.
*
* We build a hashtable of existing packs (pack_revindex), and keep reverse
* index here -- pack index file is sorted by object name mapping to offset;
* this pack_revindex[].revindex array is a list of offset/index_nr pairs
* ordered by offset, so if you know the offset of an object, next offset
* is where its packed representation ends and the index_nr can be used to
- * get the object sha1 from the main index.
+ * get the object SHA-1 from the main index.
*/
struct revindex_entry {
unsigned int offset;
@@ -451,7 +451,7 @@ static unsigned long write_object(struct sha1file *f,
} else if (obj_type == OBJ_REF_DELTA) {
/*
* Deltas with a base reference contain
- * an additional 20 bytes for the base sha1.
+ * an additional 20 bytes for the base SHA-1.
*/
sha1write(f, entry->delta->sha1, 20);
hdrlen += 20;
@@ -590,7 +590,7 @@ static void write_index_file(void)
sha1write(f, array, 256 * 4);
/*
- * Write the actual SHA1 entries..
+ * Write the actual SHA-1 entries..
*/
list = sorted_by_sha;
for (i = 0; i < nr_result; i++) {
@@ -752,7 +752,8 @@ static int pbase_tree_cache_ix_incr(int ix)
static struct pbase_tree {
struct pbase_tree *next;
- /* This is a phony "cache" entry; we are not
+ /*
+ * This is a phony "cache" entry; we are not
* going to evict it nor find it through _get()
* mechanism -- this is for the toplevel node that
* would almost always change with any commit.
@@ -770,7 +771,8 @@ static struct pbase_tree_cache *pbase_tree_get(const unsigned char *sha1)
int my_ix = pbase_tree_cache_ix(sha1);
int available_ix = -1;
- /* pbase-tree-cache acts as a limited hashtable.
+ /*
+ * pbase-tree-cache acts as a limited hashtable.
* your object will be found at your index or within a few
* slots after that slot if it is cached.
*/
@@ -789,7 +791,8 @@ static struct pbase_tree_cache *pbase_tree_get(const unsigned char *sha1)
my_ix = pbase_tree_cache_ix_incr(my_ix);
}
- /* Did not find one. Either we got a bogus request or
+ /*
+ * Did not find one. Either we got a bogus request or
* we need to read and perhaps cache.
*/
data = read_sha1_file(sha1, type, &size);
@@ -1477,13 +1480,13 @@ static void read_object_list_from_stdin(void)
}
if (line[0] == '-') {
if (get_sha1_hex(line+1, sha1))
- die("expected edge sha1, got garbage:\n %s",
+ die("expected edge SHA-1, got garbage:\n %s",
line);
add_preferred_base(sha1);
continue;
}
if (get_sha1_hex(line, sha1))
- die("expected sha1, got garbage:\n %s", line);
+ die("expected SHA-1, got garbage:\n %s", line);
hash = name_hash(line+41);
add_preferred_base_object(line+41, hash);
diff --git a/builtin-prune.c b/builtin-prune.c
index 6f0ba0d..fbbf9e5 100644
--- a/builtin-prune.c
+++ b/builtin-prune.c
@@ -63,7 +63,7 @@ static int prune_dir(int i, char *path)
prune_object(path, de->d_name, sha1);
continue;
}
- fprintf(stderr, "bad sha1 file: %s/%s\n", path, de->d_name);
+ fprintf(stderr, "bad SHA-1 file: %s/%s\n", path, de->d_name);
}
closedir(dir);
return 0;
diff --git a/builtin-push.c b/builtin-push.c
index 5f4d7d3..3a98474 100644
--- a/builtin-push.c
+++ b/builtin-push.c
@@ -8,7 +8,9 @@
#define MAX_URI (16)
-static const char push_usage[] = "git-push [--all] [--tags] [--receive-pack=<git-receive-pack>] [--repo=all] [-f | --force] [-v] [<repository> <refspec>...]";
+static const char push_usage[] =
+ "git-push [--all] [--tags] [--receive-pack=<git-receive-pack>] "
+ "[--repo=all] [-f | --force] [-v] [<repository> <refspec>...]";
static int all, tags, force, thin = 1, verbose;
static const char *receivepack;
diff --git a/builtin-read-tree.c b/builtin-read-tree.c
index 8ba436d..db18a80 100644
--- a/builtin-read-tree.c
+++ b/builtin-read-tree.c
@@ -85,7 +85,11 @@ static void prime_cache_tree(void)
}
-static const char read_tree_usage[] = "git-read-tree (<sha> | [[-m [--aggressive] | --reset | --prefix=<prefix>] [-u | -i]] [--exclude-per-directory=<gitignore>] <sha1> [<sha2> [<sha3>]])";
+static const char read_tree_usage[] =
+ "git-read-tree (<sha> | "
+ "[[-m [--aggressive] | --reset | --prefix=<prefix>] "
+ "[-u | -i]] [--exclude-per-directory=<gitignore>] "
+ "<sha1> [<sha2> [<sha3>]])";
static struct lock_file lock_file;
diff --git a/builtin-reflog.c b/builtin-reflog.c
index b443ed9..c24716b 100644
--- a/builtin-reflog.c
+++ b/builtin-reflog.c
@@ -249,7 +249,8 @@ static int expire_reflog(const char *ref, const unsigned char *sha1, int unused,
return error("not a ref '%s'", ref);
memset(&cb, 0, sizeof(cb));
- /* we take the lock for the ref itself to prevent it from
+ /*
+ * We take the lock for the ref itself to prevent it from
* getting updated.
*/
lock = lock_ref_sha1(ref + 5, sha1);
diff --git a/builtin-rev-list.c b/builtin-rev-list.c
index 1bb3a06..b23707b 100644
--- a/builtin-rev-list.c
+++ b/builtin-rev-list.c
@@ -75,7 +75,8 @@ static void show_commit(struct commit *commit)
printf(" %s", sha1_to_hex(o->sha1));
o->flags |= TMP_MARK;
}
- /* TMP_MARK is a general purpose flag that can
+ /*
+ * TMP_MARK is a general purpose flag that can
* be used locally, but the user should clean
* things up after it is done with them.
*/
@@ -107,7 +108,8 @@ static void show_commit(struct commit *commit)
static void show_object(struct object_array_entry *p)
{
- /* An object with name "foo\n0000000..." can be used to
+ /*
+ * An object with name "foo\n0000000..." can be used to
* confuse downstream git-pack-objects very badly.
*/
const char *ep = strchr(p->name, '\n');
diff --git a/builtin-rm.c b/builtin-rm.c
index 00dbe39..78bd2f0 100644
--- a/builtin-rm.c
+++ b/builtin-rm.c
@@ -10,7 +10,7 @@
#include "tree-walk.h"
static const char builtin_rm_usage[] =
-"git-rm [-f] [-n] [-r] [--cached] [--] <file>...";
+ "git-rm [-f] [-n] [-r] [--cached] [--] <file>...";
static struct {
int nr, alloc;
@@ -48,7 +48,8 @@ static int remove_file(const char *name)
static int check_local_mod(unsigned char *head)
{
- /* items in list are already sorted in the cache order,
+ /*
+ * Items in list are already sorted in the cache order,
* so we could do this a lot more efficiently by using
* tree_desc based traversal if we wanted to, but I am
* lazy, and who cares if removal of files is a tad
@@ -79,7 +80,8 @@ static int check_local_mod(unsigned char *head)
continue;
}
else if (S_ISDIR(st.st_mode)) {
- /* if a file was removed and it is now a
+ /*
+ * If a file was removed and it is now a
* directory, that is the same as ENOENT as
* far as git is concerned; we do not track
* directories.
diff --git a/builtin-shortlog.c b/builtin-shortlog.c
index edb4042..19cf5b7 100644
--- a/builtin-shortlog.c
+++ b/builtin-shortlog.c
@@ -6,7 +6,7 @@
#include "revision.h"
static const char shortlog_usage[] =
-"git-shortlog [-n] [-s] [<commit-id>... ]";
+ "git-shortlog [-n] [-s] [<commit-id>... ]";
static char *common_repo_prefix;
diff --git a/builtin-show-branch.c b/builtin-show-branch.c
index b54c410..91e0e81 100644
--- a/builtin-show-branch.c
+++ b/builtin-show-branch.c
@@ -4,9 +4,13 @@
#include "builtin.h"
static const char show_branch_usage[] =
-"git-show-branch [--sparse] [--current] [--all] [--remotes] [--topo-order] [--more=count | --list | --independent | --merge-base ] [--topics] [<refs>...] | --reflog[=n[,b]] <branch>";
+ "git-show-branch [--sparse] [--current] [--all] [--remotes] "
+ "[--topo-order] "
+ "[--more=count | --list | --independent | --merge-base ] "
+ "[--topics] [<refs>...] | --reflog[=n[,b]] <branch>";
static const char show_branch_usage_reflog[] =
-"--reflog is incompatible with --all, --remotes, --independent or --merge-base";
+ "--reflog is incompatible with --all, --remotes, "
+ "--independent or --merge-base";
static int default_num;
static int default_alloc;
@@ -380,7 +384,8 @@ static int append_head_ref(const char *refname, const unsigned char *sha1, int f
int ofs = 11;
if (strncmp(refname, "refs/heads/", ofs))
return 0;
- /* If both heads/foo and tags/foo exists, get_sha1 would
+ /*
+ * If both heads/foo and tags/foo exists, get_sha1 would
* get confused.
*/
if (get_sha1(refname + ofs, tmp) || hashcmp(tmp, sha1))
@@ -394,7 +399,8 @@ static int append_remote_ref(const char *refname, const unsigned char *sha1, int
int ofs = 13;
if (strncmp(refname, "refs/remotes/", ofs))
return 0;
- /* If both heads/foo and tags/foo exists, get_sha1 would
+ /*
+ * If both heads/foo and tags/foo exists, get_sha1 would
* get confused.
*/
if (get_sha1(refname + ofs, tmp) || hashcmp(tmp, sha1))
@@ -422,7 +428,8 @@ static int count_slash(const char *s)
static int append_matching_ref(const char *refname, const unsigned char *sha1, int flag, void *cb_data)
{
- /* we want to allow pattern hold/<asterisk> to show all
+ /*
+ * We want to allow pattern hold/<asterisk> to show all
* branches under refs/heads/hold/, and v0.99.9? to show
* refs/tags/v0.99.9a and friends.
*/
@@ -528,7 +535,7 @@ static void append_one_rev(const char *av)
sort_ref_range(saved_matches, ref_name_cnt);
return;
}
- die("bad sha1 reference %s", av);
+ die("bad SHA-1 reference %s", av);
}
static int git_show_branch_config(const char *var, const char *value)
diff --git a/builtin-show-ref.c b/builtin-show-ref.c
index 853f13f..d7b9d8d 100644
--- a/builtin-show-ref.c
+++ b/builtin-show-ref.c
@@ -4,7 +4,10 @@
#include "tag.h"
#include "path-list.h"
-static const char show_ref_usage[] = "git show-ref [-q|--quiet] [--verify] [-h|--head] [-d|--dereference] [-s|--hash[=<length>]] [--abbrev[=<length>]] [--tags] [--heads] [--] [pattern*] < ref-list";
+static const char show_ref_usage[] =
+ "git show-ref [-q|--quiet] [--verify] [-h|--head] "
+ "[-d|--dereference] [-s|--hash[=<length>]] "
+ "[--abbrev[=<length>]] [--tags] [--heads] [--] [pattern*] < ref-list";
static int deref_tags = 0, show_head = 0, tags_only = 0, heads_only = 0,
found_match = 0, verify = 0, quiet = 0, hash_only = 0, abbrev = 0;
@@ -56,7 +59,8 @@ static int show_ref(const char *refname, const unsigned char *sha1, int flag, vo
match:
found_match++;
- /* This changes the semantics slightly that even under quiet we
+ /*
+ * This changes the semantics slightly that even under quiet we
* detect and return error if the repository is corrupt and
* ref points at a nonexistent object.
*/
diff --git a/builtin-unpack-objects.c b/builtin-unpack-objects.c
index d351e02..9a47437 100644
--- a/builtin-unpack-objects.c
+++ b/builtin-unpack-objects.c
@@ -395,7 +395,7 @@ int cmd_unpack_objects(int argc, const char **argv, const char *prefix)
SHA1_Update(&ctx, buffer, offset);
SHA1_Final(sha1, &ctx);
if (hashcmp(fill(20), sha1))
- die("final sha1 did not match");
+ die("final SHA-1 did not match");
use(20);
/* Write the last part of the buffer to stdout */
diff --git a/builtin-update-index.c b/builtin-update-index.c
index 182331d..10ed20b 100644
--- a/builtin-update-index.c
+++ b/builtin-update-index.c
@@ -111,7 +111,8 @@ static int add_file_to_cache(const char *path)
ce->ce_mode = create_ce_mode(st.st_mode);
if (!trust_executable_bit) {
- /* If there is an existing entry, pick the mode bits
+ /*
+ * If there is an existing entry, pick the mode bits
* from it, otherwise assume unexecutable.
*/
int pos = cache_name_pos(path, namelen);
@@ -228,19 +229,20 @@ static void read_index_info(int line_termination)
unsigned int mode;
int stage;
- /* This reads lines formatted in one of three formats:
+ /*
+ * This reads lines formatted in one of three formats:
*
- * (1) mode SP sha1 TAB path
+ * (1) mode SP SHA-1 TAB path
* The first format is what "git-apply --index-info"
* reports, and used to reconstruct a partial tree
* that is used for phony merge base tree when falling
* back on 3-way merge.
*
- * (2) mode SP type SP sha1 TAB path
+ * (2) mode SP type SP SHA-1 TAB path
* The second format is to stuff git-ls-tree output
* into the index file.
*
- * (3) mode SP sha1 SP stage TAB path
+ * (3) mode SP SHA-1 SP stage TAB path
* This format is to put higher order stages into the
* index file and matches git-ls-files --stage output.
*/
@@ -289,9 +291,10 @@ static void read_index_info(int line_termination)
ptr);
}
else {
- /* mode ' ' sha1 '\t' name
+ /*
+ * mode ' ' SHA-1 '\t' name
* ptr[-1] points at tab,
- * ptr[-41] is at the beginning of sha1
+ * ptr[-41] is at the beginning of SHA-1
*/
ptr[-42] = ptr[-1] = 0;
if (add_cacheinfo(mode, sha1, path_name, stage))
@@ -308,7 +311,11 @@ static void read_index_info(int line_termination)
}
static const char update_index_usage[] =
-"git-update-index [-q] [--add] [--replace] [--remove] [--unmerged] [--refresh] [--really-refresh] [--cacheinfo] [--chmod=(+|-)x] [--assume-unchanged] [--info-only] [--force-remove] [--stdin] [--index-info] [--unresolve] [--again | -g] [--ignore-missing] [-z] [--verbose] [--] <file>...";
+ "git-update-index [-q] [--add] [--replace] [--remove] "
+ "[--unmerged] [--refresh] [--really-refresh] [--cacheinfo] "
+ "[--chmod=(+|-)x] [--assume-unchanged] [--info-only] "
+ "[--force-remove] [--stdin] [--index-info] [--unresolve] "
+ "[--again | -g] [--ignore-missing] [-z] [--verbose] [--] <file>...";
static unsigned char head_sha1[20];
static unsigned char merge_head_sha1[20];
@@ -369,7 +376,8 @@ static int unresolve_one(const char *path)
}
}
- /* Grab blobs from given path from HEAD and MERGE_HEAD,
+ /*
+ * Grab blobs from given path from HEAD and MERGE_HEAD,
* stuff HEAD version in stage #2,
* stuff MERGE_HEAD version in stage #3.
*/
@@ -438,7 +446,8 @@ static int do_unresolve(int ac, const char **av,
static int do_reupdate(int ac, const char **av,
const char *prefix, int prefix_length)
{
- /* Read HEAD and run update-index on paths that are
+ /*
+ * Read HEAD and run update-index on paths that are
* merged and already different between index and HEAD.
*/
int pos;
@@ -446,7 +455,8 @@ static int do_reupdate(int ac, const char **av,
const char **pathspec = get_pathspec(prefix, av + 1);
if (read_ref("HEAD", head_sha1))
- /* If there is no HEAD, that means it is an initial
+ /*
+ * If there is no HEAD, that means it is an initial
* commit. Update everything in the index.
*/
has_head = 0;
@@ -466,7 +476,8 @@ static int do_reupdate(int ac, const char **av,
free(old);
continue; /* unchanged */
}
- /* Be careful. The working tree may not have the
+ /*
+ * Be careful. The working tree may not have the
* path anymore, in which case, under 'allow_remove',
* or worse yet 'allow_replace', active_nr may decrease.
*/
@@ -540,7 +551,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
unsigned int mode;
if (i+3 >= argc)
- die("git-update-index: --cacheinfo <mode> <sha1> <path>");
+ die("git-update-index: --cacheinfo <mode> <SHA-1> <path>");
if ((sscanf(argv[i+1], "%o", &mode) != 1) ||
get_sha1_hex(argv[i+2], sha1) ||
diff --git a/builtin-update-ref.c b/builtin-update-ref.c
index b34e598..ebd2a91 100644
--- a/builtin-update-ref.c
+++ b/builtin-update-ref.c
@@ -48,7 +48,7 @@ int cmd_update_ref(int argc, const char **argv, const char *prefix)
usage(git_update_ref_usage);
if (get_sha1(value, sha1))
- die("%s: not a valid SHA1", value);
+ die("%s: not a valid SHA-1", value);
if (delete) {
if (oldval)
@@ -58,7 +58,7 @@ int cmd_update_ref(int argc, const char **argv, const char *prefix)
hashclr(oldsha1);
if (oldval && *oldval && get_sha1(oldval, oldsha1))
- die("%s: not a valid old SHA1", oldval);
+ die("%s: not a valid old SHA-1", oldval);
lock = lock_any_ref_for_update(refname, oldval ? oldsha1 : NULL);
if (!lock)
diff --git a/builtin-write-tree.c b/builtin-write-tree.c
index 50670dc..7e58045 100644
--- a/builtin-write-tree.c
+++ b/builtin-write-tree.c
@@ -39,7 +39,8 @@ int write_tree(unsigned char *sha1, int missing_ok, const char *prefix)
&& !close(newfd))
commit_lock_file(lock_file);
}
- /* Not being able to write is fine -- we are only interested
+ /*
+ * Not being able to write is fine -- we are only interested
* in updating the cache-tree part, and if the next caller
* ends up using the old index with unupdated cache-tree part
* it misses the work we did here, but that is just a
diff --git a/cache-tree.c b/cache-tree.c
index 9b73c86..91da11d 100644
--- a/cache-tree.c
+++ b/cache-tree.c
@@ -167,13 +167,15 @@ static int verify_cache(struct cache_entry **cache,
if (funny)
return -1;
- /* Also verify that the cache does not have path and path/file
+ /*
+ * Also verify that the cache does not have path and path/file
* at the same time. At this point we know the cache has only
* stage 0 entries.
*/
funny = 0;
for (i = 0; i < entries - 1; i++) {
- /* path/file always comes after path because of the way
+ /*
+ * path/file always comes after path because of the way
* the cache is sorted. Also path can appear only once,
* which means conflicting one would immediately follow.
*/
@@ -387,7 +389,8 @@ static void *write_one(struct cache_tree *it,
{
int i;
- /* One "cache-tree" entry consists of the following:
+ /*
+ * One "cache-tree" entry consists of the following:
* path (NUL terminated)
* entry_count, subtree_nr ("%d %d\n")
* tree-sha1 (missing if invalid)
diff --git a/cache.h b/cache.h
index 473197d..fd2a659 100644
--- a/cache.h
+++ b/cache.h
@@ -214,7 +214,7 @@ extern int check_repository_format(void);
#define DATA_CHANGED 0x0020
#define TYPE_CHANGED 0x0040
-/* Return a statically allocated filename matching the sha1 signature */
+/* Return a statically allocated filename matching the SHA-1 signature */
extern char *mkpath(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
extern char *git_path(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
extern char *sha1_file_name(const unsigned char *sha1);
diff --git a/combine-diff.c b/combine-diff.c
index 29d0c9c..8ddee2f 100644
--- a/combine-diff.c
+++ b/combine-diff.c
@@ -835,7 +835,7 @@ static void show_raw_diff(struct combine_diff_path *p, int num_parent, struct re
}
printf("%s%06o", prefix, p->mode);
- /* Show sha1's */
+ /* Show SHA-1's */
for (i = 0; i < num_parent; i++)
printf(" %s", diff_unique_abbrev(p->parent[i].sha1,
opt->abbrev));
diff --git a/commit.c b/commit.c
index 9b2b842..14b05a1 100644
--- a/commit.c
+++ b/commit.c
@@ -292,7 +292,7 @@ int parse_commit_buffer(struct commit *item, void *buffer, unsigned long size)
item->tree = lookup_tree(parent);
if (item->tree)
n_refs++;
- bufptr += 46; /* "tree " + "hex sha1" + "\n" */
+ bufptr += 46; /* "tree " + "hex SHA-1" + "\n" */
pptr = &item->parents;
graft = lookup_commit_graft(item->object.sha1);
diff --git a/connect.c b/connect.c
index 7844888..51598f0 100644
--- a/connect.c
+++ b/connect.c
@@ -263,7 +263,8 @@ static int match_explicit_refs(struct ref *src, struct ref *dst,
case 1:
break;
case 0:
- /* The source could be in the get_sha1() format
+ /*
+ * The source could be in the get_sha1() format
* not a reference name. :refs/other is a
* way to delete 'other' ref at the remote end.
*/
diff --git a/convert-objects.c b/convert-objects.c
index a630132..1e02ffe 100644
--- a/convert-objects.c
+++ b/convert-objects.c
@@ -238,13 +238,13 @@ static void convert_date(void *buffer, unsigned long size, unsigned char *result
char *new = xmalloc(size + 100);
unsigned long newlen = 0;
- /* "tree <sha1>\n" */
+ /* "tree <SHA-1>\n" */
memcpy(new + newlen, buffer, 46);
newlen += 46;
buffer = (char *) buffer + 46;
size -= 46;
- /* "parent <sha1>\n" */
+ /* "parent <SHA-1>\n" */
while (!memcmp(buffer, "parent ", 7)) {
memcpy(new + newlen, buffer, 48);
newlen += 48;
@@ -273,7 +273,7 @@ static void convert_commit(void *buffer, unsigned long size, unsigned char *resu
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" */
+ buffer = (char *) buffer + 46; /* "tree " + "hex SHA-1" + "\n" */
while (!memcmp(buffer, "parent ", 7)) {
convert_ascii_sha1((char *) buffer + 7);
buffer = (char *) buffer + 48;
diff --git a/csum-file.c b/csum-file.c
index b7174c6..a3fbecd 100644
--- a/csum-file.c
+++ b/csum-file.c
@@ -3,7 +3,7 @@
*
* Copyright (C) 2005 Linus Torvalds
*
- * Simple file write infrastructure for writing SHA1-summed
+ * Simple file write infrastructure for writing SHA-1-summed
* files. Useful when you write a file that you want to be
* able to verify hasn't been messed with afterwards.
*/
@@ -24,8 +24,8 @@ static void sha1flush(struct sha1file *f, unsigned int count)
return;
}
if (!ret)
- die("sha1 file '%s' write error. Out of diskspace", f->name);
- die("sha1 file '%s' write error (%s)", f->name, strerror(errno));
+ die("SHA-1 file '%s' write error. Out of diskspace", f->name);
+ die("SHA-1 file '%s' write error (%s)", f->name, strerror(errno));
}
}
@@ -42,7 +42,7 @@ int sha1close(struct sha1file *f, unsigned char *result, int update)
if (update)
sha1flush(f, 20);
if (close(f->fd))
- die("%s: sha1 file error on close (%s)", f->name, strerror(errno));
+ die("%s: SHA-1 file error on close (%s)", f->name, strerror(errno));
free(f);
return 0;
}
diff --git a/csum-file.h b/csum-file.h
index 3ad1a99..4f2b7ec 100644
--- a/csum-file.h
+++ b/csum-file.h
@@ -1,7 +1,7 @@
#ifndef CSUM_FILE_H
#define CSUM_FILE_H
-/* A SHA1-protected file */
+/* A SHA-1-protected file */
struct sha1file {
int fd, error;
unsigned int offset, namelen;
diff --git a/diff-lib.c b/diff-lib.c
index 2c9be60..8877649 100644
--- a/diff-lib.c
+++ b/diff-lib.c
@@ -188,7 +188,8 @@ static void show_new_file(struct rev_info *revs,
unsigned char *sha1;
unsigned int mode;
- /* New file in the index: it might actually be different in
+ /*
+ * New file in the index: it might actually be different in
* the working copy.
*/
if (get_stat_data(new, &sha1, &mode, cached, match_missing) < 0)
@@ -283,7 +284,8 @@ static int diff_cache(struct rev_info *revs,
ce->sha1, ce->ce_mode);
break;
}
- /* We come here with ce pointing at stage 1
+ /*
+ * We come here with ce pointing at stage 1
* (original tree) and ac[1] pointing at stage
* 3 (unmerged). show-modified with
* report-missing set to false does not say the
diff --git a/diff.c b/diff.c
index ad476f7..745bbc9 100644
--- a/diff.c
+++ b/diff.c
@@ -1196,7 +1196,8 @@ static int reuse_worktree_file(const char *name, const unsigned char *sha1, int
struct stat st;
int pos, len;
- /* We do not read the cache ourselves here, because the
+ /*
+ * We do not read the cache ourselves here, because the
* benchmark with my previous version that always reads cache
* shows that it makes things worse for diff-tree comparing
* two linux-2.6 kernel trees in an already checked out work
@@ -1211,7 +1212,8 @@ static int reuse_worktree_file(const char *name, const unsigned char *sha1, int
if (!active_cache)
return 0;
- /* We want to avoid the working directory if our caller
+ /*
+ * We want to avoid the working directory if our caller
* doesn't need the data in a normal file, this system
* is rather slow with its stat/open/mmap/close syscalls,
* and the object is contained in a pack file. The pack
@@ -1233,7 +1235,8 @@ static int reuse_worktree_file(const char *name, const unsigned char *sha1, int
ce_match_stat(ce, &st, 0) ||
hashcmp(sha1, ce->sha1))
return 0;
- /* we return 1 only when we can stat, it is a regular file,
+ /*
+ * We return 1 only when we can stat, it is a regular file,
* stat information matches, and sha1 recorded in the cache
* matches. I.e. we know the file in the work tree really is
* the same as the <name, sha1> pair.
@@ -1442,7 +1445,8 @@ static void prepare_temp_file(const char *name,
strcpy(temp->hex, sha1_to_hex(null_sha1));
else
strcpy(temp->hex, sha1_to_hex(one->sha1));
- /* Even though we may sometimes borrow the
+ /*
+ * Even though we may sometimes borrow the
* contents from the work tree, we always want
* one->mode. mode is trustworthy even when
* !(one->sha1_valid), as long as
@@ -1498,7 +1502,8 @@ static int spawn_prog(const char *pgm, const char **arg)
return -1;
}
- /* Earlier we did not check the exit status because
+ /*
+ * Earlier we did not check the exit status because
* diff exits non-zero if files are different, and
* we are not interested in knowing that. It was a
* mistake which made it harder to quit a diff-*
@@ -1512,7 +1517,8 @@ static int spawn_prog(const char *pgm, const char **arg)
return -1;
}
-/* An external diff command takes:
+/*
+ * An external diff command takes:
*
* diff-cmd name infile1 infile1-sha1 infile1-mode \
* infile2 infile2-sha1 infile2-mode [ rename-to ]
@@ -2204,7 +2210,8 @@ static void diff_flush_name(struct diff_filepair *p, int line_termination)
int diff_unmodified_pair(struct diff_filepair *p)
{
- /* This function is written stricter than necessary to support
+ /*
+ * This function is written stricter than necessary to support
* the currently implemented transformers, but the idea is to
* let transformers to produce diff_filepairs any way they want,
* and filter and clean them up here before producing the output.
@@ -2217,7 +2224,8 @@ int diff_unmodified_pair(struct diff_filepair *p)
one = p->one;
two = p->two;
- /* deletion, addition, mode or type change
+ /*
+ * deletion, addition, mode or type change
* and rename are all interesting.
*/
if (DIFF_FILE_VALID(one) != DIFF_FILE_VALID(two) ||
@@ -2225,7 +2233,8 @@ int diff_unmodified_pair(struct diff_filepair *p)
strcmp(one->path, two->path))
return 0;
- /* both are valid and point at the same path. that is, we are
+ /*
+ * both are valid and point at the same path. that is, we are
* dealing with a change.
*/
if (one->sha1_valid && two->sha1_valid &&
@@ -2372,7 +2381,8 @@ static void diff_resolve_rename_copy(void)
p->one->mode != p->two->mode)
p->status = DIFF_STATUS_MODIFIED;
else {
- /* This is a "no-change" entry and should not
+ /*
+ * This is a "no-change" entry and should not
* happen anymore, but prepare for broken callers.
*/
error("feeding unmodified %s to diffcore",
@@ -2510,7 +2520,7 @@ static void patch_id_consume(void *priv, char *line, unsigned long len)
struct patch_id_t *data = priv;
int new_len;
- /* Ignore line numbers when computing the SHA1 of the patch */
+ /* Ignore line numbers when computing the SHA-1 of the patch */
if (!strncmp(line, "@@ -", 4))
return;
@@ -2818,7 +2828,8 @@ void diff_addremove(struct diff_options *options,
char concatpath[PATH_MAX];
struct diff_filespec *one, *two;
- /* This may look odd, but it is a preparation for
+ /*
+ * This may look odd, but it is a preparation for
* feeding "there are unchanged files which should
* not produce diffs, but when you are doing copy
* detection you would need them, so here they are"
diff --git a/diffcore-break.c b/diffcore-break.c
index acb18db..eacc9d0 100644
--- a/diffcore-break.c
+++ b/diffcore-break.c
@@ -10,7 +10,8 @@ static int should_break(struct diff_filespec *src,
int break_score,
int *merge_score_p)
{
- /* dst is recorded as a modification of src. Are they so
+ /*
+ * dst is recorded as a modification of src. Are they so
* different that we are better off recording this as a pair
* of delete and create?
*
diff --git a/diffcore.h b/diffcore.h
index 1ea8067..fc71323 100644
--- a/diffcore.h
+++ b/diffcore.h
@@ -4,12 +4,14 @@
#ifndef _DIFFCORE_H_
#define _DIFFCORE_H_
-/* This header file is internal between diff.c and its diff transformers
+/*
+ * This header file is internal between diff.c and its diff transformers
* (e.g. diffcore-rename, diffcore-pickaxe). Never include this header
* in anything else.
*/
-/* We internally use unsigned short as the score value,
+/*
+ * We internally use unsigned short as the score value,
* and rely on an int capable to hold 32-bits. -B can take
* -Bmerge_score/break_score format and the two scores are
* passed around in one int (high 16-bit for merge and low 16-bit
diff --git a/fetch-pack.c b/fetch-pack.c
index 726140a..fc48577 100644
--- a/fetch-pack.c
+++ b/fetch-pack.c
@@ -584,7 +584,8 @@ static int fetch_pack(int fd[2], int nr_match, char **match)
}
if (find_common(fd, sha1, ref) < 0)
if (keep_pack != 1)
- /* When cloning, it is not unusual to have
+ /*
+ * When cloning, it is not unusual to have
* no common commit.
*/
fprintf(stderr, "warning: no common commits\n");
diff --git a/fetch.h b/fetch.h
index be48c6f..ee8a5d8 100644
--- a/fetch.h
+++ b/fetch.h
@@ -2,7 +2,7 @@
#define PULL_H
/*
- * Fetch object given SHA1 from the remote, and store it locally under
+ * Fetch object given SHA-1 from the remote, and store it locally under
* GIT_OBJECT_DIRECTORY. Return 0 on success, -1 on failure. To be
* provided by the particular implementation.
*/
@@ -17,7 +17,7 @@ extern void prefetch(unsigned char *sha1);
/*
* Fetch ref (relative to $GIT_DIR/refs) from the remote, and store
- * the 20-byte SHA1 in sha1. Return 0 on success, -1 on failure. To
+ * the 20-byte SHA-1 in sha1. Return 0 on success, -1 on failure. To
* be provided by the particular implementation.
*/
extern int fetch_ref(char *ref, unsigned char *sha1);
diff --git a/fsck-objects.c b/fsck-objects.c
index ecfb014..cc17788 100644
--- a/fsck-objects.c
+++ b/fsck-objects.c
@@ -449,7 +449,7 @@ static void fsck_dir(int i, char *path)
add_sha1_list(sha1, DIRENT_SORT_HINT(de));
continue;
}
- fprintf(stderr, "bad sha1 file: %s/%s\n", path, de->d_name);
+ fprintf(stderr, "bad SHA-1 file: %s/%s\n", path, de->d_name);
}
closedir(dir);
}
@@ -656,7 +656,7 @@ int main(int argc, char **argv)
heads++;
continue;
}
- error("invalid parameter: expected sha1, got '%s'", arg);
+ error("invalid parameter: expected SHA-1, got '%s'", arg);
}
/*
diff --git a/git-archimport.perl b/git-archimport.perl
index 2e15781..a24ec8f 100755
--- a/git-archimport.perl
+++ b/git-archimport.perl
@@ -105,7 +105,7 @@ my %stats = ( # Track which strategy we used to import:
);
my %rptags = (); # my reverse private tags
- # to map a SHA1 to a commitid
+ # to map a SHA-1 to a commitid
my $TLA = $ENV{'ARCH_CLIENT'} || 'tla';
sub do_abrowse {
@@ -1013,7 +1013,7 @@ sub git_rev_parse {
return $val;
}
-# resolve a SHA1 to a known patchset
+# resolve a SHA-1 to a known patchset
sub commitid2pset {
my $commitid = shift;
chomp $commitid;
diff --git a/git-merge-one-file.sh b/git-merge-one-file.sh
index 7d62d79..f134d02 100755
--- a/git-merge-one-file.sh
+++ b/git-merge-one-file.sh
@@ -4,9 +4,9 @@
#
# This is the git per-file merge script, called with
#
-# $1 - original file SHA1 (or empty)
-# $2 - file in branch1 SHA1 (or empty)
-# $3 - file in branch2 SHA1 (or empty)
+# $1 - original file SHA-1 (or empty)
+# $2 - file in branch1 SHA-1 (or empty)
+# $3 - file in branch2 SHA-1 (or empty)
# $4 - pathname in repository
# $5 - original file mode (or empty)
# $6 - file in branch1 mode (or empty)
diff --git a/git-svn.perl b/git-svn.perl
index 83ec03d..d27a90b 100755
--- a/git-svn.perl
+++ b/git-svn.perl
@@ -240,7 +240,7 @@ sub rebuild {
while (<$rev_list>) {
chomp;
my $c = $_;
- croak "Non-SHA1: $c\n" unless $c =~ /^$sha1$/o;
+ croak "Non-SHA-1: $c\n" unless $c =~ /^$sha1$/o;
my @commit = grep(/^git-svn-id: /,
command(qw/cat-file commit/, $c));
next if (!@commit); # skip merges
@@ -2534,7 +2534,7 @@ sub libsvn_skip_unknown_revs {
# And yes, it's still pretty fast (faster than Tie::File).
sub revdb_set {
my ($file, $rev, $commit) = @_;
- length $commit == 40 or croak "arg3 must be a full SHA1 hexsum\n";
+ length $commit == 40 or croak "arg3 must be a full SHA-1 hexsum\n";
open my $fh, '+<', $file or croak $!;
my $offset = $rev * 41;
# assume that append is the common case:
@@ -2754,7 +2754,7 @@ sub close_file {
chomp($hash = do { local $/; <$out> });
close $out or croak $!;
close $fh or croak $!;
- $hash =~ /^[a-f\d]{40}$/ or die "not a sha1: $hash\n";
+ $hash =~ /^[a-f\d]{40}$/ or die "not a SHA-1: $hash\n";
close $fb->{base} or croak $!;
} else {
$hash = $fb->{blob} or die "no blob information\n";
diff --git a/http-fetch.c b/http-fetch.c
index 67dfb0a..bafb0be 100644
--- a/http-fetch.c
+++ b/http-fetch.c
@@ -191,7 +191,7 @@ static void start_object_request(struct object_request *obj_req)
}
unlink(prevfile);
- /* Reset inflate/SHA1 if there was an error reading the previous temp
+ /* Reset inflate/SHA-1 if there was an error reading the previous temp
file; also rewind to the beginning of the local file. */
if (prev_read == -1) {
memset(&obj_req->stream, 0, sizeof(obj_req->stream));
@@ -417,8 +417,10 @@ static int fetch_index(struct alt_base *repo, unsigned char *sha1)
curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, no_pragma_header);
slot->local = indexfile;
- /* If there is data present from a previous transfer attempt,
- resume where it left off */
+ /*
+ * If there is data present from a previous transfer attempt,
+ * resume where it left off
+ */
prev_posn = ftell(indexfile);
if (prev_posn>0) {
if (get_verbosely)
diff --git a/http-push.c b/http-push.c
index 0a15f53..387c849 100644
--- a/http-push.c
+++ b/http-push.c
@@ -304,7 +304,7 @@ static void start_fetch_loose(struct transfer_request *request)
}
unlink(prevfile);
- /* Reset inflate/SHA1 if there was an error reading the previous temp
+ /* Reset inflate/SHA-1 if there was an error reading the previous temp
file; also rewind to the beginning of the local file. */
if (prev_read == -1) {
memset(&request->stream, 0, sizeof(request->stream));
@@ -2167,7 +2167,7 @@ static void fetch_symref(const char *path, char **symref, unsigned char *sha1)
if (buffer.posn == 0)
return;
- /* If it's a symref, set the refname; otherwise try for a sha1 */
+ /* If it's a symref, set the refname; otherwise try for a SHA-1 */
if (!strncmp((char *)buffer.buffer, "ref: ", 5)) {
*symref = xmalloc(buffer.posn - 5);
strlcpy(*symref, (char *)buffer.buffer + 5, buffer.posn - 5);
@@ -2426,7 +2426,8 @@ int main(int argc, char **argv)
if (!has_sha1_file(ref->old_sha1) ||
!ref_newer(ref->peer_ref->new_sha1,
ref->old_sha1)) {
- /* We do not have the remote ref, or
+ /*
+ * We do not have the remote ref, or
* we know that the remote ref is not
* an ancestor of what we are trying to
* push. Either way this can be losing
diff --git a/index-pack.c b/index-pack.c
index 72e0962..f718439 100644
--- a/index-pack.c
+++ b/index-pack.c
@@ -413,7 +413,7 @@ static int compare_delta_entry(const void *a, const void *b)
return memcmp(&delta_a->base, &delta_b->base, UNION_BASE_SZ);
}
-/* Parse all objects and return the pack content SHA1 hash */
+/* Parse all objects and return the pack content SHA-1 hash */
static void parse_pack_objects(unsigned char *sha1)
{
int i, percent = -1;
@@ -424,8 +424,8 @@ static void parse_pack_objects(unsigned char *sha1)
/*
* First pass:
* - find locations of all objects;
- * - calculate SHA1 of all non-delta objects;
- * - remember base (SHA1 or offset) for all deltas.
+ * - calculate SHA-1 of all non-delta objects;
+ * - remember base (SHA-1 or offset) for all deltas.
*/
if (verbose)
fprintf(stderr, "Indexing %d objects.\n", nr_objects);
@@ -451,7 +451,7 @@ static void parse_pack_objects(unsigned char *sha1)
flush();
SHA1_Final(sha1, &input_ctx);
if (hashcmp(fill(20), sha1))
- die("pack is corrupted (SHA1 mismatch)");
+ die("pack is corrupted (SHA-1 mismatch)");
use(20);
/* If input_fd is a file, we should have reached its end now. */
@@ -463,7 +463,7 @@ static void parse_pack_objects(unsigned char *sha1)
if (!nr_deltas)
return;
- /* Sort deltas by base SHA1/offset for fast searching */
+ /* Sort deltas by base SHA-1/offset for fast searching */
qsort(deltas, nr_deltas, sizeof(struct delta_entry),
compare_delta_entry);
@@ -647,7 +647,7 @@ static void readjust_pack_header_and_sha1(unsigned char *sha1)
if (lseek(output_fd, 0, SEEK_SET) != 0)
die("cannot seek back: %s", strerror(errno));
- /* Recompute and store the new pack's SHA1 */
+ /* Recompute and store the new pack's SHA-1 */
SHA1_Init(&ctx);
do {
unsigned char *buf[4096];
@@ -668,8 +668,8 @@ static int sha1_compare(const void *_a, const void *_b)
}
/*
- * On entry *sha1 contains the pack content SHA1 hash, on exit it is
- * the SHA1 hash of sorted object names.
+ * On entry *sha1 contains the pack content SHA-1 hash, on exit it is
+ * the SHA-1 hash of sorted object names.
*/
static const char *write_index_file(const char *index_name, unsigned char *sha1)
{
@@ -725,13 +725,13 @@ static const char *write_index_file(const char *index_name, unsigned char *sha1)
}
sha1write(f, array, 256 * sizeof(int));
- /* recompute the SHA1 hash of sorted object names.
+ /* recompute the SHA-1 hash of sorted object names.
* currently pack-objects does not do this, but that
* can be fixed.
*/
SHA1_Init(&ctx);
/*
- * Write the actual SHA1 entries..
+ * Write the actual SHA-1 entries..
*/
list = sorted_by_sha;
for (i = 0; i < nr_objects; i++) {
@@ -931,7 +931,7 @@ int main(int argc, char **argv)
die("pack has %d unresolved deltas",
nr_deltas - nr_resolved_deltas);
} else {
- /* Flush remaining pack final 20-byte SHA1. */
+ /* Flush remaining pack final 20-byte SHA-1. */
flush();
}
free(deltas);
diff --git a/merge-tree.c b/merge-tree.c
index 692ede0..72c9835 100644
--- a/merge-tree.c
+++ b/merge-tree.c
@@ -274,14 +274,14 @@ static void unresolved(const char *base, struct name_entry n[3])
*
* The output will be either:
* - successful merge
- * "0 mode sha1 filename"
+ * "0 mode SHA-1 filename"
* NOTE NOTE NOTE! FIXME! We really really need to walk the index
* in parallel with this too!
*
* - conflict:
- * "1 mode sha1 filename"
- * "2 mode sha1 filename"
- * "3 mode sha1 filename"
+ * "1 mode SHA-1 filename"
+ * "2 mode SHA-1 filename"
+ * "3 mode SHA-1 filename"
* where not all of the 1/2/3 lines may exist, of course.
*
* The successful merge rules are the same as for the three-way merge
diff --git a/mktag.c b/mktag.c
index 3448a5d..d9ae24c 100644
--- a/mktag.c
+++ b/mktag.c
@@ -3,13 +3,13 @@
/*
* A signature file has a very simple fixed format: four lines
- * of "object <sha1>" + "type <typename>" + "tag <tagname>" +
+ * of "object <SHA-1>" + "type <typename>" + "tag <tagname>" +
* "tagger <committer>", followed by a blank line, a free-form tag
* message and a signature block that git itself doesn't care about,
* but that can be verified with gpg or similar.
*
* The first three lines are guaranteed to be at least 63 bytes:
- * "object <sha1>\n" is 48 bytes, "type tag\n" at 9 bytes is the
+ * "object <SHA-1>\n" is 48 bytes, "type tag\n" at 9 bytes is the
* shortest possible type-line, and "tag .\n" at 6 bytes is the
* shortest single-character-tag line.
*
@@ -133,7 +133,7 @@ int main(int argc, char **argv)
}
/* Verify it for some basic sanity: it needs to start with
- "object <sha1>\ntype\ntagger " */
+ "object <SHA-1>\ntype\ntagger " */
if (verify_tag(buffer, size) < 0)
die("invalid tag signature file");
diff --git a/mktree.c b/mktree.c
index 56205d1..08de0d0 100644
--- a/mktree.c
+++ b/mktree.c
@@ -103,8 +103,9 @@ int main(int ac, char **av)
break;
len = sb.len;
ptr = sb.buf;
- /* Input is non-recursive ls-tree output format
- * mode SP type SP sha1 TAB name
+ /*
+ * Input is non-recursive ls-tree output format
+ * mode SP type SP SHA-1 TAB name
*/
mode = strtoul(ptr, &ntr, 8);
if (ptr == ntr || !ntr || *ntr != ' ')
@@ -117,7 +118,7 @@ int main(int ac, char **av)
die("input format error: %s", sb.buf);
if (sha1_object_info(sha1, type, NULL))
die("object %s unavailable", sha1_to_hex(sha1));
- *ntr++ = 0; /* now at the beginning of SHA1 */
+ *ntr++ = 0; /* now at the beginning of SHA-1 */
if (strcmp(ptr, type))
die("object type %s mismatch (%s)", ptr, type);
ntr += 41; /* at the beginning of name */
diff --git a/object.c b/object.c
index de244e2..05afc52 100644
--- a/object.c
+++ b/object.c
@@ -183,7 +183,7 @@ struct object *parse_object(const unsigned char *sha1)
if (buffer) {
struct object *obj;
if (check_sha1_signature(sha1, buffer, size, type) < 0)
- printf("sha1 mismatch %s\n", sha1_to_hex(sha1));
+ printf("SHA-1 mismatch %s\n", sha1_to_hex(sha1));
obj = parse_object_buffer(sha1, type, size, buffer, &eaten);
if (!eaten)
diff --git a/pack-check.c b/pack-check.c
index 08a9fd8..d735d8b 100644
--- a/pack-check.c
+++ b/pack-check.c
@@ -28,10 +28,10 @@ static int verify_packfile(struct packed_git *p,
}
SHA1_Final(sha1, &ctx);
if (hashcmp(sha1, use_pack(p, w_curs, pack_sig, NULL)))
- return error("Packfile %s SHA1 mismatch with itself",
+ return error("Packfile %s SHA-1 mismatch with itself",
p->pack_name);
if (hashcmp(sha1, (unsigned char *)index_base + index_size - 40))
- return error("Packfile %s SHA1 mismatch with idx",
+ return error("Packfile %s SHA-1 mismatch with idx",
p->pack_name);
unuse_pack(w_curs);
@@ -130,12 +130,12 @@ int verify_pack(struct packed_git *p, int verbose)
int ret;
ret = 0;
- /* Verify SHA1 sum of the index file */
+ /* Verify SHA-1 sum of the index file */
SHA1_Init(&ctx);
SHA1_Update(&ctx, index_base, index_size - 20);
SHA1_Final(sha1, &ctx);
if (hashcmp(sha1, (unsigned char *)index_base + index_size - 20))
- ret = error("Packfile index for %s SHA1 mismatch",
+ ret = error("Packfile index for %s SHA-1 mismatch",
p->pack_name);
if (!ret) {
diff --git a/patch-id.c b/patch-id.c
index 086d2d9..f036c78 100644
--- a/patch-id.c
+++ b/patch-id.c
@@ -60,7 +60,7 @@ static void generate_id_list(void)
if (!memcmp(line, "index ", 6))
continue;
- /* Ignore line numbers when computing the SHA1 of the patch */
+ /* Ignore line numbers when computing the SHA-1 of the patch */
if (!memcmp(line, "@@ -", 4))
continue;
diff --git a/read-cache.c b/read-cache.c
index c54a611..2647e96 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -227,7 +227,7 @@ int ce_modified(struct cache_entry *ce, struct stat *st, int really)
/* Immediately after read-tree or update-index --cacheinfo,
* the length field is zero. For other cases the ce_size
- * should match the SHA1 recorded in the index entry.
+ * should match the SHA-1 recorded in the index entry.
*/
if ((changed & DATA_CHANGED) && ce->ce_size != htonl(0))
return changed;
@@ -630,7 +630,7 @@ int add_cache_entry(struct cache_entry *ce, int option)
}
/*
- * "refresh" does not calculate a new sha1 file or bring the
+ * "refresh" does not calculate a new SHA-1 file or bring the
* cache up-to-date for mode/content changes. But what it
* _does_ do is to "re-match" the stat information of a file
* with the cache, so that you can refresh the cache for a
@@ -924,7 +924,7 @@ static int ce_flush(SHA_CTX *context, int fd)
left = 0;
}
- /* Append the SHA1 signature at the end */
+ /* Append the SHA-1 signature at the end */
SHA1_Final(write_buffer + left, context);
left += 20;
return (write_in_full(fd, write_buffer, left) != left) ? -1 : 0;
diff --git a/receive-pack.c b/receive-pack.c
index 6333f00..301738c 100644
--- a/receive-pack.c
+++ b/receive-pack.c
@@ -340,7 +340,7 @@ static const char *unpack(void)
/*
* The first thing we expects from index-pack's output
* is "pack\t%40s\n" or "keep\t%40s\n" (46 bytes) where
- * %40s is the newly created pack SHA1 name. In the "keep"
+ * %40s is the newly created pack SHA-1 name. In the "keep"
* case, we need it to remove the corresponding .keep file
* later on. If we don't get that then tough luck with it.
*/
diff --git a/refs.c b/refs.c
index 8117328..85a0a42 100644
--- a/refs.c
+++ b/refs.c
@@ -20,7 +20,7 @@ static const char *parse_ref_line(char *line, unsigned char *sha1)
* 42: the answer to everything.
*
* In this case, it happens to be the answer to
- * 40 (length of sha1 hex representation)
+ * 40 (length of SHA-1 hex representation)
* +1 (space in between hex and name)
* +1 (newline at the end of the line)
*/
diff --git a/setup.c b/setup.c
index e9d3f5a..47872f3 100644
--- a/setup.c
+++ b/setup.c
@@ -141,7 +141,7 @@ const char **get_pathspec(const char *prefix, const char **pathspec)
* - a refs/ directory
* - either a HEAD symlink or a HEAD file that is formatted as
* a proper "ref:", or a regular file HEAD that has a properly
- * formatted sha1 object name.
+ * formatted SHA-1 object name.
*/
static int is_git_directory(const char *suspect)
{
diff --git a/sha1_file.c b/sha1_file.c
index 43ff402..443174d 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -3,7 +3,7 @@
*
* Copyright (C) Linus Torvalds, 2005
*
- * This handles basic git sha1 object files - packing, unpacking,
+ * This handles basic git SHA-1 object files - packing, unpacking,
* creation etc.
*/
#include "cache.h"
@@ -149,7 +149,7 @@ static void fill_sha1_path(char *pathbuf, const unsigned char *sha1)
* filename.
*
* Also note that this returns the location for creating. Reading
- * SHA1 file can happen from any alternate directory listed in the
+ * SHA-1 file can happen from any alternate directory listed in the
* DB_ENVIRONMENT environment variable if it is not found in
* the primary object database.
*/
@@ -238,7 +238,7 @@ static void read_info_alternates(const char * alternates, int depth);
* contains "/the/directory/corresponding/to/.git/objects/...", while
* its name points just after the slash at the end of ".git/objects/"
* in the example above, and has enough space to hold 40-byte hex
- * SHA1, an extra slash for the first level indirection, and the
+ * SHA-1, an extra slash for the first level indirection, and the
* terminating NUL.
*/
static int link_alt_odb_entry(const char * entry, int len, const char * relative_base, int depth)
@@ -480,8 +480,8 @@ static int check_packed_git_idx(const char *path, unsigned long *idx_size_,
* Total size:
* - 256 index entries 4 bytes each
* - 24-byte entries * nr (20-byte sha1 + 4-byte offset)
- * - 20-byte SHA1 of the packfile
- * - 20-byte SHA1 file checksum
+ * - 20-byte SHA-1 of the packfile
+ * - 20-byte SHA-1 file checksum
*/
if (idx_size != 4*256 + nr * 24 + 20 + 20)
return error("wrong index file size in %s", path);
@@ -1618,7 +1618,7 @@ int move_temp_to_file(const char *tmpfile, const char *filename)
unlink(tmpfile);
if (ret) {
if (ret != EEXIST) {
- return error("unable to write sha1 filename %s: %s\n", filename, strerror(ret));
+ return error("unable to write SHA-1 filename %s: %s\n", filename, strerror(ret));
}
/* FIXME!!! Collision check here ? */
}
@@ -1753,7 +1753,7 @@ int write_sha1_file(void *buf, unsigned long len, const char *type, unsigned cha
size = stream.total_out;
if (write_buffer(fd, compressed, size) < 0)
- die("unable to write sha1 file");
+ die("unable to write SHA-1 file");
fchmod(fd, 0444);
close(fd);
free(compressed);
@@ -1869,7 +1869,7 @@ int write_sha1_from_fd(const unsigned char *sha1, int fd, char *buffer,
stream.avail_out);
} while (stream.avail_in && ret == Z_OK);
if (write_buffer(local, buffer, *bufposn - stream.avail_in) < 0)
- die("unable to write sha1 file");
+ die("unable to write SHA-1 file");
memmove(buffer, buffer + *bufposn - stream.avail_in,
stream.avail_in);
*bufposn = stream.avail_in;
diff --git a/sha1_name.c b/sha1_name.c
index 9dfb3ac..b4bf045 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -182,7 +182,7 @@ static int get_short_sha1(const char *name, int len, unsigned char *sha1,
status = find_unique_short_object(i, canonical, res, sha1);
if (!quietly && (status == SHORT_NAME_AMBIGUOUS))
- return error("short SHA1 %.*s is ambiguous.", len, canonical);
+ return error("short SHA-1 %.*s is ambiguous.", len, canonical);
return status;
}
diff --git a/upload-pack.c b/upload-pack.c
index 3648aae..ba3faae 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -343,7 +343,7 @@ static int got_sha1(char *hex, unsigned char *sha1)
int we_knew_they_have = 0;
if (get_sha1_hex(hex, sha1))
- die("git-upload-pack: expected SHA1 object, got '%s'", hex);
+ die("git-upload-pack: expected SHA-1 object, got '%s'", hex);
if (!has_sha1_file(sha1))
return -1;
@@ -484,7 +484,7 @@ static int get_common_commits(void)
packet_write(1, "NAK\n");
return -1;
}
- die("git-upload-pack: expected SHA1 list, got '%s'", line);
+ die("git-upload-pack: expected SHA-1 list, got '%s'", line);
}
}
--
1.5.0.rc2
^ permalink raw reply related [relevance 1%]
* Re: [PATCH] user-manual: set user.name and user.email with repo-config
@ 2007-01-28 2:40 2% ` Tom Prince
0 siblings, 0 replies; 200+ results
From: Tom Prince @ 2007-01-28 2:40 UTC (permalink / raw)
To: Linus Torvalds; +Cc: git, J. Bruce Fields, Junio C Hamano
On Sat, Jan 27, 2007 at 05:47:49PM -0800, Linus Torvalds wrote:
> Btw, one thing I don't like about "git-repo-config" is the name.
>
> Many people thought "git init-db" was confusing, and now we call it just
> "git init".
>
> Can I vote for doing that for "git repo-config" too? Is there something
> wrong with just calling it "git config"?
>
> Especially as it's not even repo-specific. Use "--global", and it has
> almost nothing at all to do with the particular "repo" you're working
> with.
>
> What would also mean that we'd have the man-page with a simple
>
> man git-config
>
> which makes tons of sense if it documents both the config file *and* the
> "git config" program.
>
> Or is that too sneaky?
>
> Linus
---
.gitignore | 1 +
Documentation/cmd-list.perl | 2 +-
Documentation/config.txt | 2 +-
Documentation/core-tutorial.txt | 2 +-
Documentation/cvs-migration.txt | 2 +-
Documentation/everyday.txt | 4 +-
Documentation/git-config.txt | 227 ++++++++++++++++++++
Documentation/git-pull.txt | 4 +-
Documentation/git-remote.txt | 4 +-
Documentation/git-repo-config.txt | 227 --------------------
Documentation/git-svn.txt | 20 +-
Documentation/git-update-index.txt | 4 +-
Documentation/git-var.txt | 4 +-
Documentation/git.txt | 2 +-
Documentation/howto/setup-git-server-over-http.txt | 4 +-
Documentation/tutorial.txt | 8 +-
Makefile | 4 +-
builtin-config.c | 220 +++++++++++++++++++
builtin-repo-config.c | 220 -------------------
builtin.h | 2 +-
contrib/completion/git-completion.bash | 15 +-
contrib/emacs/git.el | 8 +-
contrib/gitview/gitview | 2 +-
contrib/remotes2config.sh | 4 +-
git-clone.sh | 10 +-
git-commit.sh | 4 +-
git-cvsserver.perl | 6 +-
git-fetch.sh | 2 +-
git-instaweb.sh | 10 +-
git-ls-remote.sh | 2 +-
git-merge.sh | 4 +-
git-p4import.py | 4 +-
git-parse-remote.sh | 14 +-
git-remote.perl | 8 +-
git-repack.sh | 2 +-
git-revert.sh | 2 +-
git-sh-setup.sh | 2 +-
git-svn.perl | 20 +-
git.c | 3 +-
gitk | 2 +-
gitweb/gitweb.perl | 2 +-
ident.c | 4 +-
perl/Git.pm | 8 +-
t/t1300-repo-config.sh | 102 +++++-----
t/t1400-update-ref.sh | 4 +-
t/t1410-reflog.sh | 2 +-
t/t3200-branch.sh | 6 +-
t/t3700-add.sh | 6 +-
t/t3900-i18n-commit.sh | 24 +-
t/t3901-i18n-patch.sh | 58 +++---
t/t4000-diff-format.sh | 2 +-
t/t4006-diff-mode.sh | 2 +-
t/t4013-diff-various.sh | 2 +-
t/t4102-apply-rename.sh | 2 +-
t/t5301-sliding-window.sh | 14 +-
t/t5400-send-pack.sh | 2 +-
t/t5500-fetch-pack.sh | 2 +-
t/t5510-fetch.sh | 10 +-
t/t6200-fmt-merge-msg.sh | 6 +-
59 files changed, 674 insertions(+), 671 deletions(-)
create mode 100644 Documentation/git-config.txt
delete mode 100644 Documentation/git-repo-config.txt
create mode 100644 builtin-config.c
delete mode 100644 builtin-repo-config.c
diff --git a/.gitignore b/.gitignore
index 6da1cdb..b4dccd7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -23,6 +23,7 @@ git-clean
git-clone
git-commit
git-commit-tree
+git-config
git-convert-objects
git-count-objects
git-cvsexportcommit
diff --git a/Documentation/cmd-list.perl b/Documentation/cmd-list.perl
index 744db82..8244625 100755
--- a/Documentation/cmd-list.perl
+++ b/Documentation/cmd-list.perl
@@ -144,7 +144,7 @@ git-receive-pack synchelpers
git-reflog ancillarymanipulators
git-relink ancillarymanipulators
git-repack ancillarymanipulators
-git-repo-config ancillarymanipulators
+git-config ancillarymanipulators
git-request-pull foreignscminterface
git-rerere ancillaryinterrogators
git-reset mainporcelain
diff --git a/Documentation/config.txt b/Documentation/config.txt
index 3f2fa09..4897c55 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -62,7 +62,7 @@ The values following the equals sign in variable assign are all either
a string, an integer, or a boolean. Boolean values may be given as yes/no,
0/1 or true/false. Case is not significant in boolean values, when
converting value to the canonical form using '--bool' type specifier;
-`git-repo-config` will ensure that the output is "true" or "false".
+`git-config` will ensure that the output is "true" or "false".
String values may be entirely or partially enclosed in double quotes.
You need to enclose variable value in double quotes if you want to
diff --git a/Documentation/core-tutorial.txt b/Documentation/core-tutorial.txt
index 7317489..86a9c75 100644
--- a/Documentation/core-tutorial.txt
+++ b/Documentation/core-tutorial.txt
@@ -1130,7 +1130,7 @@ the remote repository URL in the local repository's config file
like this:
------------------------------------------------
-$ git repo-config remote.linus.url http://www.kernel.org/pub/scm/git/git.git/
+$ git config remote.linus.url http://www.kernel.org/pub/scm/git/git.git/
------------------------------------------------
and use the "linus" keyword with `git pull` instead of the full URL.
diff --git a/Documentation/cvs-migration.txt b/Documentation/cvs-migration.txt
index 775bf42..764cc56 100644
--- a/Documentation/cvs-migration.txt
+++ b/Documentation/cvs-migration.txt
@@ -36,7 +36,7 @@ them first before running git pull.
================================
The `pull` command knows where to get updates from because of certain
configuration variables that were set by the first `git clone`
-command; see `git repo-config -l` and the gitlink:git-repo-config[1] man
+command; see `git config -l` and the gitlink:git-config[1] man
page for details.
================================
diff --git a/Documentation/everyday.txt b/Documentation/everyday.txt
index ca36a76..fbbbc92 100644
--- a/Documentation/everyday.txt
+++ b/Documentation/everyday.txt
@@ -212,12 +212,12 @@ Push into another repository.::
------------
satellite$ git clone mothership:frotz frotz <1>
satellite$ cd frotz
-satellite$ git repo-config --get-regexp '^(remote|branch)\.' <2>
+satellite$ git config --get-regexp '^(remote|branch)\.' <2>
remote.origin.url mothership:frotz
remote.origin.fetch refs/heads/*:refs/remotes/origin/*
branch.master.remote origin
branch.master.merge refs/heads/master
-satellite$ git repo-config remote.origin.push \
+satellite$ git config remote.origin.push \
master:refs/remotes/satellite/master <3>
satellite$ edit/compile/test/commit
satellite$ git push origin <4>
diff --git a/Documentation/git-config.txt b/Documentation/git-config.txt
new file mode 100644
index 0000000..b0dbfb2
--- /dev/null
+++ b/Documentation/git-config.txt
@@ -0,0 +1,227 @@
+git-config(1)
+==================
+
+NAME
+----
+git-config - Get and set repository or global options
+
+
+SYNOPSIS
+--------
+[verse]
+'git-config' [--global] [type] name [value [value_regex]]
+'git-config' [--global] [type] --add name value
+'git-config' [--global] [type] --replace-all name [value [value_regex]]
+'git-config' [--global] [type] --get name [value_regex]
+'git-config' [--global] [type] --get-all name [value_regex]
+'git-config' [--global] [type] --unset name [value_regex]
+'git-config' [--global] [type] --unset-all name [value_regex]
+'git-config' [--global] -l | --list
+
+DESCRIPTION
+-----------
+You can query/set/replace/unset options with this command. The name is
+actually the section and the key separated by a dot, and the value will be
+escaped.
+
+Multiple lines can be added to an option by using the '--add' option.
+If you want to update or unset an option which can occur on multiple
+lines, a POSIX regexp `value_regex` needs to be given. Only the
+existing values that match the regexp are updated or unset. If
+you want to handle the lines that do *not* match the regex, just
+prepend a single exclamation mark in front (see EXAMPLES).
+
+The type specifier can be either '--int' or '--bool', which will make
+'git-config' ensure that the variable(s) are of the given type and
+convert the value to the canonical form (simple decimal number for int,
+a "true" or "false" string for bool). If no type specifier is passed,
+no checks or transformations are performed on the value.
+
+This command will fail if:
+
+. The .git/config file is invalid,
+. Can not write to .git/config,
+. no section was provided,
+. the section or key is invalid,
+. you try to unset an option which does not exist,
+. you try to unset/set an option for which multiple lines match, or
+. you use --global option without $HOME being properly set.
+
+
+OPTIONS
+-------
+
+--replace-all::
+ Default behavior is to replace at most one line. This replaces
+ all lines matching the key (and optionally the value_regex).
+
+--add::
+ Adds a new line to the option without altering any existing
+ values. This is the same as providing '^$' as the value_regex.
+
+--get::
+ Get the value for a given key (optionally filtered by a regex
+ matching the value). Returns error code 1 if the key was not
+ found and error code 2 if multiple key values were found.
+
+--get-all::
+ Like get, but does not fail if the number of values for the key
+ is not exactly one.
+
+--get-regexp::
+ Like --get-all, but interprets the name as a regular expression.
+
+--global::
+ Use global ~/.gitconfig file rather than the repository .git/config.
+
+--unset::
+ Remove the line matching the key from config file.
+
+--unset-all::
+ Remove all matching lines from config file.
+
+-l, --list::
+ List all variables set in config file.
+
+--bool::
+ git-config will ensure that the output is "true" or "false"
+
+--int::
+ git-config will ensure that the output is a simple
+ decimal number. An optional value suffix of 'k', 'm', or 'g'
+ in the config file will cause the value to be multiplied
+ by 1024, 1048576, or 1073741824 prior to output.
+
+
+ENVIRONMENT
+-----------
+
+GIT_CONFIG::
+ Take the configuration from the given file instead of .git/config.
+ Using the "--global" option forces this to ~/.gitconfig.
+
+GIT_CONFIG_LOCAL::
+ Currently the same as $GIT_CONFIG; when Git will support global
+ configuration files, this will cause it to take the configuration
+ from the global configuration file in addition to the given file.
+
+
+EXAMPLE
+-------
+
+Given a .git/config like this:
+
+ #
+ # This is the config file, and
+ # a '#' or ';' character indicates
+ # a comment
+ #
+
+ ; core variables
+ [core]
+ ; Don't trust file modes
+ filemode = false
+
+ ; Our diff algorithm
+ [diff]
+ external = "/usr/local/bin/gnu-diff -u"
+ renames = true
+
+ ; Proxy settings
+ [core]
+ gitproxy="ssh" for "ssh://kernel.org/"
+ gitproxy="proxy-command" for kernel.org
+ gitproxy="myprotocol-command" for "my://"
+ gitproxy=default-proxy ; for all the rest
+
+you can set the filemode to true with
+
+------------
+% git config core.filemode true
+------------
+
+The hypothetical proxy command entries actually have a postfix to discern
+what URL they apply to. Here is how to change the entry for kernel.org
+to "ssh".
+
+------------
+% git config core.gitproxy '"ssh" for kernel.org' 'for kernel.org$'
+------------
+
+This makes sure that only the key/value pair for kernel.org is replaced.
+
+To delete the entry for renames, do
+
+------------
+% git config --unset diff.renames
+------------
+
+If you want to delete an entry for a multivar (like core.gitproxy above),
+you have to provide a regex matching the value of exactly one line.
+
+To query the value for a given key, do
+
+------------
+% git config --get core.filemode
+------------
+
+or
+
+------------
+% git config core.filemode
+------------
+
+or, to query a multivar:
+
+------------
+% git config --get core.gitproxy "for kernel.org$"
+------------
+
+If you want to know all the values for a multivar, do:
+
+------------
+% git config --get-all core.gitproxy
+------------
+
+If you like to live dangerous, you can replace *all* core.gitproxy by a
+new one with
+
+------------
+% git config --replace-all core.gitproxy ssh
+------------
+
+However, if you really only want to replace the line for the default proxy,
+i.e. the one without a "for ..." postfix, do something like this:
+
+------------
+% git config core.gitproxy ssh '! for '
+------------
+
+To actually match only values with an exclamation mark, you have to
+
+------------
+% git config section.key value '[!]'
+------------
+
+To add a new proxy, without altering any of the existing ones, use
+
+------------
+% git config core.gitproxy '"proxy" for example.com'
+------------
+
+
+include::config.txt[]
+
+
+Author
+------
+Written by Johannes Schindelin <Johannes.Schindelin@gmx.de>
+
+Documentation
+--------------
+Documentation by Johannes Schindelin, Petr Baudis and the git-list <git@vger.kernel.org>.
+
+GIT
+---
+Part of the gitlink:git[7] suite
+
diff --git a/Documentation/git-pull.txt b/Documentation/git-pull.txt
index 3e5f115..a81d68c 100644
--- a/Documentation/git-pull.txt
+++ b/Documentation/git-pull.txt
@@ -42,7 +42,7 @@ git pull, git pull origin::
current branch. Normally the branch merged in is
the HEAD of the remote repository, but the choice is
determined by the branch.<name>.remote and
- branch.<name>.merge options; see gitlink:git-repo-config[1]
+ branch.<name>.merge options; see gitlink:git-config[1]
for details.
git pull origin next::
@@ -94,7 +94,7 @@ gitlink:git-reset[1].
SEE ALSO
--------
-gitlink:git-fetch[1], gitlink:git-merge[1], gitlink:git-repo-config[1]
+gitlink:git-fetch[1], gitlink:git-merge[1], gitlink:git-config[1]
Author
diff --git a/Documentation/git-remote.txt b/Documentation/git-remote.txt
index 5b93a8c..358c1ac 100644
--- a/Documentation/git-remote.txt
+++ b/Documentation/git-remote.txt
@@ -28,7 +28,7 @@ In the third form, gives some information about the remote <name>.
The remote configuration is achieved using the `remote.origin.url` and
`remote.origin.fetch` configuration variables. (See
-gitlink:git-repo-config[1]).
+gitlink:git-config[1]).
Examples
--------
@@ -58,7 +58,7 @@ See Also
--------
gitlink:git-fetch[1]
gitlink:git-branch[1]
-gitlink:git-repo-config[1]
+gitlink:git-config[1]
Author
------
diff --git a/Documentation/git-repo-config.txt b/Documentation/git-repo-config.txt
deleted file mode 100644
index 9db3d30..0000000
--- a/Documentation/git-repo-config.txt
+++ /dev/null
@@ -1,227 +0,0 @@
-git-repo-config(1)
-==================
-
-NAME
-----
-git-repo-config - Get and set repository or global options
-
-
-SYNOPSIS
---------
-[verse]
-'git-repo-config' [--global] [type] name [value [value_regex]]
-'git-repo-config' [--global] [type] --add name value
-'git-repo-config' [--global] [type] --replace-all name [value [value_regex]]
-'git-repo-config' [--global] [type] --get name [value_regex]
-'git-repo-config' [--global] [type] --get-all name [value_regex]
-'git-repo-config' [--global] [type] --unset name [value_regex]
-'git-repo-config' [--global] [type] --unset-all name [value_regex]
-'git-repo-config' [--global] -l | --list
-
-DESCRIPTION
------------
-You can query/set/replace/unset options with this command. The name is
-actually the section and the key separated by a dot, and the value will be
-escaped.
-
-Multiple lines can be added to an option by using the '--add' option.
-If you want to update or unset an option which can occur on multiple
-lines, a POSIX regexp `value_regex` needs to be given. Only the
-existing values that match the regexp are updated or unset. If
-you want to handle the lines that do *not* match the regex, just
-prepend a single exclamation mark in front (see EXAMPLES).
-
-The type specifier can be either '--int' or '--bool', which will make
-'git-repo-config' ensure that the variable(s) are of the given type and
-convert the value to the canonical form (simple decimal number for int,
-a "true" or "false" string for bool). If no type specifier is passed,
-no checks or transformations are performed on the value.
-
-This command will fail if:
-
-. The .git/config file is invalid,
-. Can not write to .git/config,
-. no section was provided,
-. the section or key is invalid,
-. you try to unset an option which does not exist,
-. you try to unset/set an option for which multiple lines match, or
-. you use --global option without $HOME being properly set.
-
-
-OPTIONS
--------
-
---replace-all::
- Default behavior is to replace at most one line. This replaces
- all lines matching the key (and optionally the value_regex).
-
---add::
- Adds a new line to the option without altering any existing
- values. This is the same as providing '^$' as the value_regex.
-
---get::
- Get the value for a given key (optionally filtered by a regex
- matching the value). Returns error code 1 if the key was not
- found and error code 2 if multiple key values were found.
-
---get-all::
- Like get, but does not fail if the number of values for the key
- is not exactly one.
-
---get-regexp::
- Like --get-all, but interprets the name as a regular expression.
-
---global::
- Use global ~/.gitconfig file rather than the repository .git/config.
-
---unset::
- Remove the line matching the key from config file.
-
---unset-all::
- Remove all matching lines from config file.
-
--l, --list::
- List all variables set in config file.
-
---bool::
- git-repo-config will ensure that the output is "true" or "false"
-
---int::
- git-repo-config will ensure that the output is a simple
- decimal number. An optional value suffix of 'k', 'm', or 'g'
- in the config file will cause the value to be multiplied
- by 1024, 1048576, or 1073741824 prior to output.
-
-
-ENVIRONMENT
------------
-
-GIT_CONFIG::
- Take the configuration from the given file instead of .git/config.
- Using the "--global" option forces this to ~/.gitconfig.
-
-GIT_CONFIG_LOCAL::
- Currently the same as $GIT_CONFIG; when Git will support global
- configuration files, this will cause it to take the configuration
- from the global configuration file in addition to the given file.
-
-
-EXAMPLE
--------
-
-Given a .git/config like this:
-
- #
- # This is the config file, and
- # a '#' or ';' character indicates
- # a comment
- #
-
- ; core variables
- [core]
- ; Don't trust file modes
- filemode = false
-
- ; Our diff algorithm
- [diff]
- external = "/usr/local/bin/gnu-diff -u"
- renames = true
-
- ; Proxy settings
- [core]
- gitproxy="ssh" for "ssh://kernel.org/"
- gitproxy="proxy-command" for kernel.org
- gitproxy="myprotocol-command" for "my://"
- gitproxy=default-proxy ; for all the rest
-
-you can set the filemode to true with
-
-------------
-% git repo-config core.filemode true
-------------
-
-The hypothetical proxy command entries actually have a postfix to discern
-what URL they apply to. Here is how to change the entry for kernel.org
-to "ssh".
-
-------------
-% git repo-config core.gitproxy '"ssh" for kernel.org' 'for kernel.org$'
-------------
-
-This makes sure that only the key/value pair for kernel.org is replaced.
-
-To delete the entry for renames, do
-
-------------
-% git repo-config --unset diff.renames
-------------
-
-If you want to delete an entry for a multivar (like core.gitproxy above),
-you have to provide a regex matching the value of exactly one line.
-
-To query the value for a given key, do
-
-------------
-% git repo-config --get core.filemode
-------------
-
-or
-
-------------
-% git repo-config core.filemode
-------------
-
-or, to query a multivar:
-
-------------
-% git repo-config --get core.gitproxy "for kernel.org$"
-------------
-
-If you want to know all the values for a multivar, do:
-
-------------
-% git repo-config --get-all core.gitproxy
-------------
-
-If you like to live dangerous, you can replace *all* core.gitproxy by a
-new one with
-
-------------
-% git repo-config --replace-all core.gitproxy ssh
-------------
-
-However, if you really only want to replace the line for the default proxy,
-i.e. the one without a "for ..." postfix, do something like this:
-
-------------
-% git repo-config core.gitproxy ssh '! for '
-------------
-
-To actually match only values with an exclamation mark, you have to
-
-------------
-% git repo-config section.key value '[!]'
-------------
-
-To add a new proxy, without altering any of the existing ones, use
-
-------------
-% git repo-config core.gitproxy '"proxy" for example.com'
-------------
-
-
-include::config.txt[]
-
-
-Author
-------
-Written by Johannes Schindelin <Johannes.Schindelin@gmx.de>
-
-Documentation
---------------
-Documentation by Johannes Schindelin, Petr Baudis and the git-list <git@vger.kernel.org>.
-
-GIT
----
-Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-svn.txt b/Documentation/git-svn.txt
index b95ff1d..aea4a6b 100644
--- a/Documentation/git-svn.txt
+++ b/Documentation/git-svn.txt
@@ -204,7 +204,7 @@ removed by default if there are no files left in them. git
cannot version empty directories. Enabling this flag will make
the commit to SVN act like git.
-repo-config key: svn.rmdir
+config key: svn.rmdir
-e::
--edit::
@@ -215,7 +215,7 @@ Edit the commit message before committing to SVN. This is off by
default for objects that are commits, and forced on when committing
tree objects.
-repo-config key: svn.edit
+config key: svn.edit
-l<num>::
--find-copies-harder::
@@ -226,8 +226,8 @@ They are both passed directly to git-diff-tree see
gitlink:git-diff-tree[1] for more information.
[verse]
-repo-config key: svn.l
-repo-config key: svn.findcopiesharder
+config key: svn.l
+config key: svn.findcopiesharder
-A<filename>::
--authors-file=<filename>::
@@ -245,7 +245,7 @@ will abort operation. The user will then have to add the
appropriate entry. Re-running the previous git-svn command
after the authors-file is modified should continue operation.
-repo-config key: svn.authorsfile
+config key: svn.authorsfile
-q::
--quiet::
@@ -262,8 +262,8 @@ repo-config key: svn.authorsfile
--repack-flags are passed directly to gitlink:git-repack[1].
-repo-config key: svn.repack
-repo-config key: svn.repackflags
+config key: svn.repack
+config key: svn.repackflags
-m::
--merge::
@@ -304,7 +304,7 @@ used to track branches across multiple SVN _repositories_.
This option may be specified multiple times, once for each
branch.
-repo-config key: svn.branch
+config key: svn.branch
-i<GIT_SVN_ID>::
--id <GIT_SVN_ID>::
@@ -320,7 +320,7 @@ for more information on using GIT_SVN_ID.
started tracking a branch and never tracked the trunk it was
descended from.
-repo-config key: svn.followparent
+config key: svn.followparent
--no-metadata::
This gets rid of the git-svn-id: lines at the end of every commit.
@@ -332,7 +332,7 @@ repo-config key: svn.followparent
The 'git-svn log' command will not work on repositories using this,
either.
-repo-config key: svn.nometadata
+config key: svn.nometadata
--
diff --git a/Documentation/git-update-index.txt b/Documentation/git-update-index.txt
index 5bbae42..b161c8b 100644
--- a/Documentation/git-update-index.txt
+++ b/Documentation/git-update-index.txt
@@ -289,7 +289,7 @@ Configuration
The command honors `core.filemode` configuration variable. If
your repository is on an filesystem whose executable bits are
-unreliable, this should be set to 'false' (see gitlink:git-repo-config[1]).
+unreliable, this should be set to 'false' (see gitlink:git-config[1]).
This causes the command to ignore differences in file modes recorded
in the index and the file mode on the filesystem if they differ only on
executable bit. On such an unfortunate filesystem, you may
@@ -301,7 +301,7 @@ The command looks at `core.ignorestat` configuration variable. See
See Also
--------
-gitlink:git-repo-config[1]
+gitlink:git-config[1]
Author
diff --git a/Documentation/git-var.txt b/Documentation/git-var.txt
index 8a50638..9b0de1c 100644
--- a/Documentation/git-var.txt
+++ b/Documentation/git-var.txt
@@ -20,7 +20,7 @@ OPTIONS
Cause the logical variables to be listed. In addition, all the
variables of the git configuration file .git/config are listed
as well. (However, the configuration variables listing functionality
- is deprecated in favor of `git-repo-config -l`.)
+ is deprecated in favor of `git-config -l`.)
EXAMPLE
--------
@@ -49,7 +49,7 @@ See Also
--------
gitlink:git-commit-tree[1]
gitlink:git-tag[1]
-gitlink:git-repo-config[1]
+gitlink:git-config[1]
Author
------
diff --git a/Documentation/git.txt b/Documentation/git.txt
index 9761de3..7cd3467 100644
--- a/Documentation/git.txt
+++ b/Documentation/git.txt
@@ -24,7 +24,7 @@ link:everyday.html[Everyday Git] for a useful minimum set of commands, and
also want to read link:cvs-migration.html[CVS migration].
The COMMAND is either a name of a Git command (see below) or an alias
-as defined in the configuration file (see gitlink:git-repo-config[1]).
+as defined in the configuration file (see gitlink:git-config[1]).
OPTIONS
-------
diff --git a/Documentation/howto/setup-git-server-over-http.txt b/Documentation/howto/setup-git-server-over-http.txt
index a202f3a..8eadc20 100644
--- a/Documentation/howto/setup-git-server-over-http.txt
+++ b/Documentation/howto/setup-git-server-over-http.txt
@@ -205,7 +205,7 @@ To check whether all is OK, do:
Now, add the remote in your existing repository which contains the project
you want to export:
- $ git-repo-config remote.upload.url \
+ $ git-config remote.upload.url \
http://<username>@<servername>/my-new-repo.git/
It is important to put the last '/'; Without it, the server will send
@@ -222,7 +222,7 @@ From your client repository, do
This pushes branch 'master' (which is assumed to be the branch you
want to export) to repository called 'upload', which we previously
-defined with git-repo-config.
+defined with git-config.
Troubleshooting:
diff --git a/Documentation/tutorial.txt b/Documentation/tutorial.txt
index c27a450..adb1e32 100644
--- a/Documentation/tutorial.txt
+++ b/Documentation/tutorial.txt
@@ -16,8 +16,8 @@ public email address before doing any operation. The easiest
way to do so is:
------------------------------------------------
-$ git repo-config --global user.name "Your Name Comes Here"
-$ git repo-config --global user.email you@yourdomain.example.com
+$ git config --global user.name "Your Name Comes Here"
+$ git config --global user.email you@yourdomain.example.com
------------------------------------------------
@@ -353,12 +353,12 @@ repository in the repository configuration, and that location is
used for pulls:
-------------------------------------
-$ git repo-config --get remote.origin.url
+$ git config --get remote.origin.url
/home/bob/myrepo
-------------------------------------
(The complete configuration created by git-clone is visible using
-"git repo-config -l", and the gitlink:git-repo-config[1] man page
+"git config -l", and the gitlink:git-config[1] man page
explains the meaning of each option.)
Git also keeps a pristine copy of Alice's master branch under the
diff --git a/Makefile b/Makefile
index 07246f3..fd8a522 100644
--- a/Makefile
+++ b/Makefile
@@ -213,7 +213,7 @@ EXTRA_PROGRAMS =
BUILT_INS = \
git-format-patch$X git-show$X git-whatchanged$X git-cherry$X \
- git-get-tar-commit-id$X git-init$X \
+ git-get-tar-commit-id$X git-init$X git-repo-config$X \
$(patsubst builtin-%.o,git-%$X,$(BUILTIN_OBJS))
# what 'all' will build and 'install' will install, in gitexecdir
@@ -299,7 +299,7 @@ BUILTIN_OBJS = \
builtin-push.o \
builtin-read-tree.o \
builtin-reflog.o \
- builtin-repo-config.o \
+ builtin-config.o \
builtin-rerere.o \
builtin-rev-list.o \
builtin-rev-parse.o \
diff --git a/builtin-config.c b/builtin-config.c
new file mode 100644
index 0000000..3c3860f
--- /dev/null
+++ b/builtin-config.c
@@ -0,0 +1,220 @@
+#include "builtin.h"
+#include "cache.h"
+
+static const char git_config_set_usage[] =
+"git-config [ --global ] [ --bool | --int ] [--get | --get-all | --get-regexp | --replace-all | --add | --unset | --unset-all] name [value [value_regex]] | --rename-section old_name new_name | --list";
+
+static char *key;
+static regex_t *key_regexp;
+static regex_t *regexp;
+static int show_keys;
+static int use_key_regexp;
+static int do_all;
+static int do_not_match;
+static int seen;
+static enum { T_RAW, T_INT, T_BOOL } type = T_RAW;
+
+static int show_all_config(const char *key_, const char *value_)
+{
+ if (value_)
+ printf("%s=%s\n", key_, value_);
+ else
+ printf("%s\n", key_);
+ return 0;
+}
+
+static int show_config(const char* key_, const char* value_)
+{
+ char value[256];
+ const char *vptr = value;
+ int dup_error = 0;
+
+ if (!use_key_regexp && strcmp(key_, key))
+ return 0;
+ if (use_key_regexp && regexec(key_regexp, key_, 0, NULL, 0))
+ return 0;
+ if (regexp != NULL &&
+ (do_not_match ^
+ regexec(regexp, (value_?value_:""), 0, NULL, 0)))
+ return 0;
+
+ if (show_keys)
+ printf("%s ", key_);
+ if (seen && !do_all)
+ dup_error = 1;
+ if (type == T_INT)
+ sprintf(value, "%d", git_config_int(key_, value_?value_:""));
+ else if (type == T_BOOL)
+ vptr = git_config_bool(key_, value_) ? "true" : "false";
+ else
+ vptr = value_?value_:"";
+ seen++;
+ if (dup_error) {
+ error("More than one value for the key %s: %s",
+ key_, vptr);
+ }
+ else
+ printf("%s\n", vptr);
+
+ return 0;
+}
+
+static int get_value(const char* key_, const char* regex_)
+{
+ int ret = -1;
+ char *tl;
+ char *global = NULL, *config = NULL;
+ const char *local;
+
+ local = getenv(CONFIG_ENVIRONMENT);
+ if (!local) {
+ const char *home = getenv("HOME");
+ local = getenv(CONFIG_LOCAL_ENVIRONMENT);
+ if (!local)
+ local = config = xstrdup(git_path("config"));
+ if (home)
+ global = xstrdup(mkpath("%s/.gitconfig", home));
+ }
+
+ key = xstrdup(key_);
+ for (tl=key+strlen(key)-1; tl >= key && *tl != '.'; --tl)
+ *tl = tolower(*tl);
+ for (tl=key; *tl && *tl != '.'; ++tl)
+ *tl = tolower(*tl);
+
+ if (use_key_regexp) {
+ key_regexp = (regex_t*)xmalloc(sizeof(regex_t));
+ if (regcomp(key_regexp, key, REG_EXTENDED)) {
+ fprintf(stderr, "Invalid key pattern: %s\n", key_);
+ goto free_strings;
+ }
+ }
+
+ if (regex_) {
+ if (regex_[0] == '!') {
+ do_not_match = 1;
+ regex_++;
+ }
+
+ regexp = (regex_t*)xmalloc(sizeof(regex_t));
+ if (regcomp(regexp, regex_, REG_EXTENDED)) {
+ fprintf(stderr, "Invalid pattern: %s\n", regex_);
+ goto free_strings;
+ }
+ }
+
+ if (do_all && global)
+ git_config_from_file(show_config, global);
+ git_config_from_file(show_config, local);
+ if (!do_all && !seen && global)
+ git_config_from_file(show_config, global);
+
+ free(key);
+ if (regexp) {
+ regfree(regexp);
+ free(regexp);
+ }
+
+ if (do_all)
+ ret = !seen;
+ else
+ ret = (seen == 1) ? 0 : seen > 1 ? 2 : 1;
+
+free_strings:
+ free(config);
+ free(global);
+ return ret;
+}
+
+int cmd_config(int argc, const char **argv, const char *prefix)
+{
+ int nongit = 0;
+ setup_git_directory_gently(&nongit);
+
+ while (1 < argc) {
+ if (!strcmp(argv[1], "--int"))
+ type = T_INT;
+ else if (!strcmp(argv[1], "--bool"))
+ type = T_BOOL;
+ else if (!strcmp(argv[1], "--list") || !strcmp(argv[1], "-l"))
+ return git_config(show_all_config);
+ else if (!strcmp(argv[1], "--global")) {
+ char *home = getenv("HOME");
+ if (home) {
+ char *user_config = xstrdup(mkpath("%s/.gitconfig", home));
+ setenv("GIT_CONFIG", user_config, 1);
+ free(user_config);
+ } else {
+ die("$HOME not set");
+ }
+ } else if (!strcmp(argv[1], "--rename-section")) {
+ int ret;
+ if (argc != 4)
+ usage(git_config_set_usage);
+ ret = git_config_rename_section(argv[2], argv[3]);
+ if (ret < 0)
+ return ret;
+ if (ret == 0) {
+ fprintf(stderr, "No such section!\n");
+ return 1;
+ }
+ return 0;
+ } else
+ break;
+ argc--;
+ argv++;
+ }
+
+ switch (argc) {
+ case 2:
+ return get_value(argv[1], NULL);
+ case 3:
+ if (!strcmp(argv[1], "--unset"))
+ return git_config_set(argv[2], NULL);
+ else if (!strcmp(argv[1], "--unset-all"))
+ return git_config_set_multivar(argv[2], NULL, NULL, 1);
+ else if (!strcmp(argv[1], "--get"))
+ return get_value(argv[2], NULL);
+ else if (!strcmp(argv[1], "--get-all")) {
+ do_all = 1;
+ return get_value(argv[2], NULL);
+ } else if (!strcmp(argv[1], "--get-regexp")) {
+ show_keys = 1;
+ use_key_regexp = 1;
+ do_all = 1;
+ return get_value(argv[2], NULL);
+ } else
+
+ return git_config_set(argv[1], argv[2]);
+ case 4:
+ if (!strcmp(argv[1], "--unset"))
+ return git_config_set_multivar(argv[2], NULL, argv[3], 0);
+ else if (!strcmp(argv[1], "--unset-all"))
+ return git_config_set_multivar(argv[2], NULL, argv[3], 1);
+ else if (!strcmp(argv[1], "--get"))
+ return get_value(argv[2], argv[3]);
+ else if (!strcmp(argv[1], "--get-all")) {
+ do_all = 1;
+ return get_value(argv[2], argv[3]);
+ } else if (!strcmp(argv[1], "--get-regexp")) {
+ show_keys = 1;
+ use_key_regexp = 1;
+ do_all = 1;
+ return get_value(argv[2], argv[3]);
+ } else if (!strcmp(argv[1], "--add"))
+ return git_config_set_multivar(argv[2], argv[3], "^$", 0);
+ else if (!strcmp(argv[1], "--replace-all"))
+
+ return git_config_set_multivar(argv[2], argv[3], NULL, 1);
+ else
+
+ return git_config_set_multivar(argv[1], argv[2], argv[3], 0);
+ case 5:
+ if (!strcmp(argv[1], "--replace-all"))
+ return git_config_set_multivar(argv[2], argv[3], argv[4], 1);
+ case 1:
+ default:
+ usage(git_config_set_usage);
+ }
+ return 0;
+}
diff --git a/builtin-repo-config.c b/builtin-repo-config.c
deleted file mode 100644
index 9063311..0000000
--- a/builtin-repo-config.c
+++ /dev/null
@@ -1,220 +0,0 @@
-#include "builtin.h"
-#include "cache.h"
-
-static const char git_config_set_usage[] =
-"git-repo-config [ --global ] [ --bool | --int ] [--get | --get-all | --get-regexp | --replace-all | --add | --unset | --unset-all] name [value [value_regex]] | --rename-section old_name new_name | --list";
-
-static char *key;
-static regex_t *key_regexp;
-static regex_t *regexp;
-static int show_keys;
-static int use_key_regexp;
-static int do_all;
-static int do_not_match;
-static int seen;
-static enum { T_RAW, T_INT, T_BOOL } type = T_RAW;
-
-static int show_all_config(const char *key_, const char *value_)
-{
- if (value_)
- printf("%s=%s\n", key_, value_);
- else
- printf("%s\n", key_);
- return 0;
-}
-
-static int show_config(const char* key_, const char* value_)
-{
- char value[256];
- const char *vptr = value;
- int dup_error = 0;
-
- if (!use_key_regexp && strcmp(key_, key))
- return 0;
- if (use_key_regexp && regexec(key_regexp, key_, 0, NULL, 0))
- return 0;
- if (regexp != NULL &&
- (do_not_match ^
- regexec(regexp, (value_?value_:""), 0, NULL, 0)))
- return 0;
-
- if (show_keys)
- printf("%s ", key_);
- if (seen && !do_all)
- dup_error = 1;
- if (type == T_INT)
- sprintf(value, "%d", git_config_int(key_, value_?value_:""));
- else if (type == T_BOOL)
- vptr = git_config_bool(key_, value_) ? "true" : "false";
- else
- vptr = value_?value_:"";
- seen++;
- if (dup_error) {
- error("More than one value for the key %s: %s",
- key_, vptr);
- }
- else
- printf("%s\n", vptr);
-
- return 0;
-}
-
-static int get_value(const char* key_, const char* regex_)
-{
- int ret = -1;
- char *tl;
- char *global = NULL, *repo_config = NULL;
- const char *local;
-
- local = getenv(CONFIG_ENVIRONMENT);
- if (!local) {
- const char *home = getenv("HOME");
- local = getenv(CONFIG_LOCAL_ENVIRONMENT);
- if (!local)
- local = repo_config = xstrdup(git_path("config"));
- if (home)
- global = xstrdup(mkpath("%s/.gitconfig", home));
- }
-
- key = xstrdup(key_);
- for (tl=key+strlen(key)-1; tl >= key && *tl != '.'; --tl)
- *tl = tolower(*tl);
- for (tl=key; *tl && *tl != '.'; ++tl)
- *tl = tolower(*tl);
-
- if (use_key_regexp) {
- key_regexp = (regex_t*)xmalloc(sizeof(regex_t));
- if (regcomp(key_regexp, key, REG_EXTENDED)) {
- fprintf(stderr, "Invalid key pattern: %s\n", key_);
- goto free_strings;
- }
- }
-
- if (regex_) {
- if (regex_[0] == '!') {
- do_not_match = 1;
- regex_++;
- }
-
- regexp = (regex_t*)xmalloc(sizeof(regex_t));
- if (regcomp(regexp, regex_, REG_EXTENDED)) {
- fprintf(stderr, "Invalid pattern: %s\n", regex_);
- goto free_strings;
- }
- }
-
- if (do_all && global)
- git_config_from_file(show_config, global);
- git_config_from_file(show_config, local);
- if (!do_all && !seen && global)
- git_config_from_file(show_config, global);
-
- free(key);
- if (regexp) {
- regfree(regexp);
- free(regexp);
- }
-
- if (do_all)
- ret = !seen;
- else
- ret = (seen == 1) ? 0 : seen > 1 ? 2 : 1;
-
-free_strings:
- free(repo_config);
- free(global);
- return ret;
-}
-
-int cmd_repo_config(int argc, const char **argv, const char *prefix)
-{
- int nongit = 0;
- setup_git_directory_gently(&nongit);
-
- while (1 < argc) {
- if (!strcmp(argv[1], "--int"))
- type = T_INT;
- else if (!strcmp(argv[1], "--bool"))
- type = T_BOOL;
- else if (!strcmp(argv[1], "--list") || !strcmp(argv[1], "-l"))
- return git_config(show_all_config);
- else if (!strcmp(argv[1], "--global")) {
- char *home = getenv("HOME");
- if (home) {
- char *user_config = xstrdup(mkpath("%s/.gitconfig", home));
- setenv("GIT_CONFIG", user_config, 1);
- free(user_config);
- } else {
- die("$HOME not set");
- }
- } else if (!strcmp(argv[1], "--rename-section")) {
- int ret;
- if (argc != 4)
- usage(git_config_set_usage);
- ret = git_config_rename_section(argv[2], argv[3]);
- if (ret < 0)
- return ret;
- if (ret == 0) {
- fprintf(stderr, "No such section!\n");
- return 1;
- }
- return 0;
- } else
- break;
- argc--;
- argv++;
- }
-
- switch (argc) {
- case 2:
- return get_value(argv[1], NULL);
- case 3:
- if (!strcmp(argv[1], "--unset"))
- return git_config_set(argv[2], NULL);
- else if (!strcmp(argv[1], "--unset-all"))
- return git_config_set_multivar(argv[2], NULL, NULL, 1);
- else if (!strcmp(argv[1], "--get"))
- return get_value(argv[2], NULL);
- else if (!strcmp(argv[1], "--get-all")) {
- do_all = 1;
- return get_value(argv[2], NULL);
- } else if (!strcmp(argv[1], "--get-regexp")) {
- show_keys = 1;
- use_key_regexp = 1;
- do_all = 1;
- return get_value(argv[2], NULL);
- } else
-
- return git_config_set(argv[1], argv[2]);
- case 4:
- if (!strcmp(argv[1], "--unset"))
- return git_config_set_multivar(argv[2], NULL, argv[3], 0);
- else if (!strcmp(argv[1], "--unset-all"))
- return git_config_set_multivar(argv[2], NULL, argv[3], 1);
- else if (!strcmp(argv[1], "--get"))
- return get_value(argv[2], argv[3]);
- else if (!strcmp(argv[1], "--get-all")) {
- do_all = 1;
- return get_value(argv[2], argv[3]);
- } else if (!strcmp(argv[1], "--get-regexp")) {
- show_keys = 1;
- use_key_regexp = 1;
- do_all = 1;
- return get_value(argv[2], argv[3]);
- } else if (!strcmp(argv[1], "--add"))
- return git_config_set_multivar(argv[2], argv[3], "^$", 0);
- else if (!strcmp(argv[1], "--replace-all"))
-
- return git_config_set_multivar(argv[2], argv[3], NULL, 1);
- else
-
- return git_config_set_multivar(argv[1], argv[2], argv[3], 0);
- case 5:
- if (!strcmp(argv[1], "--replace-all"))
- return git_config_set_multivar(argv[2], argv[3], argv[4], 1);
- case 1:
- default:
- usage(git_config_set_usage);
- }
- return 0;
-}
diff --git a/builtin.h b/builtin.h
index 0b3c9f6..cfe5990 100644
--- a/builtin.h
+++ b/builtin.h
@@ -53,7 +53,7 @@ extern int cmd_prune_packed(int argc, const char **argv, const char *prefix);
extern int cmd_push(int argc, const char **argv, const char *prefix);
extern int cmd_read_tree(int argc, const char **argv, const char *prefix);
extern int cmd_reflog(int argc, const char **argv, const char *prefix);
-extern int cmd_repo_config(int argc, const char **argv, const char *prefix);
+extern int cmd_config(int argc, const char **argv, const char *prefix);
extern int cmd_rerere(int argc, const char **argv, const char *prefix);
extern int cmd_rev_list(int argc, const char **argv, const char *prefix);
extern int cmd_rev_parse(int argc, const char **argv, const char *prefix);
diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index 7c7520e..83c69ec 100755
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -145,7 +145,7 @@ __git_remotes ()
echo ${i#$d/remotes/}
done
[ "$ngoff" ] && shopt -u nullglob
- for i in $(git --git-dir="$d" repo-config --list); do
+ for i in $(git --git-dir="$d" config --list); do
case "$i" in
remote.*.url=*)
i="${i#remote.}"
@@ -286,7 +286,7 @@ __git_commandlist="$(__git_commands 2>/dev/null)"
__git_aliases ()
{
local i IFS=$'\n'
- for i in $(git --git-dir="$(__gitdir)" repo-config --list); do
+ for i in $(git --git-dir="$(__gitdir)" config --list); do
case "$i" in
alias.*)
i="${i#alias.}"
@@ -299,7 +299,7 @@ __git_aliases ()
__git_aliased_command ()
{
local word cmdline=$(git --git-dir="$(__gitdir)" \
- repo-config --get "alias.$1")
+ config --get "alias.$1")
for word in $cmdline; do
if [ "${word##-*}" ]; then
echo $word
@@ -629,7 +629,7 @@ _git_rebase ()
COMPREPLY=($(compgen -W "$(__git_refs)" -- "$cur"))
}
-_git_repo_config ()
+_git_config ()
{
local cur="${COMP_WORDS[COMP_CWORD]}"
local prv="${COMP_WORDS[COMP_CWORD-1]}"
@@ -806,6 +806,7 @@ _git ()
checkout) _git_checkout ;;
cherry-pick) _git_cherry_pick ;;
commit) _git_commit ;;
+ config) _git_config ;;
diff) _git_diff ;;
diff-tree) _git_diff_tree ;;
fetch) _git_fetch ;;
@@ -819,7 +820,7 @@ _git ()
pull) _git_pull ;;
push) _git_push ;;
rebase) _git_rebase ;;
- repo-config) _git_repo_config ;;
+ repo-config) _git_config ;;
reset) _git_reset ;;
show) _git_show ;;
show-branch) _git_log ;;
@@ -856,7 +857,7 @@ complete -o default -F _git_name_rev git-name-rev
complete -o default -o nospace -F _git_pull git-pull
complete -o default -o nospace -F _git_push git-push
complete -o default -F _git_rebase git-rebase
-complete -o default -F _git_repo_config git-repo-config
+complete -o default -F _git_config git-config
complete -o default -F _git_reset git-reset
complete -o default -o nospace -F _git_show git-show
complete -o default -o nospace -F _git_log git-show-branch
@@ -879,7 +880,7 @@ complete -o default -o nospace -F _git_ls_tree git-ls-tree.exe
complete -o default -F _git_merge_base git-merge-base.exe
complete -o default -F _git_name_rev git-name-rev.exe
complete -o default -o nospace -F _git_push git-push.exe
-complete -o default -F _git_repo_config git-repo-config
+complete -o default -F _git_config git-config
complete -o default -o nospace -F _git_show git-show.exe
complete -o default -o nospace -F _git_log git-show-branch.exe
complete -o default -o nospace -F _git_log git-whatchanged.exe
diff --git a/contrib/emacs/git.el b/contrib/emacs/git.el
index d90ba81..24629eb 100644
--- a/contrib/emacs/git.el
+++ b/contrib/emacs/git.el
@@ -222,7 +222,7 @@ and returns the process output as a string."
"Return the name to use as GIT_COMMITTER_NAME."
; copied from log-edit
(or git-committer-name
- (git-repo-config "user.name")
+ (git-config "user.name")
(and (boundp 'add-log-full-name) add-log-full-name)
(and (fboundp 'user-full-name) (user-full-name))
(and (boundp 'user-full-name) user-full-name)))
@@ -231,7 +231,7 @@ and returns the process output as a string."
"Return the email address to use as GIT_COMMITTER_EMAIL."
; copied from log-edit
(or git-committer-email
- (git-repo-config "user.email")
+ (git-config "user.email")
(and (boundp 'add-log-mailing-address) add-log-mailing-address)
(and (fboundp 'user-mail-address) (user-mail-address))
(and (boundp 'user-mail-address) user-mail-address)))
@@ -298,9 +298,9 @@ and returns the process output as a string."
(git-get-string-sha1
(git-call-process-env-string nil "rev-parse" rev)))
-(defun git-repo-config (key)
+(defun git-config (key)
"Retrieve the value associated to KEY in the git repository config file."
- (let ((str (git-call-process-env-string nil "repo-config" key)))
+ (let ((str (git-call-process-env-string nil "config" key)))
(and str (car (split-string str "\n")))))
(defun git-symbolic-ref (ref)
diff --git a/contrib/gitview/gitview b/contrib/gitview/gitview
index 3b6bdce..521b2fc 100755
--- a/contrib/gitview/gitview
+++ b/contrib/gitview/gitview
@@ -497,7 +497,7 @@ class GitView:
fp.close()
def get_encoding(self):
- fp = os.popen("git repo-config --get i18n.commitencoding")
+ fp = os.popen("git config --get i18n.commitencoding")
self.encoding=string.strip(fp.readline())
fp.close()
if (self.encoding == ""):
diff --git a/contrib/remotes2config.sh b/contrib/remotes2config.sh
index b996996..dc09eae 100644
--- a/contrib/remotes2config.sh
+++ b/contrib/remotes2config.sh
@@ -26,8 +26,8 @@ if [ -d "$GIT_DIR"/remotes ]; then
mv "$GIT_DIR"/remotes "$GIT_DIR"/remotes.old
fi ;;
*)
- echo "git-repo-config $key "$value" $regex"
- git-repo-config $key "$value" $regex || error=1 ;;
+ echo "git-config $key "$value" $regex"
+ git-config $key "$value" $regex || error=1 ;;
esac
done
fi
diff --git a/git-clone.sh b/git-clone.sh
index ced7dfb..1531da5 100755
--- a/git-clone.sh
+++ b/git-clone.sh
@@ -36,7 +36,7 @@ clone_dumb_http () {
clone_tmp="$GIT_DIR/clone-tmp" &&
mkdir -p "$clone_tmp" || exit 1
if [ -n "$GIT_CURL_FTP_NO_EPSV" -o \
- "`git-repo-config --bool http.noEPSV`" = true ]; then
+ "`git-config --bool http.noEPSV`" = true ]; then
curl_extra_args="${curl_extra_args} --disable-epsv"
fi
http_fetch "$1/info/refs" "$clone_tmp/refs" ||
@@ -386,17 +386,17 @@ then
git-update-ref HEAD "$head_sha1" &&
# Upstream URL
- git-repo-config remote."$origin".url "$repo" &&
+ git-config remote."$origin".url "$repo" &&
# Set up the mappings to track the remote branches.
- git-repo-config remote."$origin".fetch \
+ git-config remote."$origin".fetch \
"+refs/heads/*:$remote_top/*" '^$' &&
rm -f "refs/remotes/$origin/HEAD"
git-symbolic-ref "refs/remotes/$origin/HEAD" \
"refs/remotes/$origin/$head_points_at" &&
- git-repo-config branch."$head_points_at".remote "$origin" &&
- git-repo-config branch."$head_points_at".merge "refs/heads/$head_points_at"
+ git-config branch."$head_points_at".remote "$origin" &&
+ git-config branch."$head_points_at".merge "refs/heads/$head_points_at"
esac
case "$no_checkout" in
diff --git a/git-commit.sh b/git-commit.sh
index d8c236b..85c278a 100755
--- a/git-commit.sh
+++ b/git-commit.sh
@@ -429,7 +429,7 @@ then
fi
elif test "$use_commit" != ""
then
- encoding=$(git repo-config i18n.commitencoding || echo UTF-8)
+ encoding=$(git config i18n.commitencoding || echo UTF-8)
git show -s --pretty=raw --encoding="$encoding" "$use_commit" |
sed -e '1,/^$/d' -e 's/^ //'
elif test -f "$GIT_DIR/MERGE_MSG"
@@ -485,7 +485,7 @@ then
q
}
'
- encoding=$(git repo-config i18n.commitencoding || echo UTF-8)
+ encoding=$(git config i18n.commitencoding || echo UTF-8)
set_author_env=`git show -s --pretty=raw --encoding="$encoding" "$use_commit" |
LANG=C LC_ALL=C sed -ne "$pick_author_script"`
eval "$set_author_env"
diff --git a/git-cvsserver.perl b/git-cvsserver.perl
index e18e901..9371788 100755
--- a/git-cvsserver.perl
+++ b/git-cvsserver.perl
@@ -172,11 +172,11 @@ sub req_Root
return 0;
}
- my @gitvars = `git-repo-config -l`;
+ my @gitvars = `git-config -l`;
if ($?) {
- print "E problems executing git-repo-config on the server -- this is not a git repository or the PATH is not set correctly.\n";
+ print "E problems executing git-config on the server -- this is not a git repository or the PATH is not set correctly.\n";
print "E \n";
- print "error 1 - problem executing git-repo-config\n";
+ print "error 1 - problem executing git-config\n";
return 0;
}
foreach my $line ( @gitvars )
diff --git a/git-fetch.sh b/git-fetch.sh
index 61c8cf4..c1f6e1e 100755
--- a/git-fetch.sh
+++ b/git-fetch.sh
@@ -321,7 +321,7 @@ fetch_main () {
curl_extra_args="-k"
fi
if [ -n "$GIT_CURL_FTP_NO_EPSV" -o \
- "`git-repo-config --bool http.noEPSV`" = true ]; then
+ "`git-config --bool http.noEPSV`" = true ]; then
noepsv_opt="--disable-epsv"
fi
diff --git a/git-instaweb.sh b/git-instaweb.sh
index 80adc83..cbc7418 100755
--- a/git-instaweb.sh
+++ b/git-instaweb.sh
@@ -15,11 +15,11 @@ case "$GIT_DIR" in
fqgitdir="$PWD/$GIT_DIR" ;;
esac
-local="`git repo-config --bool --get instaweb.local`"
-httpd="`git repo-config --get instaweb.httpd`"
-browser="`git repo-config --get instaweb.browser`"
-port=`git repo-config --get instaweb.port`
-module_path="`git repo-config --get instaweb.modulepath`"
+local="`git config --bool --get instaweb.local`"
+httpd="`git config --get instaweb.httpd`"
+browser="`git config --get instaweb.browser`"
+port=`git config --get instaweb.port`
+module_path="`git config --get instaweb.modulepath`"
conf=$GIT_DIR/gitweb/httpd.conf
diff --git a/git-ls-remote.sh b/git-ls-remote.sh
index dd22783..e6f574b 100755
--- a/git-ls-remote.sh
+++ b/git-ls-remote.sh
@@ -58,7 +58,7 @@ http://* | https://* | ftp://* )
curl_extra_args="-k"
fi
if [ -n "$GIT_CURL_FTP_NO_EPSV" -o \
- "`git-repo-config --bool http.noEPSV`" = true ]; then
+ "`git-config --bool http.noEPSV`" = true ]; then
curl_extra_args="${curl_extra_args} --disable-epsv"
fi
curl -nsf $curl_extra_args --header "Pragma: no-cache" "$peek_repo/info/refs" ||
diff --git a/git-merge.sh b/git-merge.sh
index 7b59026..e5d6229 100755
--- a/git-merge.sh
+++ b/git-merge.sh
@@ -233,7 +233,7 @@ case "$use_strategies" in
'')
case "$#" in
1)
- var="`git-repo-config --get pull.twohead`"
+ var="`git-config --get pull.twohead`"
if test -n "$var"
then
use_strategies="$var"
@@ -241,7 +241,7 @@ case "$use_strategies" in
use_strategies="$default_twohead_strategies"
fi ;;
*)
- var="`git-repo-config --get pull.octopus`"
+ var="`git-config --get pull.octopus`"
if test -n "$var"
then
use_strategies="$var"
diff --git a/git-p4import.py b/git-p4import.py
index 5c56cac..60a758b 100644
--- a/git-p4import.py
+++ b/git-p4import.py
@@ -193,13 +193,13 @@ class git_command:
def get_config(self, variable):
try:
- return self.git("repo-config --get %s" % variable)[0].rstrip()
+ return self.git("config --get %s" % variable)[0].rstrip()
except:
return None
def set_config(self, variable, value):
try:
- self.git("repo-config %s %s"%(variable, value) )
+ self.git("config %s %s"%(variable, value) )
except:
die("Could not set %s to " % variable, value)
diff --git a/git-parse-remote.sh b/git-parse-remote.sh
index 1122c83..87864fb 100755
--- a/git-parse-remote.sh
+++ b/git-parse-remote.sh
@@ -10,7 +10,7 @@ get_data_source () {
echo ''
;;
*)
- if test "$(git-repo-config --get "remote.$1.url")"
+ if test "$(git-config --get "remote.$1.url")"
then
echo config
elif test -f "$GIT_DIR/remotes/$1"
@@ -32,7 +32,7 @@ get_remote_url () {
echo "$1"
;;
config)
- git-repo-config --get "remote.$1.url"
+ git-config --get "remote.$1.url"
;;
remotes)
sed -ne '/^URL: */{
@@ -50,7 +50,7 @@ get_remote_url () {
get_default_remote () {
curr_branch=$(git-symbolic-ref -q HEAD | sed -e 's|^refs/heads/||')
- origin=$(git-repo-config --get "branch.$curr_branch.remote")
+ origin=$(git-config --get "branch.$curr_branch.remote")
echo ${origin:-origin}
}
@@ -60,7 +60,7 @@ get_remote_default_refs_for_push () {
'' | branches)
;; # no default push mapping, just send matching refs.
config)
- git-repo-config --get-all "remote.$1.push" ;;
+ git-config --get-all "remote.$1.push" ;;
remotes)
sed -ne '/^Push: */{
s///p
@@ -139,7 +139,7 @@ canon_refs_list_for_fetch () {
then
curr_branch=$(git-symbolic-ref -q HEAD | \
sed -e 's|^refs/heads/||')
- merge_branches=$(git-repo-config \
+ merge_branches=$(git-config \
--get-all "branch.${curr_branch}.merge")
fi
if test -z "$merge_branches" && test $is_explicit != explicit
@@ -205,7 +205,7 @@ get_remote_default_refs_for_fetch () {
echo "HEAD:" ;;
config)
canon_refs_list_for_fetch -d "$1" \
- $(git-repo-config --get-all "remote.$1.fetch") ;;
+ $(git-config --get-all "remote.$1.fetch") ;;
branches)
remote_branch=$(sed -ne '/#/s/.*#//p' "$GIT_DIR/branches/$1")
case "$remote_branch" in '') remote_branch=master ;; esac
@@ -284,7 +284,7 @@ get_uploadpack () {
data_source=$(get_data_source "$1")
case "$data_source" in
config)
- uplp=$(git-repo-config --get "remote.$1.uploadpack")
+ uplp=$(git-config --get "remote.$1.uploadpack")
echo ${uplp:-git-upload-pack}
;;
*)
diff --git a/git-remote.perl b/git-remote.perl
index fc055b6..c813fe1 100755
--- a/git-remote.perl
+++ b/git-remote.perl
@@ -64,7 +64,7 @@ sub list_remote {
my ($git) = @_;
my %seen = ();
my @remotes = eval {
- $git->command(qw(repo-config --get-regexp), '^remote\.');
+ $git->command(qw(config --get-regexp), '^remote\.');
};
for (@remotes) {
if (/^remote\.([^.]*)\.(\S*)\s+(.*)$/) {
@@ -103,7 +103,7 @@ sub list_branch {
my ($git) = @_;
my %seen = ();
my @branches = eval {
- $git->command(qw(repo-config --get-regexp), '^branch\.');
+ $git->command(qw(config --get-regexp), '^branch\.');
};
for (@branches) {
if (/^branch\.([^.]*)\.(\S*)\s+(.*)$/) {
@@ -238,8 +238,8 @@ sub add_remote {
print STDERR "remote $name already exists.\n";
exit(1);
}
- $git->command('repo-config', "remote.$name.url", $url);
- $git->command('repo-config', "remote.$name.fetch",
+ $git->command('config', "remote.$name.url", $url);
+ $git->command('config', "remote.$name.fetch",
"+refs/heads/*:refs/remotes/$name/*");
}
diff --git a/git-repack.sh b/git-repack.sh
index da8e67f..ddfa8b4 100755
--- a/git-repack.sh
+++ b/git-repack.sh
@@ -28,7 +28,7 @@ done
# Later we will default repack.UseDeltaBaseOffset to true
default_dbo=false
-case "`git repo-config --bool repack.usedeltabaseoffset ||
+case "`git config --bool repack.usedeltabaseoffset ||
echo $default_dbo`" in
true)
extra="$extra --delta-base-offset" ;;
diff --git a/git-revert.sh b/git-revert.sh
index bb8f1ca..866d622 100755
--- a/git-revert.sh
+++ b/git-revert.sh
@@ -81,7 +81,7 @@ prev=$(git-rev-parse --verify "$commit^1" 2>/dev/null) ||
git-rev-parse --verify "$commit^2" >/dev/null 2>&1 &&
die "Cannot run $me a multi-parent commit."
-encoding=$(git repo-config i18n.commitencoding || echo UTF-8)
+encoding=$(git config i18n.commitencoding || echo UTF-8)
# "commit" is an existing commit. We would want to apply
# the difference it introduces since its first parent "prev"
diff --git a/git-sh-setup.sh b/git-sh-setup.sh
index 6b1c142..b4aa4b2 100755
--- a/git-sh-setup.sh
+++ b/git-sh-setup.sh
@@ -29,7 +29,7 @@ set_reflog_action() {
}
is_bare_repository () {
- git-repo-config --bool --get core.bare ||
+ git-config --bool --get core.bare ||
case "$GIT_DIR" in
.git | */.git) echo false ;;
*) echo true ;;
diff --git a/git-svn.perl b/git-svn.perl
index 83ec03d..68156fc 100755
--- a/git-svn.perl
+++ b/git-svn.perl
@@ -593,7 +593,7 @@ sub multi_init {
"$trunk_url ($_trunk)\n";
}
init($trunk_url);
- command_noisy('repo-config', 'svn.trunk', $trunk_url);
+ command_noisy('config', 'svn.trunk', $trunk_url);
}
}
$_prefix = '' unless defined $_prefix;
@@ -772,22 +772,22 @@ sub log_use_color {
return 1 if $_color;
my ($dc, $dcvar);
$dcvar = 'color.diff';
- $dc = `git-repo-config --get $dcvar`;
+ $dc = `git-config --get $dcvar`;
if ($dc eq '') {
# nothing at all; fallback to "diff.color"
$dcvar = 'diff.color';
- $dc = `git-repo-config --get $dcvar`;
+ $dc = `git-config --get $dcvar`;
}
chomp($dc);
if ($dc eq 'auto') {
my $pc;
- $pc = `git-repo-config --get color.pager`;
+ $pc = `git-config --get color.pager`;
if ($pc eq '') {
# does not have it -- fallback to pager.color
- $pc = `git-repo-config --bool --get pager.color`;
+ $pc = `git-config --bool --get pager.color`;
}
else {
- $pc = `git-repo-config --bool --get color.pager`;
+ $pc = `git-config --bool --get color.pager`;
if ($?) {
$pc = 'false';
}
@@ -800,7 +800,7 @@ sub log_use_color {
}
return 0 if $dc eq 'never';
return 1 if $dc eq 'always';
- chomp($dc = `git-repo-config --bool --get $dcvar`);
+ chomp($dc = `git-config --bool --get $dcvar`);
return ($dc eq 'true');
}
@@ -919,7 +919,7 @@ sub complete_url_ls_init {
waitpid $pid, 0;
croak $? if $?;
my ($n) = ($switch =~ /^--(\w+)/);
- command_noisy('repo-config', "svn.$n", $full_url);
+ command_noisy('config', "svn.$n", $full_url);
}
sub common_prefix {
@@ -1594,7 +1594,7 @@ sub init_vars {
%tree_map = ();
}
-# convert GetOpt::Long specs for use by git-repo-config
+# convert GetOpt::Long specs for use by git-config
sub read_repo_config {
return unless -d $GIT_DIR;
my $opts = shift;
@@ -1602,7 +1602,7 @@ sub read_repo_config {
my $v = $opts->{$o};
my ($key) = ($o =~ /^([a-z\-]+)/);
$key =~ s/-//g;
- my $arg = 'git-repo-config';
+ my $arg = 'git-config';
$arg .= ' --int' if ($o =~ /[:=]i$/);
$arg .= ' --bool' if ($o !~ /[:=][sfi]$/);
if (ref $v eq 'ARRAY') {
diff --git a/git.c b/git.c
index 530e99f..ec91acd 100644
--- a/git.c
+++ b/git.c
@@ -224,6 +224,7 @@ static void handle_internal_command(int argc, const char **argv, char **envp)
{ "check-ref-format", cmd_check_ref_format },
{ "cherry", cmd_cherry, RUN_SETUP },
{ "commit-tree", cmd_commit_tree, RUN_SETUP },
+ { "config", cmd_config },
{ "count-objects", cmd_count_objects, RUN_SETUP },
{ "describe", cmd_describe, RUN_SETUP },
{ "diff", cmd_diff, RUN_SETUP | USE_PAGER },
@@ -254,7 +255,7 @@ static void handle_internal_command(int argc, const char **argv, char **envp)
{ "push", cmd_push, RUN_SETUP },
{ "read-tree", cmd_read_tree, RUN_SETUP },
{ "reflog", cmd_reflog, RUN_SETUP },
- { "repo-config", cmd_repo_config },
+ { "repo-config", cmd_config },
{ "rerere", cmd_rerere, RUN_SETUP },
{ "rev-list", cmd_rev_list, RUN_SETUP },
{ "rev-parse", cmd_rev_parse, RUN_SETUP },
diff --git a/gitk b/gitk
index 031c829..31d0aad 100755
--- a/gitk
+++ b/gitk
@@ -6193,7 +6193,7 @@ set wrcomcmd "git diff-tree --stdin -p --pretty"
set gitencoding {}
catch {
- set gitencoding [exec git repo-config --get i18n.commitencoding]
+ set gitencoding [exec git config --get i18n.commitencoding]
}
if {$gitencoding == ""} {
set gitencoding "utf-8"
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index 88af2e6..b606c1d 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -986,7 +986,7 @@ sub git_get_project_config {
$key =~ s/^gitweb\.//;
return if ($key =~ m/\W/);
- my @x = (git_cmd(), 'repo-config');
+ my @x = (git_cmd(), 'config');
if (defined $type) { push @x, $type; }
push @x, "--get";
push @x, "gitweb.$key";
diff --git a/ident.c b/ident.c
index 6ad8fed..92d34e0 100644
--- a/ident.c
+++ b/ident.c
@@ -160,8 +160,8 @@ static const char *env_hint =
"\n"
"Run\n"
"\n"
-" git repo-config user.email \"you@email.com\"\n"
-" git repo-config user.name \"Your Name\"\n"
+" git config user.email \"you@email.com\"\n"
+" git config user.name \"Your Name\"\n"
"\n"
"To set the identity in this repository.\n"
"Add --global to set your account\'s default\n"
diff --git a/perl/Git.pm b/perl/Git.pm
index c1729ba..5d1ccaa 100644
--- a/perl/Git.pm
+++ b/perl/Git.pm
@@ -482,14 +482,14 @@ sub wc_chdir {
=item config ( VARIABLE )
-Retrieve the configuration C<VARIABLE> in the same manner as C<repo-config>
+Retrieve the configuration C<VARIABLE> in the same manner as C<config>
does. In scalar context requires the variable to be set only one time
(exception is thrown otherwise), in array context returns allows the
variable to be set multiple times and returns all the values.
Must be called on a repository instance.
-This currently wraps command('repo-config') so it is not so fast.
+This currently wraps command('config') so it is not so fast.
=cut
@@ -500,9 +500,9 @@ sub config {
try {
if (wantarray) {
- return $self->command('repo-config', '--get-all', $var);
+ return $self->command('config', '--get-all', $var);
} else {
- return $self->command_oneline('repo-config', '--get', $var);
+ return $self->command_oneline('config', '--get', $var);
}
} catch Git::Error::Command with {
my $E = shift;
diff --git a/t/t1300-repo-config.sh b/t/t1300-repo-config.sh
index 0e4f32d..49b5666 100755
--- a/t/t1300-repo-config.sh
+++ b/t/t1300-repo-config.sh
@@ -3,13 +3,13 @@
# Copyright (c) 2005 Johannes Schindelin
#
-test_description='Test git-repo-config in different settings'
+test_description='Test git-config in different settings'
. ./test-lib.sh
test -f .git/config && rm .git/config
-git-repo-config core.penguin "little blue"
+git-config core.penguin "little blue"
cat > expect << EOF
[core]
@@ -18,7 +18,7 @@ EOF
test_expect_success 'initial' 'cmp .git/config expect'
-git-repo-config Core.Movie BadPhysics
+git-config Core.Movie BadPhysics
cat > expect << EOF
[core]
@@ -28,7 +28,7 @@ EOF
test_expect_success 'mixed case' 'cmp .git/config expect'
-git-repo-config Cores.WhatEver Second
+git-config Cores.WhatEver Second
cat > expect << EOF
[core]
@@ -40,7 +40,7 @@ EOF
test_expect_success 'similar section' 'cmp .git/config expect'
-git-repo-config CORE.UPPERCASE true
+git-config CORE.UPPERCASE true
cat > expect << EOF
[core]
@@ -54,10 +54,10 @@ EOF
test_expect_success 'similar section' 'cmp .git/config expect'
test_expect_success 'replace with non-match' \
- 'git-repo-config core.penguin kingpin !blue'
+ 'git-config core.penguin kingpin !blue'
test_expect_success 'replace with non-match (actually matching)' \
- 'git-repo-config core.penguin "very blue" !kingpin'
+ 'git-config core.penguin "very blue" !kingpin'
cat > expect << EOF
[core]
@@ -86,7 +86,7 @@ EOF
cp .git/config .git/config2
test_expect_success 'multiple unset' \
- 'git-repo-config --unset-all beta.haha'
+ 'git-config --unset-all beta.haha'
cat > expect << EOF
[beta] ; silly comment # another comment
@@ -102,7 +102,7 @@ test_expect_success 'multiple unset is correct' 'cmp .git/config expect'
mv .git/config2 .git/config
test_expect_success '--replace-all' \
- 'git-repo-config --replace-all beta.haha gamma'
+ 'git-config --replace-all beta.haha gamma'
cat > expect << EOF
[beta] ; silly comment # another comment
@@ -116,7 +116,7 @@ EOF
test_expect_success 'all replaced' 'cmp .git/config expect'
-git-repo-config beta.haha alpha
+git-config beta.haha alpha
cat > expect << EOF
[beta] ; silly comment # another comment
@@ -130,7 +130,7 @@ EOF
test_expect_success 'really mean test' 'cmp .git/config expect'
-git-repo-config nextsection.nonewline wow
+git-config nextsection.nonewline wow
cat > expect << EOF
[beta] ; silly comment # another comment
@@ -145,8 +145,8 @@ EOF
test_expect_success 'really really mean test' 'cmp .git/config expect'
-test_expect_success 'get value' 'test alpha = $(git-repo-config beta.haha)'
-git-repo-config --unset beta.haha
+test_expect_success 'get value' 'test alpha = $(git-config beta.haha)'
+git-config --unset beta.haha
cat > expect << EOF
[beta] ; silly comment # another comment
@@ -160,7 +160,7 @@ EOF
test_expect_success 'unset' 'cmp .git/config expect'
-git-repo-config nextsection.NoNewLine "wow2 for me" "for me$"
+git-config nextsection.NoNewLine "wow2 for me" "for me$"
cat > expect << EOF
[beta] ; silly comment # another comment
@@ -176,18 +176,18 @@ EOF
test_expect_success 'multivar' 'cmp .git/config expect'
test_expect_success 'non-match' \
- 'git-repo-config --get nextsection.nonewline !for'
+ 'git-config --get nextsection.nonewline !for'
test_expect_success 'non-match value' \
- 'test wow = $(git-repo-config --get nextsection.nonewline !for)'
+ 'test wow = $(git-config --get nextsection.nonewline !for)'
test_expect_failure 'ambiguous get' \
- 'git-repo-config --get nextsection.nonewline'
+ 'git-config --get nextsection.nonewline'
test_expect_success 'get multivar' \
- 'git-repo-config --get-all nextsection.nonewline'
+ 'git-config --get-all nextsection.nonewline'
-git-repo-config nextsection.nonewline "wow3" "wow$"
+git-config nextsection.nonewline "wow3" "wow$"
cat > expect << EOF
[beta] ; silly comment # another comment
@@ -202,15 +202,15 @@ EOF
test_expect_success 'multivar replace' 'cmp .git/config expect'
-test_expect_failure 'ambiguous value' 'git-repo-config nextsection.nonewline'
+test_expect_failure 'ambiguous value' 'git-config nextsection.nonewline'
test_expect_failure 'ambiguous unset' \
- 'git-repo-config --unset nextsection.nonewline'
+ 'git-config --unset nextsection.nonewline'
test_expect_failure 'invalid unset' \
- 'git-repo-config --unset somesection.nonewline'
+ 'git-config --unset somesection.nonewline'
-git-repo-config --unset nextsection.nonewline "wow3$"
+git-config --unset nextsection.nonewline "wow3$"
cat > expect << EOF
[beta] ; silly comment # another comment
@@ -224,12 +224,12 @@ EOF
test_expect_success 'multivar unset' 'cmp .git/config expect'
-test_expect_failure 'invalid key' 'git-repo-config inval.2key blabla'
+test_expect_failure 'invalid key' 'git-config inval.2key blabla'
-test_expect_success 'correct key' 'git-repo-config 123456.a123 987'
+test_expect_success 'correct key' 'git-config 123456.a123 987'
test_expect_success 'hierarchical section' \
- 'git-repo-config Version.1.2.3eX.Alpha beta'
+ 'git-config Version.1.2.3eX.Alpha beta'
cat > expect << EOF
[beta] ; silly comment # another comment
@@ -255,7 +255,7 @@ version.1.2.3eX.alpha=beta
EOF
test_expect_success 'working --list' \
- 'git-repo-config --list > output && cmp output expect'
+ 'git-config --list > output && cmp output expect'
cat > expect << EOF
beta.noindent sillyValue
@@ -263,9 +263,9 @@ nextsection.nonewline wow2 for me
EOF
test_expect_success '--get-regexp' \
- 'git-repo-config --get-regexp in > output && cmp output expect'
+ 'git-config --get-regexp in > output && cmp output expect'
-git-repo-config --add nextsection.nonewline "wow4 for you"
+git-config --add nextsection.nonewline "wow4 for you"
cat > expect << EOF
wow2 for me
@@ -273,7 +273,7 @@ wow4 for you
EOF
test_expect_success '--add' \
- 'git-repo-config --get-all nextsection.nonewline > output && cmp output expect'
+ 'git-config --get-all nextsection.nonewline > output && cmp output expect'
cat > .git/config << EOF
[novalue]
@@ -281,9 +281,9 @@ cat > .git/config << EOF
EOF
test_expect_success 'get variable with no value' \
- 'git-repo-config --get novalue.variable ^$'
+ 'git-config --get novalue.variable ^$'
-git-repo-config > output 2>&1
+git-config > output 2>&1
test_expect_success 'no arguments, but no crash' \
"test $? = 129 && grep usage output"
@@ -293,7 +293,7 @@ cat > .git/config << EOF
c = d
EOF
-git-repo-config a.x y
+git-config a.x y
cat > expect << EOF
[a.b]
@@ -304,8 +304,8 @@ EOF
test_expect_success 'new section is partial match of another' 'cmp .git/config expect'
-git-repo-config b.x y
-git-repo-config a.b c
+git-config b.x y
+git-config a.b c
cat > expect << EOF
[a.b]
@@ -328,11 +328,11 @@ cat > expect << EOF
ein.bahn=strasse
EOF
-GIT_CONFIG=other-config git-repo-config -l > output
+GIT_CONFIG=other-config git-config -l > output
test_expect_success 'alternative GIT_CONFIG' 'cmp output expect'
-GIT_CONFIG=other-config git-repo-config anwohner.park ausweis
+GIT_CONFIG=other-config git-config anwohner.park ausweis
cat > expect << EOF
[ein]
@@ -355,7 +355,7 @@ weird
EOF
test_expect_success "rename section" \
- "git-repo-config --rename-section branch.eins branch.zwei"
+ "git-config --rename-section branch.eins branch.zwei"
cat > expect << EOF
# Hallo
@@ -371,12 +371,12 @@ EOF
test_expect_success "rename succeeded" "diff -u expect .git/config"
test_expect_failure "rename non-existing section" \
- 'git-repo-config --rename-section branch."world domination" branch.drei'
+ 'git-config --rename-section branch."world domination" branch.drei'
test_expect_success "rename succeeded" "diff -u expect .git/config"
test_expect_success "rename another section" \
- 'git-repo-config --rename-section branch."1 234 blabl/a" branch.drei'
+ 'git-config --rename-section branch."1 234 blabl/a" branch.drei'
cat > expect << EOF
# Hallo
@@ -393,20 +393,20 @@ test_expect_success "rename succeeded" "diff -u expect .git/config"
test_expect_success numbers '
- git-repo-config kilo.gram 1k &&
- git-repo-config mega.ton 1m &&
- k=$(git-repo-config --int --get kilo.gram) &&
+ git-config kilo.gram 1k &&
+ git-config mega.ton 1m &&
+ k=$(git-config --int --get kilo.gram) &&
test z1024 = "z$k" &&
- m=$(git-repo-config --int --get mega.ton) &&
+ m=$(git-config --int --get mega.ton) &&
test z1048576 = "z$m"
'
rm .git/config
-git-repo-config quote.leading " test"
-git-repo-config quote.ending "test "
-git-repo-config quote.semicolon "test;test"
-git-repo-config quote.hash "test#test"
+git-config quote.leading " test"
+git-config quote.ending "test "
+git-config quote.semicolon "test;test"
+git-config quote.hash "test#test"
cat > expect << EOF
[quote]
@@ -418,10 +418,10 @@ EOF
test_expect_success 'quoting' 'cmp .git/config expect'
-test_expect_failure 'key with newline' 'git repo-config key.with\\\
+test_expect_failure 'key with newline' 'git config key.with\\\
newline 123'
-test_expect_success 'value with newline' 'git repo-config key.sub value.with\\\
+test_expect_success 'value with newline' 'git config key.sub value.with\\\
newline'
cat > .git/config <<\EOF
@@ -440,7 +440,7 @@ section.noncont=not continued
section.quotecont=cont;inued
EOF
-git repo-config --list > result
+git config --list > result
test_expect_success 'value continued on next line' 'cmp result expect'
diff --git a/t/t1400-update-ref.sh b/t/t1400-update-ref.sh
index e48e2b7..d0aba2c 100755
--- a/t/t1400-update-ref.sh
+++ b/t/t1400-update-ref.sh
@@ -93,8 +93,8 @@ rm -rf .git/$m .git/logs expect
test_expect_success \
'enable core.logAllRefUpdates' \
- 'git-repo-config core.logAllRefUpdates true &&
- test true = $(git-repo-config --bool --get core.logAllRefUpdates)'
+ 'git-config core.logAllRefUpdates true &&
+ test true = $(git-config --bool --get core.logAllRefUpdates)'
test_expect_success \
"create $m (logged by config)" \
diff --git a/t/t1410-reflog.sh b/t/t1410-reflog.sh
index 8e8d526..47d1247 100755
--- a/t/t1410-reflog.sh
+++ b/t/t1410-reflog.sh
@@ -71,7 +71,7 @@ test_expect_success setup '
check_fsck &&
chmod +x C &&
- ( test "`git repo-config --bool core.filemode`" != false ||
+ ( test "`git config --bool core.filemode`" != false ||
echo executable >>C ) &&
git add C &&
test_tick && git commit -m dragon &&
diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh
index bb80e42..5565c27 100755
--- a/t/t3200-branch.sh
+++ b/t/t3200-branch.sh
@@ -94,7 +94,7 @@ test_expect_failure \
git-branch r &&
git-branch -m q r/q'
-git-repo-config branch.s/s.dummy Hello
+git-config branch.s/s.dummy Hello
test_expect_success \
'git branch -m s/s s should work when s/t is deleted' \
@@ -107,8 +107,8 @@ test_expect_success \
test -f .git/logs/refs/heads/s'
test_expect_success 'config information was renamed, too' \
- "test $(git-repo-config branch.s.dummy) = Hello &&
- ! git-repo-config branch.s/s/dummy"
+ "test $(git-config branch.s.dummy) = Hello &&
+ ! git-config branch.s/s/dummy"
test_expect_failure \
'git-branch -m u v should fail when the reflog for u is a symlink' \
diff --git a/t/t3700-add.sh b/t/t3700-add.sh
index e98786d..caaab26 100755
--- a/t/t3700-add.sh
+++ b/t/t3700-add.sh
@@ -21,7 +21,7 @@ test_expect_success \
test_expect_success \
'git-add: Test that executable bit is not used if core.filemode=0' \
- 'git repo-config core.filemode 0 &&
+ 'git config core.filemode 0 &&
echo foo >xfoo1 &&
chmod 755 xfoo1 &&
git-add xfoo1 &&
@@ -32,7 +32,7 @@ test_expect_success \
test_expect_success \
'git-update-index --add: Test that executable bit is not used...' \
- 'git repo-config core.filemode 0 &&
+ 'git config core.filemode 0 &&
echo foo >xfoo2 &&
chmod 755 xfoo2 &&
git-update-index --add xfoo2 &&
@@ -43,7 +43,7 @@ test_expect_success \
test_expect_success \
'git-update-index --add: Test that executable bit is not used...' \
- 'git repo-config core.filemode 0 &&
+ 'git config core.filemode 0 &&
ln -s xfoo2 xfoo3 &&
git-update-index --add xfoo3 &&
case "`git-ls-files --stage xfoo3`" in
diff --git a/t/t3900-i18n-commit.sh b/t/t3900-i18n-commit.sh
index 6714b0d..e54fe0f 100755
--- a/t/t3900-i18n-commit.sh
+++ b/t/t3900-i18n-commit.sh
@@ -29,7 +29,7 @@ test_expect_success 'no encoding header for base case' '
for H in ISO-8859-1 EUCJP ISO-2022-JP
do
test_expect_success "$H setup" '
- git-repo-config i18n.commitencoding $H &&
+ git-config i18n.commitencoding $H &&
git-checkout -b $H C0 &&
echo $H >F &&
git-commit -a -F ../t3900/$H.txt
@@ -44,16 +44,16 @@ do
'
done
-test_expect_success 'repo-config to remove customization' '
- git-repo-config --unset-all i18n.commitencoding &&
- if Z=$(git-repo-config --get-all i18n.commitencoding)
+test_expect_success 'config to remove customization' '
+ git-config --unset-all i18n.commitencoding &&
+ if Z=$(git-config --get-all i18n.commitencoding)
then
echo Oops, should have failed.
false
else
test z = "z$Z"
fi &&
- git-repo-config i18n.commitencoding utf-8
+ git-config i18n.commitencoding utf-8
'
test_expect_success 'ISO-8859-1 should be shown in UTF-8 now' '
@@ -67,9 +67,9 @@ do
'
done
-test_expect_success 'repo-config to add customization' '
- git-repo-config --unset-all i18n.commitencoding &&
- if Z=$(git-repo-config --get-all i18n.commitencoding)
+test_expect_success 'config to add customization' '
+ git-config --unset-all i18n.commitencoding &&
+ if Z=$(git-config --get-all i18n.commitencoding)
then
echo Oops, should have failed.
false
@@ -81,13 +81,13 @@ test_expect_success 'repo-config to add customization' '
for H in ISO-8859-1 EUCJP ISO-2022-JP
do
test_expect_success "$H should be shown in itself now" '
- git-repo-config i18n.commitencoding '$H' &&
+ git-config i18n.commitencoding '$H' &&
compare_with '$H' ../t3900/'$H'.txt
'
done
-test_expect_success 'repo-config to tweak customization' '
- git-repo-config i18n.logoutputencoding utf-8
+test_expect_success 'config to tweak customization' '
+ git-config i18n.logoutputencoding utf-8
'
test_expect_success 'ISO-8859-1 should be shown in UTF-8 now' '
@@ -103,7 +103,7 @@ done
for J in EUCJP ISO-2022-JP
do
- git-repo-config i18n.logoutputencoding $J
+ git-config i18n.logoutputencoding $J
for H in EUCJP ISO-2022-JP
do
test_expect_success "$H should be shown in $J now" '
diff --git a/t/t3901-i18n-patch.sh b/t/t3901-i18n-patch.sh
index eda0e2d..a881797 100755
--- a/t/t3901-i18n-patch.sh
+++ b/t/t3901-i18n-patch.sh
@@ -31,7 +31,7 @@ check_encoding () {
}
test_expect_success setup '
- git-repo-config i18n.commitencoding UTF-8 &&
+ git-config i18n.commitencoding UTF-8 &&
# use UTF-8 in author and committer name to match the
# i18n.commitencoding settings
@@ -55,7 +55,7 @@ test_expect_success setup '
git commit -s -m "Second on side" &&
# the second one on the side branch is ISO-8859-1
- git-repo-config i18n.commitencoding ISO-8859-1 &&
+ git-config i18n.commitencoding ISO-8859-1 &&
# use author and committer name in ISO-8859-1 to match it.
. ../t3901-8859-1.txt &&
test_tick &&
@@ -64,11 +64,11 @@ test_expect_success setup '
git commit -s -m "Third on side" &&
# Back to default
- git-repo-config i18n.commitencoding UTF-8
+ git-config i18n.commitencoding UTF-8
'
test_expect_success 'format-patch output (ISO-8859-1)' '
- git-repo-config i18n.logoutputencoding ISO-8859-1 &&
+ git-config i18n.logoutputencoding ISO-8859-1 &&
git format-patch --stdout master..HEAD^ >out-l1 &&
git format-patch --stdout HEAD^ >out-l2 &&
@@ -79,7 +79,7 @@ test_expect_success 'format-patch output (ISO-8859-1)' '
'
test_expect_success 'format-patch output (UTF-8)' '
- git repo-config i18n.logoutputencoding UTF-8 &&
+ git config i18n.logoutputencoding UTF-8 &&
git format-patch --stdout master..HEAD^ >out-u1 &&
git format-patch --stdout HEAD^ >out-u2 &&
@@ -91,13 +91,13 @@ test_expect_success 'format-patch output (UTF-8)' '
test_expect_success 'rebase (U/U)' '
# We want the result of rebase in UTF-8
- git-repo-config i18n.commitencoding UTF-8 &&
+ git-config i18n.commitencoding UTF-8 &&
# The test is about logoutputencoding not affecting the
# final outcome -- it is used internally to generate the
# patch and the log.
- git repo-config i18n.logoutputencoding UTF-8 &&
+ git config i18n.logoutputencoding UTF-8 &&
# The result will be committed by GIT_COMMITTER_NAME --
# we want UTF-8 encoded name.
@@ -109,8 +109,8 @@ test_expect_success 'rebase (U/U)' '
'
test_expect_success 'rebase (U/L)' '
- git-repo-config i18n.commitencoding UTF-8 &&
- git repo-config i18n.logoutputencoding ISO-8859-1 &&
+ git-config i18n.commitencoding UTF-8 &&
+ git config i18n.logoutputencoding ISO-8859-1 &&
. ../t3901-utf8.txt &&
git reset --hard side &&
@@ -121,8 +121,8 @@ test_expect_success 'rebase (U/L)' '
test_expect_success 'rebase (L/L)' '
# In this test we want ISO-8859-1 encoded commits as the result
- git-repo-config i18n.commitencoding ISO-8859-1 &&
- git repo-config i18n.logoutputencoding ISO-8859-1 &&
+ git-config i18n.commitencoding ISO-8859-1 &&
+ git config i18n.logoutputencoding ISO-8859-1 &&
. ../t3901-8859-1.txt &&
git reset --hard side &&
@@ -134,8 +134,8 @@ test_expect_success 'rebase (L/L)' '
test_expect_success 'rebase (L/U)' '
# This is pathological -- use UTF-8 as intermediate form
# to get ISO-8859-1 results.
- git-repo-config i18n.commitencoding ISO-8859-1 &&
- git repo-config i18n.logoutputencoding UTF-8 &&
+ git-config i18n.commitencoding ISO-8859-1 &&
+ git config i18n.logoutputencoding UTF-8 &&
. ../t3901-8859-1.txt &&
git reset --hard side &&
@@ -147,8 +147,8 @@ test_expect_success 'rebase (L/U)' '
test_expect_success 'cherry-pick(U/U)' '
# Both the commitencoding and logoutputencoding is set to UTF-8.
- git-repo-config i18n.commitencoding UTF-8 &&
- git repo-config i18n.logoutputencoding UTF-8 &&
+ git-config i18n.commitencoding UTF-8 &&
+ git config i18n.logoutputencoding UTF-8 &&
. ../t3901-utf8.txt &&
git reset --hard master &&
@@ -162,8 +162,8 @@ test_expect_success 'cherry-pick(U/U)' '
test_expect_success 'cherry-pick(L/L)' '
# Both the commitencoding and logoutputencoding is set to ISO-8859-1
- git-repo-config i18n.commitencoding ISO-8859-1 &&
- git repo-config i18n.logoutputencoding ISO-8859-1 &&
+ git-config i18n.commitencoding ISO-8859-1 &&
+ git config i18n.logoutputencoding ISO-8859-1 &&
. ../t3901-8859-1.txt &&
git reset --hard master &&
@@ -177,8 +177,8 @@ test_expect_success 'cherry-pick(L/L)' '
test_expect_success 'cherry-pick(U/L)' '
# Commitencoding is set to UTF-8 but logoutputencoding is ISO-8859-1
- git-repo-config i18n.commitencoding UTF-8 &&
- git repo-config i18n.logoutputencoding ISO-8859-1 &&
+ git-config i18n.commitencoding UTF-8 &&
+ git config i18n.logoutputencoding ISO-8859-1 &&
. ../t3901-utf8.txt &&
git reset --hard master &&
@@ -193,8 +193,8 @@ test_expect_success 'cherry-pick(L/U)' '
# Again, the commitencoding is set to ISO-8859-1 but
# logoutputencoding is set to UTF-8.
- git-repo-config i18n.commitencoding ISO-8859-1 &&
- git repo-config i18n.logoutputencoding UTF-8 &&
+ git-config i18n.commitencoding ISO-8859-1 &&
+ git config i18n.logoutputencoding UTF-8 &&
. ../t3901-8859-1.txt &&
git reset --hard master &&
@@ -206,8 +206,8 @@ test_expect_success 'cherry-pick(L/U)' '
'
test_expect_success 'rebase --merge (U/U)' '
- git-repo-config i18n.commitencoding UTF-8 &&
- git repo-config i18n.logoutputencoding UTF-8 &&
+ git-config i18n.commitencoding UTF-8 &&
+ git config i18n.logoutputencoding UTF-8 &&
. ../t3901-utf8.txt &&
git reset --hard side &&
@@ -217,8 +217,8 @@ test_expect_success 'rebase --merge (U/U)' '
'
test_expect_success 'rebase --merge (U/L)' '
- git-repo-config i18n.commitencoding UTF-8 &&
- git repo-config i18n.logoutputencoding ISO-8859-1 &&
+ git-config i18n.commitencoding UTF-8 &&
+ git config i18n.logoutputencoding ISO-8859-1 &&
. ../t3901-utf8.txt &&
git reset --hard side &&
@@ -229,8 +229,8 @@ test_expect_success 'rebase --merge (U/L)' '
test_expect_success 'rebase --merge (L/L)' '
# In this test we want ISO-8859-1 encoded commits as the result
- git-repo-config i18n.commitencoding ISO-8859-1 &&
- git repo-config i18n.logoutputencoding ISO-8859-1 &&
+ git-config i18n.commitencoding ISO-8859-1 &&
+ git config i18n.logoutputencoding ISO-8859-1 &&
. ../t3901-8859-1.txt &&
git reset --hard side &&
@@ -242,8 +242,8 @@ test_expect_success 'rebase --merge (L/L)' '
test_expect_success 'rebase --merge (L/U)' '
# This is pathological -- use UTF-8 as intermediate form
# to get ISO-8859-1 results.
- git-repo-config i18n.commitencoding ISO-8859-1 &&
- git repo-config i18n.logoutputencoding UTF-8 &&
+ git-config i18n.commitencoding ISO-8859-1 &&
+ git config i18n.logoutputencoding UTF-8 &&
. ../t3901-8859-1.txt &&
git reset --hard side &&
diff --git a/t/t4000-diff-format.sh b/t/t4000-diff-format.sh
index 67b9681..9c58d77 100755
--- a/t/t4000-diff-format.sh
+++ b/t/t4000-diff-format.sh
@@ -28,7 +28,7 @@ test_expect_success \
'git-diff-files -p >current'
# that's as far as it comes
-if [ "$(git repo-config --get core.filemode)" = false ]
+if [ "$(git config --get core.filemode)" = false ]
then
say 'filemode disabled on the filesystem'
test_done
diff --git a/t/t4006-diff-mode.sh b/t/t4006-diff-mode.sh
index 8ad69d1..ca342f4 100755
--- a/t/t4006-diff-mode.sh
+++ b/t/t4006-diff-mode.sh
@@ -15,7 +15,7 @@ test_expect_success \
tree=`git-write-tree` &&
echo $tree'
-if [ "$(git repo-config --get core.filemode)" = false ]
+if [ "$(git config --get core.filemode)" = false ]
then
say 'filemode disabled on the filesystem, using update-index --chmod=+x'
test_expect_success \
diff --git a/t/t4013-diff-various.sh b/t/t4013-diff-various.sh
index ed37141..3d85cea 100755
--- a/t/t4013-diff-various.sh
+++ b/t/t4013-diff-various.sh
@@ -73,7 +73,7 @@ test_expect_success setup '
for i in 1 2; do echo $i; done >>dir/sub &&
git update-index file0 dir/sub &&
- git repo-config log.showroot false &&
+ git config log.showroot false &&
git commit --amend &&
git show-branch
'
diff --git a/t/t4102-apply-rename.sh b/t/t4102-apply-rename.sh
index 22da6a0..b4662b0 100755
--- a/t/t4102-apply-rename.sh
+++ b/t/t4102-apply-rename.sh
@@ -31,7 +31,7 @@ test_expect_success setup \
test_expect_success apply \
'git-apply --index --stat --summary --apply test-patch'
-if [ "$(git repo-config --get core.filemode)" = false ]
+if [ "$(git config --get core.filemode)" = false ]
then
say 'filemode disabled on the filesystem'
else
diff --git a/t/t5301-sliding-window.sh b/t/t5301-sliding-window.sh
index 5a7232a..a6dbb04 100755
--- a/t/t5301-sliding-window.sh
+++ b/t/t5301-sliding-window.sh
@@ -30,19 +30,19 @@ test_expect_success \
test_expect_success \
'verify-pack -v, packedGitWindowSize == 1 page' \
- 'git-repo-config core.packedGitWindowSize 512 &&
+ 'git-config core.packedGitWindowSize 512 &&
git-verify-pack -v "$pack1"'
test_expect_success \
'verify-pack -v, packedGit{WindowSize,Limit} == 1 page' \
- 'git-repo-config core.packedGitWindowSize 512 &&
- git-repo-config core.packedGitLimit 512 &&
+ 'git-config core.packedGitWindowSize 512 &&
+ git-config core.packedGitLimit 512 &&
git-verify-pack -v "$pack1"'
test_expect_success \
'repack -a -d, packedGit{WindowSize,Limit} == 1 page' \
- 'git-repo-config core.packedGitWindowSize 512 &&
- git-repo-config core.packedGitLimit 512 &&
+ 'git-config core.packedGitWindowSize 512 &&
+ git-config core.packedGitLimit 512 &&
commit2=`git-commit-tree $tree -p $commit1 </dev/null` &&
git-update-ref HEAD $commit2 &&
git-repack -a -d &&
@@ -53,8 +53,8 @@ test_expect_success \
test_expect_success \
'verify-pack -v, defaults' \
- 'git-repo-config --unset core.packedGitWindowSize &&
- git-repo-config --unset core.packedGitLimit &&
+ 'git-config --unset core.packedGitWindowSize &&
+ git-config --unset core.packedGitLimit &&
git-verify-pack -v "$pack2"'
test_done
diff --git a/t/t5400-send-pack.sh b/t/t5400-send-pack.sh
index 2c15191..7d93d0d 100755
--- a/t/t5400-send-pack.sh
+++ b/t/t5400-send-pack.sh
@@ -106,7 +106,7 @@ export HOME ;# this way we force the victim/.git/config to be used.
test_expect_success \
'pushing with --force should be denied with denyNonFastforwards' '
cd victim &&
- git-repo-config receive.denyNonFastforwards true &&
+ git-config receive.denyNonFastforwards true &&
cd .. &&
git-update-ref refs/heads/master master^ &&
git-send-pack --force ./victim/.git/ master &&
diff --git a/t/t5500-fetch-pack.sh b/t/t5500-fetch-pack.sh
index 058cce0..e35d60f 100755
--- a/t/t5500-fetch-pack.sh
+++ b/t/t5500-fetch-pack.sh
@@ -98,7 +98,7 @@ pull_to_client () {
mkdir client &&
cd client &&
git-init 2>> log2.txt &&
- git repo-config transfer.unpacklimit 0
+ git config transfer.unpacklimit 0
)
add A1
diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh
index 3ce9446..50c6485 100755
--- a/t/t5510-fetch.sh
+++ b/t/t5510-fetch.sh
@@ -22,14 +22,14 @@ test_expect_success "clone and setup child repos" '
cd .. &&
git clone . two &&
cd two &&
- git repo-config branch.master.remote one &&
- git repo-config remote.one.url ../one/.git/ &&
- git repo-config remote.one.fetch refs/heads/master:refs/heads/one &&
+ git config branch.master.remote one &&
+ git config remote.one.url ../one/.git/ &&
+ git config remote.one.fetch refs/heads/master:refs/heads/one &&
cd .. &&
git clone . three &&
cd three &&
- git repo-config branch.master.remote two &&
- git repo-config branch.master.merge refs/heads/one &&
+ git config branch.master.remote two &&
+ git config branch.master.merge refs/heads/one &&
mkdir -p .git/remotes &&
{
echo "URL: ../two/.git/"
diff --git a/t/t6200-fmt-merge-msg.sh b/t/t6200-fmt-merge-msg.sh
index 63e49f3..ea14023 100755
--- a/t/t6200-fmt-merge-msg.sh
+++ b/t/t6200-fmt-merge-msg.sh
@@ -108,7 +108,7 @@ EOF
test_expect_success 'merge-msg test #3' '
- git repo-config merge.summary true &&
+ git config merge.summary true &&
git checkout master &&
setdate &&
@@ -138,7 +138,7 @@ EOF
test_expect_success 'merge-msg test #4' '
- git repo-config merge.summary true &&
+ git config merge.summary true &&
git checkout master &&
setdate &&
@@ -150,7 +150,7 @@ test_expect_success 'merge-msg test #4' '
test_expect_success 'merge-msg test #5' '
- git repo-config merge.summary yes &&
+ git config merge.summary yes &&
git checkout master &&
setdate &&
--
1.5.0.rc2.g5355
^ permalink raw reply related [relevance 2%]
* Re: newbie questions about git design and features (some wrt hg)
@ 2007-01-30 16:55 2% ` Shawn O. Pearce
0 siblings, 0 replies; 200+ results
From: Shawn O. Pearce @ 2007-01-30 16:55 UTC (permalink / raw)
To: Mike Coleman; +Cc: git
Mike Coleman <tutufan@gmail.com> wrote:
> 1. As of today, is there any real safety concern with either tool's
> repo format? Is either tool significantly better in this regard?
> (Keith Packard's post hints at a problem here, but doesn't really make
> the case.)
I think the Git format is tighter in terms of compression,
and simpler in terms of understanding and writing code. I have
personally written the code to read and write the Git repository
format in both C and Java, and in both cases it falls out in just
a few hundred lines of code (assuming you have libz handy to do
the compression/decompression for you).
The Git format is completely safe with regards to parallel
modification of a repository, which is good for shared repositories
that might have multiple people pushing into it at once.
Git's format is also safe with regards to *any* update.
You literally cannot destroy the repository during an update.
Its impossible. You'd have to physically destroy the storage device.
(OK, that's overstating it a bit, but it is really hard.)
The point Keith was making was the Git format is "add-only".
Once something has been stored, we NEVER modify it again. This
bypasses any sort of possible problems that can occur with partial
modifications caused by a process aborting in the middle of a change.
I think hg modifies files as it goes, which could cause some issues
when a writer is aborted. I'm sure they have thought about the
problem and tried to make it safe, but there isn't anything safer
than just leaving the damn thing alone. :)
> 2. Does the git packed object format solve the performance problem
> alluded to in posts from a year or two ago?
Yes. By a huge margin. Git's *fast*. Ignore anything from a year
or two ago.
> 3. Someone mentioned that git bisect can work between any two
> commits, not necessarily just one that happens to be an ancestor of
> the other. This sounds really cool. Can hg's bisect do this, too?
No clue.
> 4. What is git's index good for? I find that I like the idea of it,
> but I'm not sure I could justify it's presence to someone else, as
> opposed to having it hidden in the way that hg's dircache (?) is. Can
> anyone think of a good scenario where it's a pretty obvious benefit?
Its a good way to stage the stuff in your next commit. By that I
mean you edit some code. Then you look at what differs between the
index and your working directory. You decide "this hunk is good, it
passed the tests, I want to commit that, so toss it into the index".
Now that hunk isn't different anymore.
When it comes time to commit, all of your already reviewed stuff is
staged in the index. You just need to issue a commit and supply
the message. But you can leave modified stuff in the working
directory, even for files that were alerady updated in the index.
This really helps during a merge. Only the stuff which Git could
not merge for you is seen as different between the index and the
working directory; all of the stuff that Git merged for you is
already staged in the index. So you can focus on the conflicts,
and stage their resolutions into the index as you go. This makes
it easier to work through larger merges where more than 1 or 2
files contains conflicts.
> 5. I think I read that there'd been just one incompatible change over
> time in the git repo format. What was it?
A LONG time ago, like in the very first version Linus offered out
to the public, we computed the identity of an object using the
SHA-1 hash of the *compressed* data. This is sensitive to the
compression settings used, and was not the best idea as a result.
It was very quickly changed to compute the identity of the object
using the SHA-1 has of the raw (user) data, removing any dependence
on the compression routine to always yield the same result for the
same input.
We haven't had a change since then. We have added some new
compression options which are just that, options. If you use them
older Git binaries won't necessarily recognize the repository data,
but these are off by default and can be enabled on a per-repository
basis. E.g. if you are only using newer Git on a given system you
can enable the newer compression features on all of the repositories
on that system.
> 6. Does either tool use hard links? This matters to me because I do
> development on a connected machine and a disconnected machine, using a
> usb drive to rsync between. (Perhaps there'll be some way to transfer
> changes using git or hg instead of rsync, but I haven't figured that
> out yet.)
Git can use hardlinks if you ask it to. We only use them for the
repository files, not for the user's actual source files.
Git has its own native transport (git-push, git-fetch) which can
move data between two Git repositories via local filesystem access,
SSH, HTTP, FTP, and rsync (latter two are read-only transports).
> 7. I'm a fan of Python, and I'm really a fan of using high-level
> languages with performance-critical parts in a lower-level language,
> so in that regard, I really like hg's implementation. If someone
> wanted to do it, is a Python clone of git conceivable? Is there
> something about it that just requires C?
Yes, a Python clone of Git is conceivable. Indeed, there is a
pure Java clone in process (jgit) for an Eclipse plugin (egit).
If you wanted to rewrite Git in Python, knock yourself out.
But we've ported all of our Python to C, as its just faster.
> 8. It feels like hg is not really comfortable with parallel
> development over time on different heads within a single repo.
> Rather, it seems that multiple repos are supposed to be used for this.
> Does this lead to any problems? For example, is it harder or
> different to merge two heads if they're in different repo than if
> they're in the same repo?
No clue. I know multiple heads in one Git repository works
*awesome*. Especially on large repositories (>10k files) as the time
required to start a new branch is only the time needed to update the
files in the working directory which don't have the correct version.
Usually that's a small percentage (<200) of the files and thus its
very fast to switch to a new branch of development, and switch back.
On a decent UNIX system (and my Mac OS X PowerBook doesn't really
count) flipping branches in git-gui is almost immediate. You pick
the branch in the menu and *wham* its switched. And that's my
PowerBook, which as I said, doesn't quite count as good UNIX
system...
--
Shawn.
^ permalink raw reply [relevance 2%]
* Re: restriction of pulls
@ 2007-02-09 15:32 2% ` Rogan Dawes
2007-02-09 16:19 5% ` Andy Parkins
0 siblings, 2 replies; 200+ results
From: Rogan Dawes @ 2007-02-09 15:32 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: Christoph Duelli, git
Johannes Schindelin wrote:
> Hi,
>
> On Fri, 9 Feb 2007, Christoph Duelli wrote:
>
>> Is it possible to restrict a chechout, clone or a later pull to some
>> subdirectory of a repository?
>
> No. In git, a revision really is a revision, and not a group of file
> revisions.
>
> Ciao,
> Dscho
>
I thought about how this might be implemented, although I'm not entirely
sure how efficient this will be.
One obstacle to implementing partial checkouts is that one does not know
which objects have changed or been deleted. One way of addressing this
is to keep a record of the hashes of all the objects that were NOT
checked out. (If one does not check out part of a directory, simply
store the hash of the top level, and you do not need to store the child
hashes.) This record would be a kind of "negative index".
When deciding what to check in, or which files are modified, one would
check the "negative index" first to see if an entry exists. If not, only
then would you check the filesystem to see if modification times have
changed. With the "negative index", and the files in the file system,
one would be able to construct new commits, without any problem.
It would also require an updated transfer protocol, which would allow
the client to specify a tag/commit, then walk the tree that it points to
to find the portion that the client is looking for, then pull only those
objects (and possibly their history). This is likely to be VERY
inefficient in terms of round trips, at least initially.
This might be able to benefit from the shallow checkout support that was
recently implemented.
Comments?
Rogan
^ permalink raw reply [relevance 2%]
* Re: restriction of pulls
2007-02-09 15:32 2% ` Rogan Dawes
@ 2007-02-09 16:19 5% ` Andy Parkins
1 sibling, 0 replies; 200+ results
From: Andy Parkins @ 2007-02-09 16:19 UTC (permalink / raw)
To: git; +Cc: Rogan Dawes, Johannes Schindelin, Christoph Duelli
On Friday 2007 February 09 15:32, Rogan Dawes wrote:
> One obstacle to implementing partial checkouts is that one does not know
> which objects have changed or been deleted. One way of addressing this
Why would you want to do a partial checkout. I used subversion for a long
time before git, which does to partial checkouts and it's a nightmare.
Things like this
cd dir1/
edit files
cd ../dir2
edit files
svn commit
* committed revision 100
KABLAM! Disaster. Revision 100 no longer compiles/runs. The changes in dir1
and dir2 were complimentary changes (say like renaming a function and then
the places that call that function).
I didn't even notice how awful it was until I started using git and had a VCS
that did the right thing.
In every way that matters you can do a partial checkout - I can pull any
version of any file out of the repository. However, it should certainly not
be the case that git records that fact.
I think what you're actually after (from your description) is a shallow clone.
I believe that went in a while ago from Dscho.
$ git clone --depth=5 <someurl>
Will fetch only the last 5 revisions from the remote. The other half to that
is a shallow-by-tree clone; that is anathema to git as there is no such thing
as a partial tree. Submodule support is what you want, but that's still in
development.
The only piece that (I think) is missing to get the functionality you want is
a kind of lazy transfer mode. For something like, say, the kde repository
you can do
svn checkout svn://svn.kde.org/kde/some/deep/path/in/the/project
And just get that directory - i.e. you don't have to pay the cost of
downloading the whole of KDE. Git can't do that; however, I think one day it
will be able to by choosing not to download every object from the remote.
Andy
--
Dr Andy Parkins, M Eng (hons), MIEE
andyparkins@gmail.com
^ permalink raw reply [relevance 5%]
* Re: restriction of pulls
@ 2007-02-12 13:58 3% ` Rogan Dawes
0 siblings, 1 reply; 200+ results
From: Rogan Dawes @ 2007-02-12 13:58 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: Rogan Dawes, Christoph Duelli, git
Johannes Schindelin wrote:
> Hi,
>
> On Fri, 9 Feb 2007, Rogan Dawes wrote:
>
>> Johannes Schindelin wrote:
>>> On Fri, 9 Feb 2007, Christoph Duelli wrote:
>>>
>>>> Is it possible to restrict a chechout, clone or a later pull to some
>>>> subdirectory of a repository?
>>> No. In git, a revision really is a revision, and not a group of file
>>> revisions.
>> I thought about how this might be implemented, although I'm not entirely
>> sure how efficient this will be.
>
> There are basically three ways I can think of:
>
> - rewrite the commit objects on the fly. You might want to avoid the use
> of the pack protocol here (i.e. use HTTP or FTP transport).
>
> - try to teach git a way to ignore certain missing objects and
> directories. This might be involved, but you could extend upload-pack
> easily with a new extension for that.
>
> (my favourite:)
> - use git-split to create a new branch, which only contains doc/. Do work
> only on that branch, and merge into mainline from time to time.
>
> If you don't need the history, you don't need to git-split the branch.
>
> You only need to make sure that the newly created branch is _not_ branched
> off of mainline, since the next merge would _delete_ all files outside of
> doc/ (merge would see that the files exist in mainline, and existed in the
> common ancestor, too, so would think that the files were deleted in the
> doc branch).
>
> Ciao,
> Dscho
>
Your third option sounds quite clever, apart from the problem of
attributing a commit and a commit message to someone, when the actual
commit doesn't match what they actually did :-(
As well as wondering what happens when they check out a few more files.
Do we rewrite those commits as well? What happens if the user has made
some commits already? What happens if they have already sent those
upstream? etc.
I think the best solution is ultimately to make git able to cope with
certain missing objects.
I started writing this in response to another message, but it will do
fine here, too:
The description I give here will likely horrify people in terms of
communications inefficiency, but I'm sure that can be improved.
Scenario:
A user sees a documentation bug in a git-managed project, and decides
that she wants to do something about it. Since she is not on the fastest
of connections, she'd like to reduce the checkout to a reasonable
minimum, while still working with the git tools.
Viewing the repo layout using gitweb, she sees that all the
documentation is stored in the docs/ directory from the root.
So, she creates a local repo to work in:
$ git init-db
She configures her local repo to reference the source one:
(Hypothetical syntax)
$ git clone --reference http://example.com/project.git \
http://example.com/project.git
Since the reference and repo are the same (and non-local), git doesn't
actually download anything, other than the current heads (and maybe tags).
She then does a partial checkout of the master branch, but only the
docs/ directory:
$ git checkout -p master docs/
The -p flag indicates that this is a partial checkout of master. Git
records that the current HEAD is "master", checks out the docs/
directory, and removes any other files in the working directory (that it
knew about from the existing index, if any - I'm not suggesting that it
should arbitrarily delete files!)
The checkout process goes as follows: Resolve the <treeish> that HEAD
points to, and retrieve it from the upstream repo if it does not exist
locally. Continue requesting only the necessary tree and blob objects to
satisfy the requested checkout. i.e. From the first tree, identify the
docs/ directory. Then request only that tree object. Continue to
download tree and blob objects until the entire docs/ directory can be
created in the working directory.
This will likely require a new index file format, that simply stores the
hashes of objects (blobs or trees) that have not been checked out, as
well as the current file's stat information.
Now create a "negative index" (pindex?) that has details about the other
files and directories that were not checked out. Obviously, this does
not need to recurse into directories that were not checked out. Simply
having the hash of the parent directory in the pindex is sufficient
information to reconstruct a new index. (This might require a new index
format that does not include all known files, but simply stores the hash
of the unchecked-out tree or blob.)
Then creating a new commit would require creating the necessary blobs
for changed files, new tree objects for trees that change, and a commit
object.
As far as I can tell, that could then be pushed/pulled/merged using the
existing tools, without any problems.
Rogan
^ permalink raw reply [relevance 3%]
* Re: restriction of pulls
@ 2007-02-12 14:29 4% ` Rogan Dawes
0 siblings, 0 replies; 200+ results
From: Rogan Dawes @ 2007-02-12 14:29 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: Christoph Duelli, git
Johannes Schindelin wrote:
> Hi,
>
> On Mon, 12 Feb 2007, Rogan Dawes wrote:
>
>> Johannes Schindelin wrote:
>>> (my favourite:)
>>> - use git-split to create a new branch, which only contains doc/. Do work
>>> only on that branch, and merge into mainline from time to time.
>> Your third option sounds quite clever, apart from the problem of attributing a
>> commit and a commit message to someone, when the actual commit doesn't match
>> what they actually did :-(
>
> This problem is not related to subprojects at all. If the commit message
> does not match the patch, you are always fscked.
Well, I was thinking about the fact that the files originally checked in
will not match the files "checked in" in the rewritten commit.
>> As well as wondering what happens when they check out a few more files. Do we
>> rewrite those commits as well? What happens if the user has made some commits
>> already? What happens if they have already sent those upstream? etc.
>
> I think you misunderstood. My favourite option would make docs a
> _separate_ project, with its own history. It just happens to be pulled
> from time to time, just like git-gui, gitk and git-fast-import in git.git.
I see. However, that does not allow for the random single-file checkout
scenario I sketched out. Which may or may not be common/desirable, but
it is an extreme case of the partial checkout, without fixed delineation.
>> I think the best solution is ultimately to make git able to cope with
>> certain missing objects.
>
> Hmm. I am not convinced. On nice thing about git is its level of
> integrity. Which means that no random objects are missing.
Good point. :-(
>> I started writing this in response to another message, but it will do fine
>> here, too:
>>
>> The description I give here will likely horrify people in terms of
>> communications inefficiency, but I'm sure that can be improved.
>>
>> [goes on... and describes the lazy clone!]
>
> AFAICT this really is the lazy clone. And it was already determined that
> it is all to easy to pull in all commit objects by accident. Which boils
> down to a substantial chunk of the repository.
>
Not so much a lazy clone as a partial clone. It is only in the "clone",
"fetch" or "checkout" code paths that new objects will be retrieved from
the source repo. Things like "git log"/"git show" would not do so, and
would be required to handle missing objects gracefully.
> But if you want to play with it: by all means, go ahead. It might just be
> that you overcome the fundamental difficulties, and we get something nice
> out of it.
>
> Ciao,
> Dscho
>
Maybe ;-) We'll see if I get any time for it.
Rogan
^ permalink raw reply [relevance 4%]
* [ANNOUNCE] GIT 1.5.0
@ 2007-02-14 3:14 2% Junio C Hamano
0 siblings, 0 replies; 200+ results
From: Junio C Hamano @ 2007-02-14 3:14 UTC (permalink / raw)
To: git; +Cc: linux-kernel
The latest feature release GIT 1.5.0 is available at the usual places:
http://www.kernel.org/pub/software/scm/git/
git-1.5.0.tar.{gz,bz2} (tarball)
git-htmldocs-1.5.0.tar.{gz,bz2} (preformatted docs)
git-manpages-1.5.0.tar.{gz,bz2} (preformatted docs)
RPMS/$arch/git-*-1.5.0-1.$arch.rpm (RPM)
----------------------------------------------------------------
GIT v1.5.0 Release Notes
========================
Old news
--------
This section is for people who are upgrading from ancient
versions of git. Although all of the changes in this section
happened before the current v1.4.4 release, they are summarized
here in the v1.5.0 release notes for people who skipped earlier
versions.
As of git v1.5.0 there are some optional features that changes
the repository to allow data to be stored and transferred more
efficiently. These features are not enabled by default, as they
will make the repository unusable with older versions of git.
Specifically, the available options are:
- There is a configuration variable core.legacyheaders that
changes the format of loose objects so that they are more
efficient to pack and to send out of the repository over git
native protocol, since v1.4.2. However, loose objects
written in the new format cannot be read by git older than
that version; people fetching from your repository using
older clients over dumb transports (e.g. http) using older
versions of git will also be affected.
- Since v1.4.3, configuration repack.usedeltabaseoffset allows
packfile to be created in more space efficient format, which
cannot be read by git older than that version.
The above two are not enabled by default and you explicitly have
to ask for them, because these two features make repositories
unreadable by older versions of git, and in v1.5.0 we still do
not enable them by default for the same reason. We will change
this default probably 1 year after 1.4.2's release, when it is
reasonable to expect everybody to have new enough version of
git.
- 'git pack-refs' appeared in v1.4.4; this command allows tags
to be accessed much more efficiently than the traditional
'one-file-per-tag' format. Older git-native clients can
still fetch from a repository that packed and pruned refs
(the server side needs to run the up-to-date version of git),
but older dumb transports cannot. Packing of refs is done by
an explicit user action, either by use of "git pack-refs
--prune" command or by use of "git gc" command.
- 'git -p' to paginate anything -- many commands do pagination
by default on a tty. Introduced between v1.4.1 and v1.4.2;
this may surprise old timers.
- 'git archive' superseded 'git tar-tree' in v1.4.3;
- 'git cvsserver' was new invention in v1.3.0;
- 'git repo-config', 'git grep', 'git rebase' and 'gitk' were
seriously enhanced during v1.4.0 timeperiod.
- 'gitweb' became part of git.git during v1.4.0 timeperiod and
seriously modified since then.
- reflog is an v1.4.0 invention. This allows you to name a
revision that a branch used to be at (e.g. "git diff
master@{yesterday} master" allows you to see changes since
yesterday's tip of the branch).
Updates in v1.5.0 since v1.4.4 series
-------------------------------------
* Index manipulation
- git-add is to add contents to the index (aka "staging area"
for the next commit), whether the file the contents happen to
be is an existing one or a newly created one.
- git-add without any argument does not add everything
anymore. Use 'git-add .' instead. Also you can add
otherwise ignored files with an -f option.
- git-add tries to be more friendly to users by offering an
interactive mode ("git-add -i").
- git-commit <path> used to refuse to commit if <path> was
different between HEAD and the index (i.e. update-index was
used on it earlier). This check was removed.
- git-rm is much saner and safer. It is used to remove paths
from both the index file and the working tree, and makes sure
you are not losing any local modification before doing so.
- git-reset <tree> <paths>... can be used to revert index
entries for selected paths.
- git-update-index is much less visible. Many suggestions to
use the command in git output and documentation have now been
replaced by simpler commands such as "git add" or "git rm".
* Repository layout and objects transfer
- The data for origin repository is stored in the configuration
file $GIT_DIR/config, not in $GIT_DIR/remotes/, for newly
created clones. The latter is still supported and there is
no need to convert your existing repository if you are
already comfortable with your workflow with the layout.
- git-clone always uses what is known as "separate remote"
layout for a newly created repository with a working tree.
A repository with the separate remote layout starts with only
one default branch, 'master', to be used for your own
development. Unlike the traditional layout that copied all
the upstream branches into your branch namespace (while
renaming their 'master' to your 'origin'), the new layout
puts upstream branches into local "remote-tracking branches"
with their own namespace. These can be referenced with names
such as "origin/$upstream_branch_name" and are stored in
.git/refs/remotes rather than .git/refs/heads where normal
branches are stored.
This layout keeps your own branch namespace less cluttered,
avoids name collision with your upstream, makes it possible
to automatically track new branches created at the remote
after you clone from it, and makes it easier to interact with
more than one remote repository (you can use "git remote" to
add other repositories to track). There might be some
surprises:
* 'git branch' does not show the remote tracking branches.
It only lists your own branches. Use '-r' option to view
the tracking branches.
* If you are forking off of a branch obtained from the
upstream, you would have done something like 'git branch
my-next next', because traditional layout dropped the
tracking branch 'next' into your own branch namespace.
With the separate remote layout, you say 'git branch next
origin/next', which allows you to use the matching name
'next' for your own branch. It also allows you to track a
remote other than 'origin' (i.e. where you initially cloned
from) and fork off of a branch from there the same way
(e.g. "git branch mingw j6t/master").
Repositories initialized with the traditional layout continue
to work.
- New branches that appear on the origin side after a clone is
made are also tracked automatically. This is done with an
wildcard refspec "refs/heads/*:refs/remotes/origin/*", which
older git does not understand, so if you clone with 1.5.0,
you would need to downgrade remote.*.fetch in the
configuration file to specify each branch you are interested
in individually if you plan to fetch into the repository with
older versions of git (but why would you?).
- Similarly, wildcard refspec "refs/heads/*:refs/remotes/me/*"
can be given to "git-push" command to update the tracking
branches that is used to track the repository you are pushing
from on the remote side.
- git-branch and git-show-branch know remote tracking branches
(use the command line switch "-r" to list only tracked branches).
- git-push can now be used to delete a remote branch or a tag.
This requires the updated git on the remote side (use "git
push <remote> :refs/heads/<branch>" to delete "branch").
- git-push more aggressively keeps the transferred objects
packed. Earlier we recommended to monitor amount of loose
objects and repack regularly, but you should repack when you
accumulated too many small packs this way as well. Updated
git-count-objects helps you with this.
- git-fetch also more aggressively keeps the transferred objects
packed. This behavior of git-push and git-fetch can be
tweaked with a single configuration transfer.unpacklimit (but
usually there should not be any need for a user to tweak it).
- A new command, git-remote, can help you manage your remote
tracking branch definitions.
- You may need to specify explicit paths for upload-pack and/or
receive-pack due to your ssh daemon configuration on the
other end. This can now be done via remote.*.uploadpack and
remote.*.receivepack configuration.
* Bare repositories
- Certain commands change their behavior in a bare repository
(i.e. a repository without associated working tree). We use
a fairly conservative heuristic (if $GIT_DIR is ".git", or
ends with "/.git", the repository is not bare) to decide if a
repository is bare, but "core.bare" configuration variable
can be used to override the heuristic when it misidentifies
your repository.
- git-fetch used to complain updating the current branch but
this is now allowed for a bare repository. So is the use of
'git-branch -f' to update the current branch.
- Porcelain-ish commands that require a working tree refuses to
work in a bare repository.
* Reflog
- Reflog records the history from the view point of the local
repository. In other words, regardless of the real history,
the reflog shows the history as seen by one particular
repository (this enables you to ask "what was the current
revision in _this_ repository, yesterday at 1pm?"). This
facility is enabled by default for repositories with working
trees, and can be accessed with the "branch@{time}" and
"branch@{Nth}" notation.
- "git show-branch" learned showing the reflog data with the
new -g option. "git log" has -s option to view reflog
entries in a more verbose manner.
- git-branch knows how to rename branches and moves existing
reflog data from the old branch to the new one.
- In addition to the reflog support in v1.4.4 series, HEAD
reference maintains its own log. "HEAD@{5.minutes.ago}"
means the commit you were at 5 minutes ago, which takes
branch switching into account. If you want to know where the
tip of your current branch was at 5 minutes ago, you need to
explicitly say its name (e.g. "master@{5.minutes.ago}") or
omit the refname altogether i.e. "@{5.minutes.ago}".
- The commits referred to by reflog entries are now protected
against pruning. The new command "git reflog expire" can be
used to truncate older reflog entries and entries that refer
to commits that have been pruned away previously with older
versions of git.
Existing repositories that have been using reflog may get
complaints from fsck-objects and may not be able to run
git-repack, if you had run git-prune from older git; please
run "git reflog expire --stale-fix --all" first to remove
reflog entries that refer to commits that are no longer in
the repository when that happens.
* Crufts removal
- We used to say "old commits are retrievable using reflog and
'master@{yesterday}' syntax as long as you haven't run
git-prune". We no longer have to say the latter half of the
above sentence, as git-prune does not remove things reachable
from reflog entries.
- 'git-prune' by default does not remove _everything_
unreachable, as there is a one-day grace period built-in.
- There is a toplevel garbage collector script, 'git-gc', that
runs periodic cleanup functions, including 'git-repack -a -d',
'git-reflog expire', 'git-pack-refs --prune', and 'git-rerere
gc'.
- The output from fsck ("fsck-objects" is called just "fsck"
now, but the old name continues to work) was needlessly
alarming in that it warned missing objects that are reachable
only from dangling objects. This has been corrected and the
output is much more useful.
* Detached HEAD
- You can use 'git-checkout' to check out an arbitrary revision
or a tag as well, instead of named branches. This will
dissociate your HEAD from the branch you are currently on.
A typical use of this feature is to "look around". E.g.
$ git checkout v2.6.16
... compile, test, etc.
$ git checkout v2.6.17
... compile, test, etc.
- After detaching your HEAD, you can go back to an existing
branch with usual "git checkout $branch". Also you can
start a new branch using "git checkout -b $newbranch" to
start a new branch at that commit.
- You can even pull from other repositories, make merges and
commits while your HEAD is detached. Also you can use "git
reset" to jump to arbitrary commit, while still keeping your
HEAD detached.
Going back to attached state (i.e. on a particular branch) by
"git checkout $branch" can lose the current stat you arrived
in these ways, and "git checkout" refuses when the detached
HEAD is not pointed by any existing ref (an existing branch,
a remote tracking branch or a tag). This safety can be
overridden with "git checkout -f $branch".
* Packed refs
- Repositories with hundreds of tags have been paying large
overhead, both in storage and in runtime, due to the
traditional one-ref-per-file format. A new command,
git-pack-refs, can be used to "pack" them in more efficient
representation (you can let git-gc do this for you).
- Clones and fetches over dumb transports are now aware of
packed refs and can download from repositories that use
them.
* Configuration
- configuration related to color setting are consolidated under
color.* namespace (older diff.color.*, status.color.* are
still supported).
- 'git-repo-config' command is accessible as 'git-config' now.
* Updated features
- git-describe uses better criteria to pick a base ref. It
used to pick the one with the newest timestamp, but now it
picks the one that is topologically the closest (that is,
among ancestors of commit C, the ref T that has the shortest
output from "git-rev-list T..C" is chosen).
- git-describe gives the number of commits since the base ref
between the refname and the hash suffix. E.g. the commit one
before v2.6.20-rc6 in the kernel repository is:
v2.6.20-rc5-306-ga21b069
which tells you that its object name begins with a21b069,
v2.6.20-rc5 is an ancestor of it (meaning, the commit
contains everything -rc5 has), and there are 306 commits
since v2.6.20-rc5.
- git-describe with --abbrev=0 can be used to show only the
name of the base ref.
- git-blame learned a new option, --incremental, that tells it
to output the blames as they are assigned. A sample script
to use it is also included as contrib/blameview.
- git-blame starts annotating from the working tree by default.
* Less external dependency
- We no longer require the "merge" program from the RCS suite.
All 3-way file-level merges are now done internally.
- The original implementation of git-merge-recursive which was
in Python has been removed; we have a C implementation of it
now.
- git-shortlog is no longer a Perl script. It no longer
requires output piped from git-log; it can accept revision
parameters directly on the command line.
* I18n
- We have always encouraged the commit message to be encoded in
UTF-8, but the users are allowed to use legacy encoding as
appropriate for their projects. This will continue to be the
case. However, a non UTF-8 commit encoding _must_ be
explicitly set with i18n.commitencoding in the repository
where a commit is made; otherwise git-commit-tree will
complain if the log message does not look like a valid UTF-8
string.
- The value of i18n.commitencoding in the originating
repository is recorded in the commit object on the "encoding"
header, if it is not UTF-8. git-log and friends notice this,
and reencodes the message to the log output encoding when
displaying, if they are different. The log output encoding
is determined by "git log --encoding=<encoding>",
i18n.logoutputencoding configuration, or i18n.commitencoding
configuration, in the decreasing order of preference, and
defaults to UTF-8.
- Tools for e-mailed patch application now default to -u
behavior; i.e. it always re-codes from the e-mailed encoding
to the encoding specified with i18n.commitencoding. This
unfortunately forces projects that have happily been using a
legacy encoding without setting i18n.commitencoding to set
the configuration, but taken with other improvement, please
excuse us for this very minor one-time inconvenience.
* e-mailed patches
- See the above I18n section.
- git-format-patch now enables --binary without being asked.
git-am does _not_ default to it, as sending binary patch via
e-mail is unusual and is harder to review than textual
patches and it is prudent to require the person who is
applying the patch to explicitly ask for it.
- The default suffix for git-format-patch output is now ".patch",
not ".txt". This can be changed with --suffix=.txt option,
or setting the config variable "format.suffix" to ".txt".
* Foreign SCM interfaces
- git-svn now requires the Perl SVN:: libraries, the
command-line backend was too slow and limited.
- the 'commit' subcommand of git-svn has been renamed to
'set-tree', and 'dcommit' is the recommended replacement for
day-to-day work.
- git fast-import backend.
* User support
- Quite a lot of documentation updates.
- Bash completion scripts have been updated heavily.
- Better error messages for often used Porcelainish commands.
- Git GUI. This is a simple Tk based graphical interface for
common Git operations.
* Sliding mmap
- We used to assume that we can mmap the whole packfile while
in use, but with a large project this consumes huge virtual
memory space and truly huge ones would not fit in the
userland address space on 32-bit platforms. We now mmap huge
packfile in pieces to avoid this problem.
* Shallow clones
- There is a partial support for 'shallow' repositories that
keeps only recent history. A 'shallow clone' is created by
specifying how deep that truncated history should be
(e.g. "git clone --depth=5 git://some.where/repo.git").
Currently a shallow repository has number of limitations:
- Cloning and fetching _from_ a shallow clone are not
supported (nor tested -- so they might work by accident but
they are not expected to).
- Pushing from nor into a shallow clone are not expected to
work.
- Merging inside a shallow repository would work as long as a
merge base is found in the recent history, but otherwise it
will be like merging unrelated histories and may result in
huge conflicts.
but this would be more than adequate for people who want to
look at near the tip of a big project with a deep history and
send patches in e-mail format.
^ permalink raw reply [relevance 2%]
* [PATCH] git-clone: Sync documentation to usage note.
@ 2007-02-15 22:13 16% Christian Schlotter
0 siblings, 0 replies; 200+ results
From: Christian Schlotter @ 2007-02-15 22:13 UTC (permalink / raw)
To: git; +Cc: Christian Schlotter
Documentation advertises the new `--depth <n>' parameter with an equal
sign, while the usage notes (shown after `git-clone --help') do not. If I
understood git-clone's source code correctly, the version without the
equal sign is correct, which is why this patch syncs documentation to the
usage note.
Please note that I was not able to test the new shallow clone feature, as
both
git clone --depth=5 git://git2.kernel.org/pub/scm/git/git.git
and
git clone --depth 5 git://git2.kernel.org/pub/scm/git/git.git
do not seem to work. The former correctly produces the usage note, while
the latter prints
Initialized empty Git repository in /home/cs/tmp2/git/.git/
fatal: read error (Connection reset by peer)
fetch-pack from 'git://git2.kernel.org/pub/scm/git/git.git' failed.
Is this a problem on my end?
Signed-off-by: Christian Schlotter <schlotter@users.sourceforge.net>
---
Documentation/RelNotes-1.5.0.txt | 2 +-
Documentation/git-clone.txt | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/Documentation/RelNotes-1.5.0.txt b/Documentation/RelNotes-1.5.0.txt
index 599efb8..daf4bdb 100644
--- a/Documentation/RelNotes-1.5.0.txt
+++ b/Documentation/RelNotes-1.5.0.txt
@@ -448,7 +448,7 @@ Updates in v1.5.0 since v1.4.4 series
- There is a partial support for 'shallow' repositories that
keeps only recent history. A 'shallow clone' is created by
specifying how deep that truncated history should be
- (e.g. "git clone --depth=5 git://some.where/repo.git").
+ (e.g. "git clone --depth 5 git://some.where/repo.git").
Currently a shallow repository has number of limitations:
diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt
index 707376f..6d32c49 100644
--- a/Documentation/git-clone.txt
+++ b/Documentation/git-clone.txt
@@ -11,7 +11,7 @@ SYNOPSIS
[verse]
'git-clone' [--template=<template_directory>] [-l [-s]] [-q] [-n] [--bare]
[-o <name>] [-u <upload-pack>] [--reference <repository>]
- [--depth=<depth>] <repository> [<directory>]
+ [--depth <depth>] <repository> [<directory>]
DESCRIPTION
-----------
@@ -96,7 +96,7 @@ OPTIONS
if unset the templates are taken from the installation
defined default, typically `/usr/share/git-core/templates`.
---depth=<depth>::
+--depth <depth>::
Create a 'shallow' clone with a history truncated to the
specified number of revs. A shallow repository has
number of limitations (you cannot clone or fetch from
--
1.5.0
^ permalink raw reply related [relevance 16%]
* Re: StGIT discards local commits on "stg pull"
@ 2007-02-19 20:47 1% ` Yann Dirson
0 siblings, 0 replies; 200+ results
From: Yann Dirson @ 2007-02-19 20:47 UTC (permalink / raw)
To: Catalin Marinas; +Cc: Pavel Roskin, git
On Tue, Feb 13, 2007 at 10:48:11PM +0000, Catalin Marinas wrote:
> On 13/02/07, Pavel Roskin <proski@gnu.org> wrote:
> >On Mon, 2007-02-12 at 09:31 +0000, Catalin Marinas wrote:
> >> On 12/02/07, Pavel Roskin <proski@gnu.org> wrote:
> >
> >> > The example below shows that git-pull keeps my commit, but "stg pull"
> >> > discards it by rebasing back to the remote ID.
> >>
> >> I think this is a "feature" but we should've probably leave the
> >> original behaviour as the default. Maybe we should also have this
> >> per-branch rather than per-repository.
> >
> >I don't know the original motivation behind effectively reimplementing
> >"git pull" in StGIT, but it's clear that the StGIT's own implementation
> >needs some polish.
The primary motivation was to allow some sort of distributed handling
of a stack. That is, I publish an stgit-managed branch, you "stg
clone" it, you create your own patches on top of that, and when I
refresh my stack, you can just "stg pull" it as you would do if my
published work was a standard non-rewinding git branch.
> >I think it's always wrong to lose local commits. I think StGIT should
> >refuse to rebase if a merge would be needed
Right, we should make it so losing local commits cannot be done by
error. However, we cannot rely on the branch topology at the time
we're rebasing. Consider those 2 use cases:
- my stack forks off a non-rewinding branch, and I "stg commit" part
of it, then "stg pull"
- my stack forks off a rewinding branch, and I use "git fetch" to look
at what's new upstream, then I decide it's a good time to rebase, and
run "stg pull" (or preferably "stg rebase" to avoid fetching more
recent commits by error)
In the 2 cases "git pull" would do a merge. One crucial thing
distinguishes the 2 cases, is that in the 1st case we have "manually"
messed with the stack base. By "manually", I mean we changed the
stack base by other means than pulling/rebasing, but this notion
possibly needs some tuning. "stg commit" is an example, "stg
uncommit" is another, and both would cause "git pull" to do a merge
*because rebasing would not be what you want*, whereas in the
rewinding-branch use-case *what you is precisely rebasing*.
What we could do then, is having "rebase" and "pull" record an
orig-base ref as a "backup copy" of the the new base, and first refuse
to do the job (unless --force'd) if the base does not match its backup
(that is, if the user used "commit" or "uncommit").
> >or the rebase would go back in history (in other words, if
> >git-pull would not go to the remote revision).
I'm less sure about the use-case you're trying to address here. Could
you please give more details ? The only case I can think of would be
that of a rewinding branch that would have been just that, rewinded,
so it should be handled differently than when any new commit would
exist on top of this ancestor commit.
> >If we look at it from the user standpoint, the branches could be
> >distinguished by the use model:
> >
> >1) Tracking branch: pull is OK, commit is not OK, push is not OK. All
> >development is done in StGIT patches and sent to others.
> >
> >2) Development branch: commit is OK, push is OK, pull is OK but no
> >merges by default.
Right, those ones are probably the most used.
> >3) Merge branch: pull is OK, even with automatic merge, commit is OK,
> >merge is OK.
This one I'm not sure to understand well. Could you please describe
it in more details, perhaps in terms of the relation with other repos,
and of the most distinctive local operations ?
> I probably have another situation - a branch managed partially with
> StGIT but GIT commits (or 'stg commit') used and pulling would lead to
> a merge of the base, followed by patch pushing. This would work if we
> use git-pull rather than git-fetch.
You mean, a branch to which possibly several devs would commit (or to
which you want to commit multiple topic branches yourself), and where
you want to keep track of merges between these branches (as opposed to
rebasing), while still using stgit locally ?
> >> The solution would be to define the following in your gitconfig file
> >> (either ~/.gitconfig or .git/config; a full example in StGIT's
> >> examples/gitconfig):
> >>
> >> [stgit]
> >> pullcmd = git-pull
> >> pull-does-rebase = no
> >>
> >> The last line would tell StGIT not to do the rebasing and let git-pull
> >> handle it.
> >
> >It's actually my deliberate choice to subject myself to the pains of the
> >default configuration. I don't want to live in backwards compatible
> >environment until it rots away. I'll rather eat the dogfood we are
> >offering to others :)
>
> I don't consider this as a backward-compatibility feature. It simply
> targets a different workflow and it would be even better if we have it
> per-branch. The default should be the current fetch+rebase (as the
> most common case would be to use StGIT commands only) but with a
> warning if stack base fast-forwarding is not possible.
One way to handle different workflows could be to define a particular
workflow with a set of settings such as pullcmd and pull-does-rebase.
That way, we could say eg. "stg branch --workflow=<id>" to set the
vars in one run.
Best regards,
--
Yann.
^ permalink raw reply [relevance 1%]
* [PATCH 8/8] convert remaining users of "cmp" to "git diff"
@ 2007-02-25 22:38 2% Johannes Schindelin
0 siblings, 0 replies; 200+ results
From: Johannes Schindelin @ 2007-02-25 22:38 UTC (permalink / raw)
To: git, junkio
This is really
$ perl -pi.bak -e \
"s/(^\s*|'|\"|^\s*if |&&\s*)cmp /\1git diff /" t/*.sh
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
BTW all tests pass with this series...
t/t1002-read-tree-m-u-2way.sh | 32 +++++++++++++-------------
t/t1003-read-tree-prefix.sh | 2 +-
t/t1020-subdirectory.sh | 16 ++++++------
t/t1200-tutorial.sh | 22 +++++++++---------
t/t1300-repo-config.sh | 46 +++++++++++++++++++-------------------
t/t2101-update-index-reupdate.sh | 12 +++++-----
t/t3300-funny-names.sh | 2 +-
t/t4012-diff-binary.sh | 4 +-
t/t4109-apply-multifrag.sh | 6 ++--
t/t4110-apply-scan.sh | 2 +-
t/t5300-pack-object.sh | 12 +++++-----
t/t5400-send-pack.sh | 4 +-
t/t6021-merge-criss-cross.sh | 2 +-
t/t9101-git-svn-props.sh | 4 +-
t/t9105-git-svn-commit-diff.sh | 4 +-
t/t9107-git-svn-migrate.sh | 2 +-
t/t9108-git-svn-glob.sh | 4 +-
17 files changed, 88 insertions(+), 88 deletions(-)
diff --git a/t/t1002-read-tree-m-u-2way.sh b/t/t1002-read-tree-m-u-2way.sh
index 87fe993..2a70ee9 100755
--- a/t/t1002-read-tree-m-u-2way.sh
+++ b/t/t1002-read-tree-m-u-2way.sh
@@ -59,9 +59,9 @@ test_expect_success \
git-read-tree --reset -u $treeH &&
git-read-tree -m -u $treeH $treeM &&
git-ls-files --stage >1-3.out &&
- cmp M.out 1-3.out &&
+ git diff M.out 1-3.out &&
sum bozbar frotz nitfol >actual3.sum &&
- cmp M.sum actual3.sum &&
+ git diff M.sum actual3.sum &&
check_cache_at bozbar clean &&
check_cache_at frotz clean &&
check_cache_at nitfol clean'
@@ -79,7 +79,7 @@ test_expect_success \
compare_change 4diff.out expected &&
check_cache_at yomin clean &&
sum bozbar frotz nitfol >actual4.sum &&
- cmp M.sum actual4.sum &&
+ git diff M.sum actual4.sum &&
echo yomin >yomin1 &&
diff yomin yomin1 &&
rm -f yomin1'
@@ -98,7 +98,7 @@ test_expect_success \
compare_change 5diff.out expected &&
check_cache_at yomin dirty &&
sum bozbar frotz nitfol >actual5.sum &&
- cmp M.sum actual5.sum &&
+ git diff M.sum actual5.sum &&
: dirty index should have prevented -u from checking it out. &&
echo yomin yomin >yomin1 &&
diff yomin yomin1 &&
@@ -115,7 +115,7 @@ test_expect_success \
diff -U0 M.out 6.out &&
check_cache_at frotz clean &&
sum bozbar frotz nitfol >actual3.sum &&
- cmp M.sum actual3.sum &&
+ git diff M.sum actual3.sum &&
echo frotz >frotz1 &&
diff frotz frotz1 &&
rm -f frotz1'
@@ -132,7 +132,7 @@ test_expect_success \
diff -U0 M.out 7.out &&
check_cache_at frotz dirty &&
sum bozbar frotz nitfol >actual7.sum &&
- if cmp M.sum actual7.sum; then false; else :; fi &&
+ if git diff M.sum actual7.sum; then false; else :; fi &&
: dirty index should have prevented -u from checking it out. &&
echo frotz frotz >frotz1 &&
diff frotz frotz1 &&
@@ -163,9 +163,9 @@ test_expect_success \
git-update-index --add rezrov &&
git-read-tree -m -u $treeH $treeM &&
git-ls-files --stage >10.out &&
- cmp M.out 10.out &&
+ git diff M.out 10.out &&
sum bozbar frotz nitfol >actual10.sum &&
- cmp M.sum actual10.sum'
+ git diff M.sum actual10.sum'
test_expect_success \
'11 - dirty path removed.' \
@@ -210,9 +210,9 @@ test_expect_success \
compare_change 14diff.out expected &&
sum bozbar frotz >actual14.sum &&
grep -v nitfol M.sum > expected14.sum &&
- cmp expected14.sum actual14.sum &&
+ git diff expected14.sum actual14.sum &&
sum bozbar frotz nitfol >actual14a.sum &&
- if cmp M.sum actual14a.sum; then false; else :; fi &&
+ if git diff M.sum actual14a.sum; then false; else :; fi &&
check_cache_at nitfol clean &&
echo nitfol nitfol >nitfol1 &&
diff nitfol nitfol1 &&
@@ -232,9 +232,9 @@ test_expect_success \
check_cache_at nitfol dirty &&
sum bozbar frotz >actual15.sum &&
grep -v nitfol M.sum > expected15.sum &&
- cmp expected15.sum actual15.sum &&
+ git diff expected15.sum actual15.sum &&
sum bozbar frotz nitfol >actual15a.sum &&
- if cmp M.sum actual15a.sum; then false; else :; fi &&
+ if git diff M.sum actual15a.sum; then false; else :; fi &&
echo nitfol nitfol nitfol >nitfol1 &&
diff nitfol nitfol1 &&
rm -f nitfol1'
@@ -267,7 +267,7 @@ test_expect_success \
diff -U0 M.out 18.out &&
check_cache_at bozbar clean &&
sum bozbar frotz nitfol >actual18.sum &&
- cmp M.sum actual18.sum'
+ git diff M.sum actual18.sum'
test_expect_success \
'19 - local change already having a good result, further modified.' \
@@ -282,9 +282,9 @@ test_expect_success \
check_cache_at bozbar dirty &&
sum frotz nitfol >actual19.sum &&
grep -v bozbar M.sum > expected19.sum &&
- cmp expected19.sum actual19.sum &&
+ git diff expected19.sum actual19.sum &&
sum bozbar frotz nitfol >actual19a.sum &&
- if cmp M.sum actual19a.sum; then false; else :; fi &&
+ if git diff M.sum actual19a.sum; then false; else :; fi &&
echo gnusto gnusto >bozbar1 &&
diff bozbar bozbar1 &&
rm -f bozbar1'
@@ -300,7 +300,7 @@ test_expect_success \
diff -U0 M.out 20.out &&
check_cache_at bozbar clean &&
sum bozbar frotz nitfol >actual20.sum &&
- cmp M.sum actual20.sum'
+ git diff M.sum actual20.sum'
test_expect_success \
'21 - no local change, dirty cache.' \
diff --git a/t/t1003-read-tree-prefix.sh b/t/t1003-read-tree-prefix.sh
index 48ab117..4029f57 100755
--- a/t/t1003-read-tree-prefix.sh
+++ b/t/t1003-read-tree-prefix.sh
@@ -21,7 +21,7 @@ two/one' >expect
test_expect_success 'read-tree --prefix' '
git-read-tree --prefix=two/ $tree &&
git-ls-files >actual &&
- cmp expect actual
+ git diff expect actual
'
test_done
diff --git a/t/t1020-subdirectory.sh b/t/t1020-subdirectory.sh
index 1e8f9e5..22588bb 100755
--- a/t/t1020-subdirectory.sh
+++ b/t/t1020-subdirectory.sh
@@ -46,10 +46,10 @@ test_expect_success 'cat-file' '
two=`expr "$two" : "[0-7]* \\([0-9a-f]*\\)"` &&
echo "$two" &&
git-cat-file -p "$two" >actual &&
- cmp dir/two actual &&
+ git diff dir/two actual &&
cd dir &&
git-cat-file -p "$two" >actual &&
- cmp two actual
+ git diff two actual
'
rm -f actual dir/actual
@@ -86,10 +86,10 @@ test_expect_success 'write-tree' '
test_expect_success 'checkout-index' '
cd $HERE &&
git-checkout-index -f -u one &&
- cmp one original.one &&
+ git diff one original.one &&
cd dir &&
git-checkout-index -f -u two &&
- cmp two ../original.two
+ git diff two ../original.two
'
test_expect_success 'read-tree' '
@@ -97,13 +97,13 @@ test_expect_success 'read-tree' '
rm -f one dir/two &&
tree=`git-write-tree` &&
git-read-tree --reset -u "$tree" &&
- cmp one original.one &&
- cmp dir/two original.two &&
+ git diff one original.one &&
+ git diff dir/two original.two &&
cd dir &&
rm -f two &&
git-read-tree --reset -u "$tree" &&
- cmp two ../original.two &&
- cmp ../one ../original.one
+ git diff two ../original.two &&
+ git diff ../one ../original.one
'
test_expect_success 'no file/rev ambiguity check inside .git' '
diff --git a/t/t1200-tutorial.sh b/t/t1200-tutorial.sh
index ca2c30f..a3c2650 100755
--- a/t/t1200-tutorial.sh
+++ b/t/t1200-tutorial.sh
@@ -27,9 +27,9 @@ index 557db03..263414f 100644
+It's a new day for git
EOF
git-diff-files -p > diff.output
-test_expect_success 'git-diff-files -p' 'cmp diff.expect diff.output'
+test_expect_success 'git-diff-files -p' 'git diff diff.expect diff.output'
git diff > diff.output
-test_expect_success 'git diff' 'cmp diff.expect diff.output'
+test_expect_success 'git diff' 'git diff diff.expect diff.output'
tree=$(git-write-tree 2>/dev/null)
@@ -38,10 +38,10 @@ test_expect_success 'tree' "test 8988da15d077d4829fc51d8544c097def6644dbb = $tre
output="$(echo "Initial commit" | git-commit-tree $(git-write-tree) 2>&1 > .git/refs/heads/master)"
git-diff-index -p HEAD > diff.output
-test_expect_success 'git-diff-index -p HEAD' 'cmp diff.expect diff.output'
+test_expect_success 'git-diff-index -p HEAD' 'git diff diff.expect diff.output'
git diff HEAD > diff.output
-test_expect_success 'git diff HEAD' 'cmp diff.expect diff.output'
+test_expect_success 'git diff HEAD' 'git diff diff.expect diff.output'
#rm hello
#test_expect_success 'git-read-tree --reset HEAD' "git-read-tree --reset HEAD ; test \"hello: needs update\" = \"$(git-update-index --refresh)\""
@@ -73,15 +73,15 @@ git-whatchanged -p --root | \
sed -e "1s/^\(.\{7\}\).\{40\}/\1VARIABLE/" \
-e "2,3s/^\(.\{8\}\).*$/\1VARIABLE/" \
> whatchanged.output
-test_expect_success 'git-whatchanged -p --root' 'cmp whatchanged.expect whatchanged.output'
+test_expect_success 'git-whatchanged -p --root' 'git diff whatchanged.expect whatchanged.output'
git tag my-first-tag
-test_expect_success 'git tag my-first-tag' 'cmp .git/refs/heads/master .git/refs/tags/my-first-tag'
+test_expect_success 'git tag my-first-tag' 'git diff .git/refs/heads/master .git/refs/tags/my-first-tag'
# TODO: test git-clone
git checkout -b mybranch
-test_expect_success 'git checkout -b mybranch' 'cmp .git/refs/heads/master .git/refs/heads/mybranch'
+test_expect_success 'git checkout -b mybranch' 'git diff .git/refs/heads/master .git/refs/heads/mybranch'
cat > branch.expect <<EOF
master
@@ -89,7 +89,7 @@ cat > branch.expect <<EOF
EOF
git branch > branch.output
-test_expect_success 'git branch' 'cmp branch.expect branch.output'
+test_expect_success 'git branch' 'git diff branch.expect branch.output'
git checkout mybranch
echo "Work, work, work" >>hello
@@ -125,7 +125,7 @@ cat > show-branch.expect << EOF
EOF
git show-branch --topo-order master mybranch > show-branch.output
-test_expect_success 'git show-branch' 'cmp show-branch.expect show-branch.output'
+test_expect_success 'git show-branch' 'git diff show-branch.expect show-branch.output'
git checkout mybranch
@@ -138,7 +138,7 @@ EOF
git merge -s "Merge upstream changes." master | \
sed -e "1s/[0-9a-f]\{40\}/VARIABLE/g" >resolve.output
-test_expect_success 'git resolve' 'cmp resolve.expect resolve.output'
+test_expect_success 'git resolve' 'git diff resolve.expect resolve.output'
cat > show-branch2.expect << EOF
! [master] Merged "mybranch" changes.
@@ -148,7 +148,7 @@ cat > show-branch2.expect << EOF
EOF
git show-branch --topo-order master mybranch > show-branch2.output
-test_expect_success 'git show-branch' 'cmp show-branch2.expect show-branch2.output'
+test_expect_success 'git show-branch' 'git diff show-branch2.expect show-branch2.output'
# TODO: test git fetch
diff --git a/t/t1300-repo-config.sh b/t/t1300-repo-config.sh
index 84a5939..3753e9f 100755
--- a/t/t1300-repo-config.sh
+++ b/t/t1300-repo-config.sh
@@ -16,7 +16,7 @@ cat > expect << EOF
penguin = little blue
EOF
-test_expect_success 'initial' 'cmp .git/config expect'
+test_expect_success 'initial' 'git diff .git/config expect'
git-config Core.Movie BadPhysics
@@ -26,7 +26,7 @@ cat > expect << EOF
Movie = BadPhysics
EOF
-test_expect_success 'mixed case' 'cmp .git/config expect'
+test_expect_success 'mixed case' 'git diff .git/config expect'
git-config Cores.WhatEver Second
@@ -38,7 +38,7 @@ cat > expect << EOF
WhatEver = Second
EOF
-test_expect_success 'similar section' 'cmp .git/config expect'
+test_expect_success 'similar section' 'git diff .git/config expect'
git-config CORE.UPPERCASE true
@@ -51,7 +51,7 @@ cat > expect << EOF
WhatEver = Second
EOF
-test_expect_success 'similar section' 'cmp .git/config expect'
+test_expect_success 'similar section' 'git diff .git/config expect'
test_expect_success 'replace with non-match' \
'git-config core.penguin kingpin !blue'
@@ -69,7 +69,7 @@ cat > expect << EOF
WhatEver = Second
EOF
-test_expect_success 'non-match result' 'cmp .git/config expect'
+test_expect_success 'non-match result' 'git diff .git/config expect'
cat > .git/config << EOF
[beta] ; silly comment # another comment
@@ -97,7 +97,7 @@ noIndent= sillyValue ; 'nother silly comment
[nextSection] noNewline = ouch
EOF
-test_expect_success 'multiple unset is correct' 'cmp .git/config expect'
+test_expect_success 'multiple unset is correct' 'git diff .git/config expect'
mv .git/config2 .git/config
@@ -114,7 +114,7 @@ noIndent= sillyValue ; 'nother silly comment
[nextSection] noNewline = ouch
EOF
-test_expect_success 'all replaced' 'cmp .git/config expect'
+test_expect_success 'all replaced' 'git diff .git/config expect'
git-config beta.haha alpha
@@ -128,7 +128,7 @@ noIndent= sillyValue ; 'nother silly comment
[nextSection] noNewline = ouch
EOF
-test_expect_success 'really mean test' 'cmp .git/config expect'
+test_expect_success 'really mean test' 'git diff .git/config expect'
git-config nextsection.nonewline wow
@@ -143,7 +143,7 @@ noIndent= sillyValue ; 'nother silly comment
nonewline = wow
EOF
-test_expect_success 'really really mean test' 'cmp .git/config expect'
+test_expect_success 'really really mean test' 'git diff .git/config expect'
test_expect_success 'get value' 'test alpha = $(git-config beta.haha)'
git-config --unset beta.haha
@@ -158,7 +158,7 @@ noIndent= sillyValue ; 'nother silly comment
nonewline = wow
EOF
-test_expect_success 'unset' 'cmp .git/config expect'
+test_expect_success 'unset' 'git diff .git/config expect'
git-config nextsection.NoNewLine "wow2 for me" "for me$"
@@ -173,7 +173,7 @@ noIndent= sillyValue ; 'nother silly comment
NoNewLine = wow2 for me
EOF
-test_expect_success 'multivar' 'cmp .git/config expect'
+test_expect_success 'multivar' 'git diff .git/config expect'
test_expect_success 'non-match' \
'git-config --get nextsection.nonewline !for'
@@ -200,7 +200,7 @@ noIndent= sillyValue ; 'nother silly comment
NoNewLine = wow2 for me
EOF
-test_expect_success 'multivar replace' 'cmp .git/config expect'
+test_expect_success 'multivar replace' 'git diff .git/config expect'
test_expect_failure 'ambiguous value' 'git-config nextsection.nonewline'
@@ -222,7 +222,7 @@ noIndent= sillyValue ; 'nother silly comment
NoNewLine = wow2 for me
EOF
-test_expect_success 'multivar unset' 'cmp .git/config expect'
+test_expect_success 'multivar unset' 'git diff .git/config expect'
test_expect_failure 'invalid key' 'git-config inval.2key blabla'
@@ -245,7 +245,7 @@ noIndent= sillyValue ; 'nother silly comment
Alpha = beta
EOF
-test_expect_success 'hierarchical section value' 'cmp .git/config expect'
+test_expect_success 'hierarchical section value' 'git diff .git/config expect'
cat > expect << EOF
beta.noindent=sillyValue
@@ -255,7 +255,7 @@ version.1.2.3eX.alpha=beta
EOF
test_expect_success 'working --list' \
- 'git-config --list > output && cmp output expect'
+ 'git-config --list > output && git diff output expect'
cat > expect << EOF
beta.noindent sillyValue
@@ -263,7 +263,7 @@ nextsection.nonewline wow2 for me
EOF
test_expect_success '--get-regexp' \
- 'git-config --get-regexp in > output && cmp output expect'
+ 'git-config --get-regexp in > output && git diff output expect'
git-config --add nextsection.nonewline "wow4 for you"
@@ -273,7 +273,7 @@ wow4 for you
EOF
test_expect_success '--add' \
- 'git-config --get-all nextsection.nonewline > output && cmp output expect'
+ 'git-config --get-all nextsection.nonewline > output && git diff output expect'
cat > .git/config << EOF
[novalue]
@@ -302,7 +302,7 @@ cat > expect << EOF
x = y
EOF
-test_expect_success 'new section is partial match of another' 'cmp .git/config expect'
+test_expect_success 'new section is partial match of another' 'git diff .git/config expect'
git-config b.x y
git-config a.b c
@@ -317,7 +317,7 @@ cat > expect << EOF
x = y
EOF
-test_expect_success 'new variable inserts into proper section' 'cmp .git/config expect'
+test_expect_success 'new variable inserts into proper section' 'git diff .git/config expect'
cat > other-config << EOF
[ein]
@@ -330,7 +330,7 @@ EOF
GIT_CONFIG=other-config git-config -l > output
-test_expect_success 'alternative GIT_CONFIG' 'cmp output expect'
+test_expect_success 'alternative GIT_CONFIG' 'git diff output expect'
GIT_CONFIG=other-config git-config anwohner.park ausweis
@@ -341,7 +341,7 @@ cat > expect << EOF
park = ausweis
EOF
-test_expect_success '--set in alternative GIT_CONFIG' 'cmp other-config expect'
+test_expect_success '--set in alternative GIT_CONFIG' 'git diff other-config expect'
cat > .git/config << EOF
# Hallo
@@ -416,7 +416,7 @@ cat > expect << EOF
hash = "test#test"
EOF
-test_expect_success 'quoting' 'cmp .git/config expect'
+test_expect_success 'quoting' 'git diff .git/config expect'
test_expect_failure 'key with newline' 'git config key.with\\\
newline 123'
@@ -442,7 +442,7 @@ EOF
git config --list > result
-test_expect_success 'value continued on next line' 'cmp result expect'
+test_expect_success 'value continued on next line' 'git diff result expect'
test_done
diff --git a/t/t2101-update-index-reupdate.sh b/t/t2101-update-index-reupdate.sh
index a78ea7f..723a682 100755
--- a/t/t2101-update-index-reupdate.sh
+++ b/t/t2101-update-index-reupdate.sh
@@ -17,7 +17,7 @@ test_expect_success 'update-index --add' \
echo goodbye people >file2 &&
git-update-index --add file1 file2 &&
git-ls-files -s >current &&
- cmp current expected'
+ git diff current expected'
test_expect_success 'update-index --again' \
'rm -f file1 &&
@@ -30,7 +30,7 @@ test_expect_success 'update-index --again' \
echo happy - failed as expected
fi &&
git-ls-files -s >current &&
- cmp current expected'
+ git diff current expected'
cat > expected <<\EOF
100644 0f1ae1422c2bf43f117d3dbd715c988a9ed2103f 0 file2
@@ -38,7 +38,7 @@ EOF
test_expect_success 'update-index --remove --again' \
'git-update-index --remove --again &&
git-ls-files -s >current &&
- cmp current expected'
+ git diff current expected'
test_expect_success 'first commit' 'git-commit -m initial'
@@ -55,7 +55,7 @@ test_expect_success 'update-index again' \
echo happy >dir1/file3 &&
git-update-index --again &&
git-ls-files -s >current &&
- cmp current expected'
+ git diff current expected'
cat > expected <<\EOF
100644 d7fb3f695f06c759dbf3ab00046e7cc2da22d10f 0 dir1/file3
@@ -68,7 +68,7 @@ test_expect_success 'update-index --update from subdir' \
git-update-index --again &&
cd .. &&
git-ls-files -s >current &&
- cmp current expected'
+ git diff current expected'
cat > expected <<\EOF
100644 594fb5bb1759d90998e2bf2a38261ae8e243c760 0 dir1/file3
@@ -79,6 +79,6 @@ test_expect_success 'update-index --update with pathspec' \
cat file2 >dir1/file3 &&
git-update-index --again dir1/ &&
git-ls-files -s >current &&
- cmp current expected'
+ git diff current expected'
test_done
diff --git a/t/t3300-funny-names.sh b/t/t3300-funny-names.sh
index b5a1400..5913152 100755
--- a/t/t3300-funny-names.sh
+++ b/t/t3300-funny-names.sh
@@ -24,7 +24,7 @@ EOF
cat >"$p1" "$p0"
echo 'Foo Bar Baz' >"$p2"
-test -f "$p1" && cmp "$p0" "$p1" || {
+test -f "$p1" && git diff "$p0" "$p1" || {
# since FAT/NTFS does not allow tabs in filenames, skip this test
say 'Your filesystem does not allow tabs in filenames, test skipped.'
test_done
diff --git a/t/t4012-diff-binary.sh b/t/t4012-diff-binary.sh
index 323606c..c5f530f 100755
--- a/t/t4012-diff-binary.sh
+++ b/t/t4012-diff-binary.sh
@@ -25,11 +25,11 @@ cat > expected <<\EOF
EOF
test_expect_success 'diff without --binary' \
'git-diff | git-apply --stat --summary >current &&
- cmp current expected'
+ git diff current expected'
test_expect_success 'diff with --binary' \
'git-diff --binary | git-apply --stat --summary >current &&
- cmp current expected'
+ git diff current expected'
# apply needs to be able to skip the binary material correctly
# in order to report the line number of a corrupt patch.
diff --git a/t/t4109-apply-multifrag.sh b/t/t4109-apply-multifrag.sh
index 5988e1a..180febc 100755
--- a/t/t4109-apply-multifrag.sh
+++ b/t/t4109-apply-multifrag.sh
@@ -146,7 +146,7 @@ test_expect_success "S = patch (1)" \
'cat patch1.patch patch2.patch | patch -p1'
test_expect_success "S = cmp (1)" \
- 'cmp main.c.git main.c'
+ 'git diff main.c.git main.c'
rm -f main.c main.c.git
@@ -158,7 +158,7 @@ test_expect_success "S = patch (2)" \
'cat patch1.patch patch2.patch patch3.patch | patch -p1'
test_expect_success "S = cmp (2)" \
- 'cmp main.c.git main.c'
+ 'git diff main.c.git main.c'
rm -f main.c main.c.git
@@ -170,7 +170,7 @@ test_expect_success "S = patch (3)" \
'cat patch1.patch patch4.patch | patch -p1'
test_expect_success "S = cmp (3)" \
- 'cmp main.c.git main.c'
+ 'git diff main.c.git main.c'
test_done
diff --git a/t/t4110-apply-scan.sh b/t/t4110-apply-scan.sh
index 005f744..ec00ed6 100755
--- a/t/t4110-apply-scan.sh
+++ b/t/t4110-apply-scan.sh
@@ -95,7 +95,7 @@ test_expect_success "S = patch scan" \
mv new.txt patch.txt
test_expect_success "S = cmp" \
- 'cmp apply.txt patch.txt'
+ 'git diff apply.txt patch.txt'
test_done
diff --git a/t/t5300-pack-object.sh b/t/t5300-pack-object.sh
index f511547..522d7b2 100755
--- a/t/t5300-pack-object.sh
+++ b/t/t5300-pack-object.sh
@@ -56,7 +56,7 @@ test_expect_success \
'(cd ../.git && find objects -type f -print) |
while read path
do
- cmp $path ../.git/$path || {
+ git diff $path ../.git/$path || {
echo $path differs.
return 1
}
@@ -86,7 +86,7 @@ test_expect_success \
'(cd ../.git && find objects -type f -print) |
while read path
do
- cmp $path ../.git/$path || {
+ git diff $path ../.git/$path || {
echo $path differs.
return 1
}
@@ -182,17 +182,17 @@ test_expect_success \
'build pack index for an existing pack' \
'cp test-1-${packname_1}.pack test-3.pack &&
git-index-pack -o tmp.idx test-3.pack &&
- cmp tmp.idx test-1-${packname_1}.idx &&
+ git diff tmp.idx test-1-${packname_1}.idx &&
git-index-pack test-3.pack &&
- cmp test-3.idx test-1-${packname_1}.idx &&
+ git diff test-3.idx test-1-${packname_1}.idx &&
cp test-2-${packname_2}.pack test-3.pack &&
git-index-pack -o tmp.idx test-2-${packname_2}.pack &&
- cmp tmp.idx test-2-${packname_2}.idx &&
+ git diff tmp.idx test-2-${packname_2}.idx &&
git-index-pack test-3.pack &&
- cmp test-3.idx test-2-${packname_2}.idx &&
+ git diff test-3.idx test-2-${packname_2}.idx &&
:'
diff --git a/t/t5400-send-pack.sh b/t/t5400-send-pack.sh
index fc4a126..03c2692 100755
--- a/t/t5400-send-pack.sh
+++ b/t/t5400-send-pack.sh
@@ -77,7 +77,7 @@ test_expect_success \
echo >&2 Thanks, it correctly failed.
true
fi &&
- if cmp victim/.git/refs/heads/master .git/refs/heads/master
+ if git diff victim/.git/refs/heads/master .git/refs/heads/master
then
# should have been left as it was!
false
@@ -86,7 +86,7 @@ test_expect_success \
fi &&
# this should update
git-send-pack --force ./victim/.git/ master &&
- cmp victim/.git/refs/heads/master .git/refs/heads/master
+ git diff victim/.git/refs/heads/master .git/refs/heads/master
'
test_expect_success \
diff --git a/t/t6021-merge-criss-cross.sh b/t/t6021-merge-criss-cross.sh
index 499cafb..c9d43dd 100755
--- a/t/t6021-merge-criss-cross.sh
+++ b/t/t6021-merge-criss-cross.sh
@@ -87,6 +87,6 @@ cat > file-expect <<EOF
9
EOF
-test_expect_success 'Criss-cross merge result' 'cmp file file-expect'
+test_expect_success 'Criss-cross merge result' 'git diff file file-expect'
test_done
diff --git a/t/t9101-git-svn-props.sh b/t/t9101-git-svn-props.sh
index 622ea1c..28738d7 100755
--- a/t/t9101-git-svn-props.sh
+++ b/t/t9101-git-svn-props.sh
@@ -96,7 +96,7 @@ test_expect_success 'fetch and pull latest from svn and checkout a new wc' \
for i in crlf ne_crlf lf ne_lf cr ne_cr empty_cr empty_lf empty empty_crlf
do
- test_expect_success "Comparing $i" "cmp $i new_wc/$i"
+ test_expect_success "Comparing $i" "git diff $i new_wc/$i"
done
@@ -144,7 +144,7 @@ test_expect_success 'test show-ignore' "
svn commit -m 'propset svn:ignore'
cd .. &&
git-svn show-ignore > show-ignore.got &&
- cmp show-ignore.expect show-ignore.got
+ git diff show-ignore.expect show-ignore.got
"
test_done
diff --git a/t/t9105-git-svn-commit-diff.sh b/t/t9105-git-svn-commit-diff.sh
index c668dd1..082785e 100755
--- a/t/t9105-git-svn-commit-diff.sh
+++ b/t/t9105-git-svn-commit-diff.sh
@@ -28,7 +28,7 @@ test_expect_success 'test the commit-diff command' "
test -n '$prev' && test -n '$head' &&
git-svn commit-diff -r1 '$prev' '$head' '$svnrepo' &&
svn co $svnrepo wc &&
- cmp readme wc/readme
+ git diff readme wc/readme
"
test_expect_success 'commit-diff to a sub-directory (with git-svn config)' "
@@ -37,7 +37,7 @@ test_expect_success 'commit-diff to a sub-directory (with git-svn config)' "
git-svn fetch &&
git-svn commit-diff -r3 '$prev' '$head' &&
svn cat $svnrepo/subdir/readme > readme.2 &&
- cmp readme readme.2
+ git diff readme readme.2
"
test_done
diff --git a/t/t9107-git-svn-migrate.sh b/t/t9107-git-svn-migrate.sh
index dc2afda..37ae559 100755
--- a/t/t9107-git-svn-migrate.sh
+++ b/t/t9107-git-svn-migrate.sh
@@ -105,7 +105,7 @@ test_expect_success ".rev_db auto-converted to .rev_db.UUID" "
git-svn fetch -i trunk &&
test -L $GIT_DIR/svn/trunk/.rev_db &&
test -f \$expect &&
- cmp \$expect $GIT_DIR/svn/trunk/.rev_db
+ git diff \$expect $GIT_DIR/svn/trunk/.rev_db
"
test_done
diff --git a/t/t9108-git-svn-glob.sh b/t/t9108-git-svn-glob.sh
index db4344c..83b94ed 100755
--- a/t/t9108-git-svn-glob.sh
+++ b/t/t9108-git-svn-glob.sh
@@ -48,7 +48,7 @@ test_expect_success 'test refspec globbing' "
git-svn multi-fetch &&
git log --pretty=oneline refs/remotes/tags/end | \
sed -e 's/^.\{41\}//' > output.end &&
- cmp expect.end output.end &&
+ git diff expect.end output.end &&
test \"\`git rev-parse refs/remotes/tags/end~1\`\" = \
\"\`git rev-parse refs/remotes/branches/start\`\" &&
test \"\`git rev-parse refs/remotes/branches/start~2\`\" = \
@@ -80,7 +80,7 @@ test_expect_success 'test left-hand-side only globbing' "
\`git rev-parse refs/remotes/two/branches/start\` &&
git log --pretty=oneline refs/remotes/two/tags/end | \
sed -e 's/^.\{41\}//' > output.two &&
- cmp expect.two output.two
+ git diff expect.two output.two
"
test_done
--
1.5.0.1.788.g8ca52
^ permalink raw reply related [relevance 2%]
* Re: Google Summer of Code 2007
@ 2007-03-01 2:08 3% ` Jakub Narebski
0 siblings, 0 replies; 200+ results
From: Jakub Narebski @ 2007-03-01 2:08 UTC (permalink / raw)
To: git
Shawn O. Pearce wrote:
> ShadeHawk and robinr brought up Google's Summer of Code on #git the
> other day. I had also been thinking about seeing if we cannot get
> Git involved with SoC, so here goes... ;-)
>
> The application deadline for organizations is March 12th.
> The earliest that we can submit an application is March 5th, so we
> still have time to kick ideas around and see if the community is
> interested in participating in SoC.
Well, certainly there is a number of areas to work on. This includes:
* much talked on (and even with two different independent
implementations) _subproject (submodule) support_, which would
certainly help using git for large modular projects like KDE,
Mozilla or distributions.
* lightweight checkout aka. .gitlink idea, to have file which
would point to object directory, refs directory, index file
and current branch file. It could help submodule support.
* partial/sparse checkouts, where you can checkout for example
only Documentation directory, work on it, but commit full tree.
Sometimes it better suits than using submodules
* gitweb caching and other gitweb improvements: bringing together
all gitweb implementations. Perhaps gitweb maintainer could
come of it. Or at least gitweb admin for kernel.org
* builtinification and libification
* lazy clone aka remote alternates, if it can be done at all...
> Google's FAQ has a lot of details, but the important part which
> lists what should be included in an application can be found here:
>
> http://code.google.com/support/bin/answer.py?answer=60303&topic=10727
>
> I don't know how the great SoC filter works for organizations,
> but last year's list (found at http://code.google.com/soc/) has a
> number of projects listed on it that are actively using Git for their
> version control. It would be nice if the SoC program was able to
> benefit multiple projects in one shot, by helping to improve Git. :)
The other SCM which participated in SOC2006, Subversion and Monotone,
both are backed by organizations. Mercurial didn't participate, but has
a page with ideas for SOC2006.
If Eclipse is to participate, perhaps one of Eclipse projects could be
git plugin for Eclipse, or Java implementation of Git (perhaps with some
Java improvements :-), or perhaps some generic distributed SCM plugin
framework.
--
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git
^ permalink raw reply [relevance 3%]
* GIT v1.5.1-rc1
@ 2007-03-19 10:53 1% ` Junio C Hamano
0 siblings, 0 replies; 200+ results
From: Junio C Hamano @ 2007-03-19 10:53 UTC (permalink / raw)
To: git
Some 1000 messages ago, I sent out a short-term release plan and
listed the topics that we would want to have in 1.5.1. As of
last week, all of them have been cooked enough in 'next' and now
are in 'master'.
The last round to reach 1.5.0 took painfully long. While it was
worth it, considering that 1.5.0 is a big departure from 1.4.4
series and satisfied our "usability and teachability" goal, I
think we should slow down and make smaller releases a bit more
often. So I tagged the tip of the 'master' with -rc1 tag, after
fixing one issue that has been nagging me while it was in 'next'.
So from now on until the final, which I am hoping to do before
the end of month, please concentrate on fixes and "obviously
low-impact" improvements.
With the system we have in place that uses two primary
integration branches to manage git.git project, earth-shattering
enhancements or new commands could still be cooked in 'pu', or
theoretically even in 'next' without causing problems to the
stabilization effort, but I'd rather see people's attention on
perfecting what will be in 1.5.1 before starting anything new.
I expect to spend much less time looking at any material that
are not meant for 'master' until the end of the month, so please
consider that the chance of getting things in 'next' is very
slim from now on. I might queue new stuff in 'pu' only to give
a distribution point that is easier to access for everybody to
test, but I won't guarantee that the branch will even compile.
Having said that, there always are exceptions to the rule.
Some of the things we have reviewed and discussed on the list
for the past several days might have been good for 'next' (or
even 'master'). I did not have enough time to look at them
fully, I might have missed them, and/or I commented on them with
intention to cook them in 'next' but might have forgotten to
apply. If they are reasonably well isolated new features
(e.g. "remote show showing push entries") I would not mind
applying them, but please make convincing sales talk to explain
why your new feature is useful to users. If it is something so
commonly useful to be placed on "Everyday GIT", or tutorial,
adding a paragraph to these documents to show why it is a *must*
*have* is a good way to sell your ware, for example.
Also I might have dropped a handful patches to non-core area,
e.g. contrib/emacs/ and cvs interface. Please remind me of them
if they should be in 1.5.1 by cheering them on with your Acks,
resends, and follow-up patches.
Even though it is rather core area, I suspect that it wouldn't
be a change with huge impact to exploit what Linus did today to
allow optimizing pathspec pruning in tree_entry_interesting().
If such a change is done obviously correctly, I think it is Ok
to have it in 'next' and make it graduate to 'master' before
1.5.1 final.
Although we've talked about it for a while, the more I look at
the current code, the more I feel that resolving the issue of
"read-tree -m" gotcha that causes switching between branches
that have file (or symlink) A and a directory A would be quite
high impact, so unless there is an obviously correct fix, I'd
like to defer it post 1.5.1.
Finally, here is to review what we have so far to be in the
upcoming 1.5.1. Patches to Documentation/RelNotes-1.5.1.txt to
fill items I missed, older than ceb8442a, are very much
appreciated.
GIT v1.5.1 Release Notes (draft)
========================
Updates since v1.5.0
--------------------
* Deprecated commands and options.
- git-diff-stages and git-resolve have been removed.
* New commands and options.
- "git log" and friends take --reverse. This makes output
that typically goes reverse order in chronological order.
"git shortlog" usually lists commits in chronological order,
but with "--reverse", they are shown in reverse
chronological order.
- "git diff" learned --ignore-space-at-eol. This is a weaker
form of --ignore-space-change.
- "git diff --no-index pathA pathB" can be used as diff
replacement with git specific enhancements.
- "git diff --pretty=format:<string>" to allow more flexible
custom log output.
- "git diff --no-index" can read from '-' (standard input).
- "git diff" also learned --exit-code to exit with non-zero
status when it found differences. In the future we might
want to make this the default but that would be a rather big
backward incompatible change; it will stay as an option for
now.
- "git branch --track" can be used to set up configuration
variables to help it easier to base your work on branches
you track from a remote site.
- "git format-patch --attach" now emits attachments. Use
--inline to get an inlined multipart/mixed.
- "git name-rev" learned --refs=<pattern>, to limit the tags
used for naming the given revisions only to the ones
matching the given pattern.
- "git remote update" is to run "git fetch" for defined remotes
to update tracking branches.
- "git cvsimport" can now take '-d' to talk with a CVS
repository different from what are recorded in CVS/Root
(overriding it with environment CVSROOT does not work).
- "git bundle" can help sneaker-netting your changes between
repositories.
- "git mergetool" can help 3-way file-level conflict
resolution with your favorite graphical merge tools.
- A new configuration "core.symlinks" can be used to disable
symlinks on filesystems that do not support them; they are
checked out as regular files instead.
* Updated behaviour of existing commands.
- "git fsck" does not barf on corrupt loose objects.
- "git archimport" allows remapping when coming up with git
branch names from arch names.
- git-svn got almost a rewrite.
- core.autocrlf configuration, when set to 'true', makes git
to convert CRLF at the end of lines in text files to LF when
reading from the filesystem, and convert in reverse when
writing to the filesystem. The variable can be set to
'input', in which case the conversion happens only while
reading from the filesystem but files are written out with
LF at the end of lines. Currently, which paths to consider
'text' (i.e. be subjected to the autocrlf mechanism) is
decided purely based on the contents, but the plan is to
allow users to explicitly override this heuristic based on
paths.
- The behaviour of 'git-apply', when run in a subdirectory,
without --index nor --cached were inconsistent with that of
the command with these options. This was fixed to match the
behaviour with --index. A patch that is meant to be applied
with -p1 from the toplevel of the project tree can be
applied with any custom -p<n> option. A patch that is not
relative to the toplevel needs to be applied with -p<n>
option with or without --index (or --cached).
- "git diff" outputs a trailing HT when pathnames have embedded
SP on +++/--- header lines, in order to help "GNU patch" to
parse its output. "git apply" was already updated to accept
this modified output format since ce74618d (Sep 22, 2006).
- "git cvsserver" runs hooks/update and honors its exit status.
- "git cvsserver" can be told to send everything with -kb.
- "git diff --check" also honors the --color output option.
- "git name-rev" used to stress the fact that a ref is a tag too
much, by saying something like "v1.2.3^0~22". It now says
"v1.2.3~22" in such a case (it still says "v1.2.3^0" if it does
not talk about an ancestor of the commit that is tagged, which
makes sense).
- "git rev-list --boundary" now shows boundary markers for the
commits omitted by --max-age and --max-count condition.
- The configuration mechanism now reads $(prefix)/etc/gitconfig.
- "git apply --verbose" shows what preimage lines were wanted
when it couldn't find them.
- "git status" in a read-only repository got a bit saner.
- "git fetch" (hence "git clone" and "git pull") are less
noisy when the output does not go to tty.
- "git fetch" between repositories with many refs were slow
even when there are not many changes that needed
transferring. This has been sped up by partially rewriting
the heaviest parts in C.
- "git mailinfo" which splits an e-mail into a patch and the
metainformation was rewritten, thanks to Don Zickus. It
handles nested multipart better.
- send-email learned configurable bcc and chain-reply-to.
- Using objects from packs is now seriouly optimized by clever
use of a cache. This should be most noticeable in git-log
family of commands that involve reading many tree objects.
In addition, traversing revisions while filtering changes
with pathspecs is made faster by terminating the comparison
between the trees as early as possible.
* Hooks
- The sample update hook to show how to send out notification
e-mail was updated to show only new commits that appeared in
the repository. Earlier, it showed new commits that appeared
on the branch.
* Others
- git-revert, git-gc and git-cherry-pick are now built-ins.
^ permalink raw reply [relevance 1%]
* Re: .gitlink for Summer of Code
@ 2007-03-27 23:20 4% ` David Lang
0 siblings, 0 replies; 200+ results
From: David Lang @ 2007-03-27 23:20 UTC (permalink / raw)
To: Jakub Narebski; +Cc: git
On Wed, 28 Mar 2007, Jakub Narebski wrote:
>> if I'm working on the 'ubuntu superproject' it would be nice to be able to find
>> what is different between the 'Jan 2007' and 'April 2007' versions. one could
>> have the 2.6.19 kernel and the other would have 2.6.20. I don't care about all
>> the individual changes between these two states of the kernel, but I need to be
>> able to compile either one as part of my testing. If I bisect the in the
>> superproject to the commit that updated the kernel, then I would consider
>> getting the 'kernel subproject' history to be able to bisect the bug further (or
>> I may just report it to the kernel maintainers for them to check.
>
> I'd rather call this idea _sparse_ clone (not shallow), as you have only
> some points in the history, but they don't need to be top 'n' ones.
Ok I can see the difference in the definition of the two, the ideal would
probably be to have sparse and shallow clones be different instances of the same
mechanism.
sparse being specific points in the history, shallow being a range.
allow for multiple ranges, and the ability to 'fill in the blanks' later so
that points can become ranges and ranges can merge.
also having the server say 'it would only be XMB more to pull everything you
don't have, do you want to do this?' would cause more load on the server for
each of the partial pulls, but would encourage people to fill out partial
repositories instead of hitting the servers repeatedly.
David Lang
^ permalink raw reply [relevance 4%]
* [ANNOUNCE] GIT 1.5.1
@ 2007-04-04 9:12 1% Junio C Hamano
0 siblings, 0 replies; 200+ results
From: Junio C Hamano @ 2007-04-04 9:12 UTC (permalink / raw)
To: git; +Cc: linux-kernel
The latest feature release GIT 1.5.1 is available at the usual
places:
http://www.kernel.org/pub/software/scm/git/
git-1.5.1.tar.{gz,bz2} (tarball)
git-htmldocs-1.5.1.tar.{gz,bz2} (preformatted docs)
git-manpages-1.5.1.tar.{gz,bz2} (preformatted docs)
RPMS/$arch/git-*-1.5.1-1.$arch.rpm (RPM)
----------------------------------------------------------------
GIT v1.5.1 Release Notes
========================
Updates since v1.5.0
--------------------
* Deprecated commands and options.
- git-diff-stages and git-resolve have been removed.
* New commands and options.
- "git log" and friends take --reverse, which instructs them
to give their output in the order opposite from their usual.
They typically output from new to old, but with this option
their output would read from old to new. "git shortlog"
usually lists older commits first, but with this option,
they are shown from new to old.
- "git log --pretty=format:<string>" to allow more flexible
custom log output.
- "git diff" learned --ignore-space-at-eol. This is a weaker
form of --ignore-space-change.
- "git diff --no-index pathA pathB" can be used as diff
replacement with git specific enhancements.
- "git diff --no-index" can read from '-' (standard input).
- "git diff" also learned --exit-code to exit with non-zero
status when it found differences. In the future we might
want to make this the default but that would be a rather big
backward incompatible change; it will stay as an option for
now.
- "git diff --quiet" is --exit-code with output turned off,
meant for scripted use to quickly determine if there is any
tree-level difference.
- Textual patch generation with "git diff" without -w/-b
option has been significantly optimized. "git blame" got
faster because of the same change.
- "git log" and "git rev-list" has been optimized
significantly when they are used with pathspecs.
- "git branch --track" can be used to set up configuration
variables to help it easier to base your work on branches
you track from a remote site.
- "git format-patch --attach" now emits attachments. Use
--inline to get an inlined multipart/mixed.
- "git name-rev" learned --refs=<pattern>, to limit the tags
used for naming the given revisions only to the ones
matching the given pattern.
- "git remote update" is to run "git fetch" for defined remotes
to update tracking branches.
- "git cvsimport" can now take '-d' to talk with a CVS
repository different from what are recorded in CVS/Root
(overriding it with environment CVSROOT does not work).
- "git bundle" can help sneaker-netting your changes between
repositories.
- "git mergetool" can help 3-way file-level conflict
resolution with your favorite graphical merge tools.
- A new configuration "core.symlinks" can be used to disable
symlinks on filesystems that do not support them; they are
checked out as regular files instead.
- You can name a commit object with its first line of the
message. The syntax to use is ':/message text'. E.g.
$ git show ":/object name: introduce ':/<oneline prefix>' notation"
means the same thing as:
$ git show 28a4d940443806412effa246ecc7768a21553ec7
- "git bisect" learned a new command "run" that takes a script
to run after each revision is checked out to determine if it
is good or bad, to automate the bisection process.
- "git log" family learned a new traversal option --first-parent,
which does what the name suggests.
* Updated behavior of existing commands.
- "git-merge-recursive" used to barf when there are more than
one common ancestors for the merge, and merging them had a
rename/rename conflict. This has been fixed.
- "git fsck" does not barf on corrupt loose objects.
- "git rm" does not remove newly added files without -f.
- "git archimport" allows remapping when coming up with git
branch names from arch names.
- git-svn got almost a rewrite.
- core.autocrlf configuration, when set to 'true', makes git
to convert CRLF at the end of lines in text files to LF when
reading from the filesystem, and convert in reverse when
writing to the filesystem. The variable can be set to
'input', in which case the conversion happens only while
reading from the filesystem but files are written out with
LF at the end of lines. Currently, which paths to consider
'text' (i.e. be subjected to the autocrlf mechanism) is
decided purely based on the contents, but the plan is to
allow users to explicitly override this heuristic based on
paths.
- The behavior of 'git-apply', when run in a subdirectory,
without --index nor --cached were inconsistent with that of
the command with these options. This was fixed to match the
behavior with --index. A patch that is meant to be applied
with -p1 from the toplevel of the project tree can be
applied with any custom -p<n> option. A patch that is not
relative to the toplevel needs to be applied with -p<n>
option with or without --index (or --cached).
- "git diff" outputs a trailing HT when pathnames have embedded
SP on +++/--- header lines, in order to help "GNU patch" to
parse its output. "git apply" was already updated to accept
this modified output format since ce74618d (Sep 22, 2006).
- "git cvsserver" runs hooks/update and honors its exit status.
- "git cvsserver" can be told to send everything with -kb.
- "git diff --check" also honors the --color output option.
- "git name-rev" used to stress the fact that a ref is a tag too
much, by saying something like "v1.2.3^0~22". It now says
"v1.2.3~22" in such a case (it still says "v1.2.3^0" if it does
not talk about an ancestor of the commit that is tagged, which
makes sense).
- "git rev-list --boundary" now shows boundary markers for the
commits omitted by --max-age and --max-count condition.
- The configuration mechanism now reads $(prefix)/etc/gitconfig.
- "git apply --verbose" shows what preimage lines were wanted
when it couldn't find them.
- "git status" in a read-only repository got a bit saner.
- "git fetch" (hence "git clone" and "git pull") are less
noisy when the output does not go to tty.
- "git fetch" between repositories with many refs were slow
even when there are not many changes that needed
transferring. This has been sped up by partially rewriting
the heaviest parts in C.
- "git mailinfo" which splits an e-mail into a patch and the
meta-information was rewritten, thanks to Don Zickus. It
handles nested multipart better. The command was broken for
a brief period on 'master' branch since 1.5.0 but the
breakage is fixed now.
- send-email learned configurable bcc and chain-reply-to.
- "git remote show $remote" also talks about branches that
would be pushed if you run "git push remote".
- Using objects from packs is now seriously optimized by clever
use of a cache. This should be most noticeable in git-log
family of commands that involve reading many tree objects.
In addition, traversing revisions while filtering changes
with pathspecs is made faster by terminating the comparison
between the trees as early as possible.
* Hooks
- The part to send out notification e-mails was removed from
the sample update hook, as it was not an appropriate place
to do so. The proper place to do this is the new post-receive
hook. An example hook has been added to contrib/hooks/.
* Others
- git-revert, git-gc and git-cherry-pick are now built-ins.
Fixes since v1.5.0
------------------
These are all in v1.5.0.x series.
* Documentation updates
- Clarifications and corrections to 1.5.0 release notes.
- The main documentation did not link to git-remote documentation.
- Clarified introductory text of git-rebase documentation.
- Converted remaining mentions of update-index on Porcelain
documents to git-add/git-rm.
- Some i18n.* configuration variables were incorrectly
described as core.*; fixed.
- added and clarified core.bare, core.legacyheaders configurations.
- updated "git-clone --depth" documentation.
- user-manual updates.
- Options to 'git remote add' were described insufficiently.
- Configuration format.suffix was not documented.
- Other formatting and spelling fixes.
- user-manual has better cross references.
- gitweb installation/deployment procedure is now documented.
* Bugfixes
- git-upload-pack closes unused pipe ends; earlier this caused
many zombies to hang around.
- git-rerere was recording the contents of earlier hunks
duplicated in later hunks. This prevented resolving the same
conflict when performing the same merge the other way around.
- git-add and git-update-index on a filesystem on which
executable bits are unreliable incorrectly reused st_mode
bits even when the path changed between symlink and regular
file.
- git-daemon marks the listening sockets with FD_CLOEXEC so
that it won't be leaked into the children.
- segfault from git-blame when the mandatory pathname
parameter was missing was fixed; usage() message is given
instead.
- git-rev-list did not read $GIT_DIR/config file, which means
that did not honor i18n.logoutputencoding correctly.
- Automated merge conflict handling when changes to symbolic
links conflicted were completely broken. The merge-resolve
strategy created a regular file with conflict markers in it
in place of the symbolic link. The default strategy,
merge-recursive was even more broken. It removed the path
that was pointed at by the symbolic link. Both of these
problems have been fixed.
- 'git diff maint master next' did not correctly give combined
diff across three trees.
- 'git fast-import' portability fix for Solaris.
- 'git show-ref --verify' without arguments did not error out
but segfaulted.
- 'git diff :tracked-file `pwd`/an-untracked-file' gave an extra
slashes after a/ and b/.
- 'git format-patch' produced too long filenames if the commit
message had too long line at the beginning.
- Running 'make all' and then without changing anything
running 'make install' still rebuilt some files. This
was inconvenient when building as yourself and then
installing as root (especially problematic when the source
directory is on NFS and root is mapped to nobody).
- 'git-rerere' failed to deal with two unconflicted paths that
sorted next to each other.
- 'git-rerere' attempted to open(2) a symlink and failed if
there was a conflict. Since a conflicting change to a
symlink would not benefit from rerere anyway, the command
now ignores conflicting changes to symlinks.
- 'git-repack' did not like to pass more than 64 arguments
internally to underlying 'rev-list' logic, which made it
impossible to repack after accumulating many (small) packs
in the repository.
- 'git-diff' to review the combined diff during a conflicted
merge were not reading the working tree version correctly
when changes to a symbolic link conflicted. It should have
read the data using readlink(2) but read from the regular
file the symbolic link pointed at.
- 'git-remote' did not like period in a remote's name.
- 'git.el' honors the commit coding system from the configuration.
- 'blameview' in contrib/ correctly digs deeper when a line is
clicked.
- 'http-push' correctly makes sure the remote side has leading
path. Earlier it started in the middle of the path, and
incorrectly.
- 'git-merge' did not exit with non-zero status when the
working tree was dirty and cannot fast forward. It does
now.
- 'cvsexportcommit' does not lose yet-to-be-used message file.
- int-vs-size_t typefix when running combined diff on files
over 2GB long.
- 'git apply --whitespace=strip' should not touch unmodified
lines.
- 'git-mailinfo' choke when a logical header line was too long.
- 'git show A..B' did not error out. Negative ref ("not A" in
this example) does not make sense for the purpose of the
command, so now it errors out.
- 'git fmt-merge-msg --file' without file parameter did not
correctly error out.
- 'git archimport' barfed upon encountering a commit without
summary.
- 'git index-pack' did not protect itself from getting a short
read out of pread(2).
- 'git http-push' had a few buffer overruns.
- Build dependency fixes to rebuild fetch.o when other headers
change.
- git.el does not add duplicate sign-off lines.
- git-commit shows the full stat of the resulting commit, not
just about the files in the current directory, when run from
a subdirectory.
- "git-checkout -m '@{8 hours ago}'" had a funny failure from
eval; fixed.
- git-merge (hence git-pull) did not refuse fast-forwarding
when the working tree had local changes that would have
conflicted with it.
- a handful small fixes to gitweb.
- build procedure for user-manual is fixed not to require locally
installed stylesheets.
- "git commit $paths" on paths whose earlier contents were
already updated in the index were failing out.
* Tweaks
- sliding mmap() inefficiently mmaped the same region of a
packfile with an access pattern that used objects in the
reverse order. This has been made more efficient.
^ permalink raw reply [relevance 1%]
* Re: [PATCH 5/6] Teach "fsck" not to follow subproject links
@ 2007-04-12 18:32 1% ` Dana How
0 siblings, 0 replies; 200+ results
From: Dana How @ 2007-04-12 18:32 UTC (permalink / raw)
To: Linus Torvalds
Cc: David Lang, Sam Vilain, Git Mailing List, Junio C Hamano, danahow
On 4/11/07, Linus Torvalds <torvalds@linux-foundation.org> wrote:
> On Wed, 11 Apr 2007, David Lang wrote:
> > this is why I was suggesting a --multiple-project option to let you tell fsck
> > about all of the repositories that it needs to look for refs in.
>
> Well, just from a personal observation:
> - I would *personally* actually refuse to share objects with anybody
> else.
>
> I just find the idea too scary. Somebody doing something bad to their
> object store by mistake (running "git prune" without realizing that there
> are *my* objects there too, or just deciding that they want to play with
> the object directory by hand, or running a new fancy experimental importer
> that has a subtle bug wrt object handling or anything like that).
>
> I'll endorse use "alternates" files, but partly because I know the main
> project is safe (any alternates usage is in the "satellite" clones anyway,
> and they will never write to the alternate object directory), and partly
> because at least for the kernel, we don't have branches that get reset in
> the main project, so there's no reason to fear that a "git repack -a -d"
> will ever screw up any of the satellite repositories even by mistake.
>
> But for git projects, even alternates isn't safe, in case somebody bases
> their own work on a version of "pu" that eventually goes away (even with
> reflogs, pruning *eventually* takes place).
>
> So I tend to think that alternates and shared object directories are
> really for "temporary" stuff, or for *managed* repositories that are at
> git *hosting* sites (eg repo.or.cz), and where there is some other safety
> involved, ie users don't actually access the object directories directly
> in any way.
>
> So I've at least personally come to the conclusion that for a *developer*
> (as opposed to a hosting site!), shared object directories just never make
> sense. The downsides are just too big. Even alternates is something where
> you just need to be fairly careful!
These arguments all seem pretty convincing to me --
maybe the problem is that I'm not a "*developer*" right now.
Instead I'm part of a multi-developer *site*.
Below I talk about a possible way we could use git
without changing it (since I recognize this would be a minority usage pattern).
We use perforce to manage a mixed hardware/software project
(I'm the 55GB check-out guy, remember?). We have at least 3 different
kinds of data with different usage patterns, and using perforce for
everything in one centralized server was not the best solution.
Each user ("client") has their own worktree and the perforce
repository is on a shared central server. You can consider perforce
to have the equivalent of git's index, but it is stored on the server,
in one file ("db.have") covering all clients. Obviously that becomes a
bottleneck -- and recently db.have got larger than the total cache RAM on
the server, which really slowed things down until we moved to a larger
server. But repository architecture aside, the real problem has been
perforce's usability. Frequently one contributor, having gotten ahead
of the team, needs to share this more recent work with only a few
people. This could be done with p4 branching, but this is really clunky.
So instead the work is pushed out (submitted) to everyone, causing
instability; this is partially remedied by doing it in smaller chunks.
Another perforce problem is that tagging consumes a lot of server
space (and may slow things down as well).
Some of this data will stay in perforce, some will move into revision
control built-in to some of our other tools, and I'd like to try to move some
of it into git. The main attraction for the last group is the lightweight
branching that would allow early/tentative work to be easily shared.
I think the subproject work currently being discussed is going to
be very helpful as well -- the perforce equivalent is chaotic.
We could give each user a work tree and an object repository,
and then have a "release" repository. Unfortunately, this would be
slower to use than the current perforce "solution": users would check
in to their local repository, at the speed of gzip, anyone checking
it out would do so at the speed of gzip, and all work would need
to be resubmitted (using perforce jargon here) to the central repo,
again at the speed of gzip. Currently, people either submit or
check out from the central repo, and it's all done at the speed of
a network copy. This speed issue is important because of
the size of a commit we'd like to share (but not yet release):
about 40 files, half of them control files of several KB each, 1/4 of them
design files of several MB each, and the last 1/4 detailed design
files 100X larger. These 40 files will reference (include) 50 others
of several KB each sprinkled through-out the hierarchy, a few of which
might have changed. And yes, almost all of these are generated files,
but the generation time, and the instability of the tool and script environment,
preclude forcing the other users to regenerate them, like you would
with a .o file.
So, there are 2 alternative set-ups. In one, everyone uses a shared
object repository (everyone's .git/objects is a symlink to it). In this
repository, objects/. , objects/?? , objects/pack , and objects/info all
have "sticky" set, and we do the appropriate machinations to make
all files read-only. There would be an additional phantom user "git"
who owns the shared object repository (the only user whose .git/objects
is not a symlink). Users would commit to their own repositories,
which would write data to the shared object repository and
update their refs (e.g. HEAD). To "release", push to the ~git repository.
This push would be like a current push -- fast-forward only, figure out the list
of objects that need to be transmitted -- but instead of transmitting the
objects, change their ownership to ~git and then update ~git's refs.
Since users can share local commits, maybe the ~git ownership
change should happen at commit time. This all seems do-able
without change in git; instead I'd add a few bash wrapper scripts
(and see below for fsck and pack/prune).
Another setup is like the previous, but make the central repo have
its own hidden object repository. You would push to it using the
standard git command.
Finally, users could run git-fsck [with misleading output];
they could run git-prune{,-packed}, but these commands wouldn't
be able to delete anything. If we don't want users to pack,
then ~git/.git/objects/pack would be writable only by ~git.
So basically, normal people wouldn't do the things in this paragraph.
To do meaningful and safe fsck/prune on the shared repository
as ~git, I'd add some scripting. If you require all users'
GIT_DIR's to look like /home/USER/*/.git , then you can get all
their refs and do a meaningful fsck. If not, you could do a fsck
--unreachable as ~git and filter the result by date and/or type.
(This sort of corresponds to abandoned changesets in perforce.)
Once you have an fsck method you like, its filtered output (i.e.,
--unreachable objects you want to keep) can be fed to git-prune.
Care would also be required with git-repack/git-prune-packed,
but it seems mostly addressable with scheduling.
If I proceed down this path, I'd like to implement this procedure
without any change in git's .c or .sh files. It's clear this is a
minority use and should not depend on anything being maintained
for it inside git. I would write a few bash scripts and a README/HOWTO
for possible inclusion in contrib.
BTW,
has anyone ever thought of writing an "Administrator's Manual" for git?
Thanks,
--
Dana L. How danahow@gmail.com +1 650 804 5991 cell
^ permalink raw reply [relevance 1%]
* Re: GIT vs Other: Need argument
@ 2007-04-19 12:57 3% ` Andy Parkins
0 siblings, 0 replies; 200+ results
From: Andy Parkins @ 2007-04-19 12:57 UTC (permalink / raw)
To: git; +Cc: Marcin Kasperski
On Thursday 2007 April 19 12:59, Marcin Kasperski wrote:
> > but git is definitely no harder to learn
> > than anything else. I browsed through the mecurial tutorial
> > yesterday - and as well as being significantly less powerful than git,
> > it's no easier.
>
> Mercurial is easier to learn, because it has better docs and slightly
> simpler command line (all those -a, -p, ... options which one always
> forgets to add). I tried it.
> In fact, I did the experiment about month ago. I wanted to give a try
> to distributed vc tool. I started from GIT, played a bit with it, and
> abandoned it because a) I did not know whether I am expected to use git,
> or cg, b) While reading docs many times I had the feeling that something
> strange and unclear is going behind the hood.
In terms of normal operation, there aren't many switches one actually needs to
remember. The only one I can think of is "-a" for commit - however, that's
just to make it work like mercurial - a seasoned git user won't use many
switches. My daily grind consists of
git add file.c
git commit
git add file.c
git commit
git add -i
git commit
(Interactive mode for git-add is a joy to use - I don't know if Mercurial has
anything similar).
Now, to your point. I think you're right. What I said was that git actually
is easier; however if you looked at some of the documentation you would
incorrectly assume that that was not the case.
> > (I can't believe this one - if you want to branch a mercurial repository
> > you have to have another complete checkout. Erm... the checkout takes
> > up more space than the repository - why do I need another copy? Anyway,
> > git is no harder than Mercurial here)
>
> AFAIK you are wrong, they are able to link some files while cloning, so
Can't be. I'm talking about the working directory not the repository - if the
files are linked back to the originals, then it's not a separately editable
set of files is it?
> you loose space only if you switch machine or filesystem. Also, recent
> mercurial has initial within-repo branches support. But I am not really
> the best person to conduct git-vs-hg discussion.
I'm glad that Mercurial is getting in-repo branches, they're great. I really
wouldn't want to live without them now I have them.
> > "(Note for Windows users: Mercurial is missing a merge program" - that
> > Windows support isn't looking quite so hot now.
>
> Mercurial on windows works well with kdiff3 or tortoisemerge, you must
> only install one of them.
Aren't they manual merge tools? I think "merge" is for merging automatically,
and moaning about conflicts if they turn up - /then/ you go to tortoisemerge.
> As I said, I am not conducting hg-vs-git discussion. I just happened
> to introduce and manage VC system in corporate environment, so I am able
> to point that this is important feature.
I appreciate that - I don't want to start a fight. My point should probably
have been more directly focussed on git (which was what I wanted to do) -
it's my opinion that git is in fact easier than Mercurial; however, it's
public face is not letting people see that.
> > As for permissions, well Shawn has often spoken of his hook scripts that
> > implement very strong permissions (and he has done so again in this
> > thread).
>
> I am not quite sure how can you forbid johny to see the code
> in ./secret, while johny must checkout whole repo...
Me either - the only permissions that could have been relevant are those
needed to push to the central repository. As I said, git can cope there
without trouble.
> Permissions are not only about writing.
That one is true - perhaps one day git will get partial clone support to match
it's shallow clones - then it would be possible to put permissions on the
read of a central repository. Can Mercurial do that?
> > Depends what you want - I installed cygwin
>
> This is really not an option for typical windows user. Believe me.
> Maybe it could be, if cygwin managed to create normal setup program
> one day...
I'm not an expert in Windows by any means - all I did was run setup.exe and
picked git and ssh from the list. It doesn't get much easier.
> Let me retype it: I am not complaining. GIT developers are not forced to
> think about win users, or about corporate needs. But if they are, it is
> reasonable to know the problems.
Absolutely - I certainly haven't taken anything you've written as a complaint.
If anything I find it interesting because I think it confirms what I
thought - git is not short on features or usability, it's just got a PR
problem.
Andy
--
Dr Andy Parkins, M Eng (hons), MIET
andyparkins@gmail.com
^ permalink raw reply [relevance 3%]
* Git benchmarks at OpenOffice.org wiki
@ 2007-05-01 21:46 2% Jakub Narebski
2007-05-01 22:27 3% ` Junio C Hamano
2007-05-02 14:24 0% ` Jan Holesovsky
0 siblings, 2 replies; 200+ results
From: Jakub Narebski @ 2007-05-01 21:46 UTC (permalink / raw)
To: git; +Cc: releases, Jan Holesovsky
OpenOffice.org is looking for a new SCM (Software Configuration
Management) tool, or at least was on Friday, 19 Jan 2007;
see: http://blogs.sun.com/GullFOSS/entry/openoffice_org_scm
One of the SCMs considered is Git. One of others is Subversion.
There is a functional git tree with the entire OOo history for testing
purposes that can be found at: http://go-oo.org/git.
What I am concerned about is some of git benchmark results at Git page
on OpenOffice.org wiki:
http://wiki.services.openoffice.org/wiki/Git#Comparison
Actually it is comparison with CVS and Subversion, although most
benchmarks are done only for git.
In 'Size of data on the server' git has CVS beat hands down: 1.3G vs
8.5G for sources, 591M vs 1.1G for third party. I think it is similar
for Subversion. I hope that repository is fully packed: IIRC the Mozilla
CVS repository import was about 0.6GB pack file, not 1.3GB.
The problem is with 'Size of checkout': to start working in repository
one needs 1.4G (sources) and 98M (third party) for CVS checkout (it is
1.5G for sources for Subversion checkout). Ordinary for distributed SCM
you would need size of repository + size of sources (working area),
which is 2.8G for sources and 688M for third party stuff files you can
hack on + the history]. This makes some prefer to go centralized SCM
route, i.e. Subversion as replacement for CVS (+ CWS, ChildWorkSpace).
What might help here is splitting repository into current (e.g. from
OOo 2.0) and historical part, and / or using shallow clone. Implementing
partial checkouts, i.e. checking out only part of working area (and
using 'theirs' strategy for merging not-checked-out part for merges)
would help. Splitting repository into submodules, and submodule
support -- it depends on organization of OOo sources, would certainly
help for third party stuff repository.
'Checkout time' (which should be renamed to 'Initial checkout time'),
in which git also loses with 130 minutes (Linux, 2MBit DSL) [from
go-oo.org], 100min (Linux, 2MBit DSL, Wireless, no proxy) [from
go-oo.org] versus 117 minutes (Linux, 2MBit DSL), 26 minutes (Linux,
2MBit DSL, with compression (-z 6)) for CVS, and 60 Minutes (Windows,
34Mbit Line) for Subversion, would also be helped by the above.
What I'm really concerned about is branch switch and merging branches,
when one of the branches is an old one (e.g. unxsplash branch), which
takes 3min (!) according to the benchmark. 13-25sec for commit is also
bit long, but BRANCH SWITCHING which takes 3 MINUTES!? There is no
comparison benchmark for CVS or Subversion, though...
Comparison / benchmark lacks some crucial info, like what computer was
used (CPU, RAM, HDD), what filesystem was used, git version etc. It
does have commands used for tests (benchmarks).
Could you confirm (or deny) those results? go-oo.org uses git 1.4.3.4;
was there some improvement or bugfix related to the speed of checkout?
--
Jakub Narebski
ShadeHawk on #git
Poland
^ permalink raw reply [relevance 2%]
* Re: Git benchmarks at OpenOffice.org wiki
2007-05-01 21:46 2% Git benchmarks at OpenOffice.org wiki Jakub Narebski
@ 2007-05-01 22:27 3% ` Junio C Hamano
2007-05-02 14:24 0% ` Jan Holesovsky
1 sibling, 0 replies; 200+ results
From: Junio C Hamano @ 2007-05-01 22:27 UTC (permalink / raw)
To: Jakub Narebski; +Cc: git, releases, Jan Holesovsky
Jakub Narebski <jnareb@gmail.com> writes:
> What might help here is splitting repository into current (e.g. from
> OOo 2.0) and historical part, and / or using shallow clone.
Yes, depending on where you cut off and how reasonable the
project history is.
> Implementing
> partial checkouts, i.e. checking out only part of working area (and
> using 'theirs' strategy for merging not-checked-out part for merges)
> would help.
Partial checkouts, perhaps, "theirs", NO.
Consider that you are working on the tip with partial checkout.
Somebody has a bugfix that is applicable to all of ancient, old,
maintenance and current codebase. Naturally you would want the
bugfix to be applied to ancient, merge it to old, and then
maintenance and then current (the last one is what you are
working on).
What happens if you actually pull ancient when you are partially
checked out and use "theirs"?
> Splitting repository into submodules, and submodule
> support -- it depends on organization of OOo sources, would certainly
> help for third party stuff repository.
This is probably the most sane way.
^ permalink raw reply [relevance 3%]
* Re: Git benchmarks at OpenOffice.org wiki
2007-05-01 21:46 2% Git benchmarks at OpenOffice.org wiki Jakub Narebski
2007-05-01 22:27 3% ` Junio C Hamano
@ 2007-05-02 14:24 0% ` Jan Holesovsky
2007-05-02 23:30 4% ` Jakub Narebski
1 sibling, 1 reply; 200+ results
From: Jan Holesovsky @ 2007-05-02 14:24 UTC (permalink / raw)
To: Jakub Narebski; +Cc: git, releases
Hi Jakub,
On Tuesday 01 May 2007 23:46, Jakub Narebski wrote:
> OpenOffice.org is looking for a new SCM (Software Configuration
> Management) tool, or at least was on Friday, 19 Jan 2007;
> see: http://blogs.sun.com/GullFOSS/entry/openoffice_org_scm
>
> One of the SCMs considered is Git. One of others is Subversion.
> There is a functional git tree with the entire OOo history for testing
> purposes that can be found at: http://go-oo.org/git.
>
> What I am concerned about is some of git benchmark results at Git page
> on OpenOffice.org wiki:
> http://wiki.services.openoffice.org/wiki/Git#Comparison
> Actually it is comparison with CVS and Subversion, although most
> benchmarks are done only for git.
I did the git numbers, so if they are wrong - blame me :-) I am also curious
about the SVN numbers, because the SVN conversion [from my point of view]
cheats a lot. From what I know, it does not contain the historical branches
(yes, the >3000 of them that are in the git tree), and if I understood that
correctly, instead of history in the branches, they commit just
'integration commits' [one commit for all the changes in the branch] which
breaks 'svn blame' completely.
Unfortunately, I did not have a chance to try the SVN tree yet to see it
myself to prove this true or false :-(
> In 'Size of data on the server' git has CVS beat hands down: 1.3G vs
> 8.5G for sources, 591M vs 1.1G for third party. I think it is similar
> for Subversion. I hope that repository is fully packed: IIRC the Mozilla
> CVS repository import was about 0.6GB pack file, not 1.3GB.
>
> The problem is with 'Size of checkout': to start working in repository
> one needs 1.4G (sources) and 98M (third party) for CVS checkout (it is
> 1.5G for sources for Subversion checkout). Ordinary for distributed SCM
> you would need size of repository + size of sources (working area),
> which is 2.8G for sources and 688M for third party stuff files you can
> hack on + the history]. This makes some prefer to go centralized SCM
> route, i.e. Subversion as replacement for CVS (+ CWS, ChildWorkSpace).
Considering the size OOo needs for build (>8G without languages),
the ~1.4G overhead for history is very well bearable. I am surprised about
the 100M overhead for SVN as well - from my experience it is usually about
the size of the project itself; but maybe they improved something in SVN
in the meantime.
> What might help here is splitting repository into current (e.g. from
> OOo 2.0) and historical part,
No, I don't want this ;-)
> and / or using shallow clone. Implementing
> partial checkouts, i.e. checking out only part of working area (and
> using 'theirs' strategy for merging not-checked-out part for merges)
> would help. Splitting repository into submodules, and submodule
> support -- it depends on organization of OOo sources, would certainly
> help for third party stuff repository.
We should better split the OOo sources; it's a process that already started
[UNO runtime environment vs. OOo without URE], and I proposed some more
changes already.
> 'Checkout time' (which should be renamed to 'Initial checkout time'),
> in which git also loses with 130 minutes (Linux, 2MBit DSL) [from
> go-oo.org], 100min (Linux, 2MBit DSL, Wireless, no proxy) [from
> go-oo.org] versus 117 minutes (Linux, 2MBit DSL), 26 minutes (Linux,
> 2MBit DSL, with compression (-z 6)) for CVS, and 60 Minutes (Windows,
> 34Mbit Line) for Subversion, would also be helped by the above.
Good point, and I already changed the page in the morning. I also added the
checkout time that I got over a fast line [it was 44min].
> What I'm really concerned about is branch switch and merging branches,
> when one of the branches is an old one (e.g. unxsplash branch), which
> takes 3min (!) according to the benchmark. 13-25sec for commit is also
> bit long, but BRANCH SWITCHING which takes 3 MINUTES!? There is no
> comparison benchmark for CVS or Subversion, though...
I am really curious about the SVN tree. As I said, I did not see it yet.
There is just some info about it here:
http://wiki.services.openoffice.org/wiki/SVNMigration, but I cannot check it
now, the Wiki is down :-(
> Comparison / benchmark lacks some crucial info, like what computer was
> used (CPU, RAM, HDD), what filesystem was used, git version etc. It
> does have commands used for tests (benchmarks).
For the git tests, it was:
CPU: AMD Athlon(tm) 64 Processor 3200+
RAM: 1G RAM
Disk (info from bonnie):
---Sequential Output (nosync)--- ---Sequential Input-- --Rnd Seek-
-Per Char- --Block--- -Rewrite-- -Per Char- --Block--- --04k (03)-
Machine MB K/sec %CPU K/sec %CPU K/sec %CPU K/sec %CPU K/sec %CPU /sec %CPU
one 1*2000 37819 77.6 44296 16.8 16982 5.1 35203 63.9 45915 6.6 152.4 0.4
Filesystem: ext3
> Could you confirm (or deny) those results? go-oo.org uses git 1.4.3.4;
> was there some improvement or bugfix related to the speed of checkout?
Regards,
Jan
^ permalink raw reply [relevance 0%]
* Re: Git benchmarks at OpenOffice.org wiki
2007-05-02 14:24 0% ` Jan Holesovsky
@ 2007-05-02 23:30 4% ` Jakub Narebski
0 siblings, 0 replies; 200+ results
From: Jakub Narebski @ 2007-05-02 23:30 UTC (permalink / raw)
To: Jan Holesovsky, git; +Cc: dev
Jan Holesovsky wrote:
> On Tuesday 01 May 2007 23:46, Jakub Narebski wrote:
>
>> What I am concerned about is some of git benchmark results at Git page
>> on OpenOffice.org wiki:
>> http://wiki.services.openoffice.org/wiki/Git#Comparison
>> The problem is with 'Size of checkout': to start working in repository
>> one needs 1.4G (sources) and 98M (third party) for CVS checkout (it is
>> 1.5G for sources for Subversion checkout). Ordinary for distributed SCM
>> you would need size of repository + size of sources (working area),
>> which is 2.8G for sources and 688M for third party stuff files you can
>> hack on + the history]. This makes some prefer to go centralized SCM
>> route, i.e. Subversion as replacement for CVS (+ CWS, ChildWorkSpace).
>
> Considering the size OOo needs for build (>8G without languages),
> the ~1.4G overhead for history is very well bearable. I am surprised about
> the 100M overhead for SVN as well - from my experience it is usually about
> the size of the project itself; but maybe they improved something in SVN
> in the meantime.
I think the supposition that SVN uses hardlinks for pristine copy
of sources (HEAD version) seems probable; then there it is 100M overhead
plus size of changed files, and of course this tricks works only on
filesystems which support hardlinks, and assumes either hardlinks being
COW-links (copy-on-write) or editor behaving.
>> What might help here is splitting repository into current (e.g. from
>> OOo 2.0) and historical part,
>
> No, I don't want this ;-)
I forgot to add there is possible to graft historical repository to the
current work repository, resulting in full history available. For example
Linux kernel repository has backported from BK historical repository, and
there is grafts file which connect those two repositories.
>> and / or using shallow clone.
git-clone(1):
--depth <depth>::
Create a 'shallow' clone with a history truncated to the
specified number of revs. A shallow repository has
number of limitations (you cannot clone or fetch from
it, nor push from nor into it), but is adequate if you
want to only look at near the tip of a large project
with a long history, and would want to send in a fixes
as patches.
It is possible that those limitations will be lifted in the future
(if possible), so there is alternate possibility to reduce needed
disk space for git checkout. But certainly this is not for everybody.
>> Implementing
>> partial checkouts, i.e. checking out only part of working area (...)
The problem with implementing this feature (you can do partial checkout
using low level commands, but this feature is not implemented [yet?]
per se) is with doing merge on part which is not checked out. Might
not be a problem for OOo; but this might be also not needed for OOo.
Sometimes submodules are better, sometimes partial checkout is the
only way: see below.
>> Splitting repository into submodules, and submodule
>> support -- it depends on organization of OOo sources, would certainly
>> help for third party stuff repository.
>
> We should better split the OOo sources; it's a process that already started
> [UNO runtime environment vs. OOo without URE], and I proposed some more
> changes already.
In my opinion each submodule should be able to compile and test by
itself. You can go X.Org route with splitting sources into modules...
or you can make use of the new submodules support (currently plumbing
level, i.e. low level commands), aka. gitlinks.
The submodules support makes it possible to split sources into
independent modules (parts), which can be developed independently,
and which you can download (clone, fetch) or not, while making it
possible to bind it all together into one superproject.
See (somewhat not up to date) http://git.or.cz/gitwiki/SubprojectSupport
page on git wiki.
>> What I'm really concerned about is branch switch and merging branches,
>> when one of the branches is an old one (e.g. unxsplash branch), which
>> takes 3min (!) according to the benchmark. 13-25sec for commit is also
>> bit long, but BRANCH SWITCHING which takes 3 MINUTES!? There is no
>> comparison benchmark for CVS or Subversion, though...
By the way, the time to switch branch should be proportional to number
of changed files, which you can get with "git diff --summary unxsplash
HEAD". Or to be more realistic to checkout some old version
(some old tag), as usually branches which got merged in are deleted
(or even never got published). For example when bisecting some bug:
Subversion doesn't have bisect, does it?
I wonder if running "git pack-refs" would help this benchmark...
--
Jakub Narebski
Poland
^ permalink raw reply [relevance 4%]
* svn user trying to recover from brain damage
@ 2007-05-09 15:30 2% Joshua Ball
2007-05-09 16:22 1% ` Petr Baudis
0 siblings, 1 reply; 200+ results
From: Joshua Ball @ 2007-05-09 15:30 UTC (permalink / raw)
To: git
Hi all,
The git page says that this mailing list is for "bug reports, feature
requests, comments and patches". Is there a mailing list for new users
crying out for help? If so, forward me there.
OK, I'm feeling very frustrated right now, so let me just say that git
documentation sucks. All the documentation I can find anywhere falls
into two categories:
1. Tutorials for people brand new to version control, with just enough
information for them to "obey the rules", but completely empty of any
information that could help them exploit the real power of
decentralized version control.
2. Technical documentation which assumes pre-obtained knowledge.
Now that I've insulted you and am probably not on your good side...
What the heck do these terms mean? The glossary on the Git wiki was
unhelpful (I'll explain later). BTW, what is wrong with the wiki?
(Particularly the excessive [grayed-out text [no match, add rest:
"used by any common UNIX command. The fact that it is a
mispronunciation of "]]. Is this some new kind of spam, or a buggy
wiki feature?)
HEAD
HEAD REF
working tree
object
branch
merge
master
commit (as in the phrase "bring the working tree to a given commit")
While the Git wiki does in fact define all of these, it doesn't answer
any of my questions about those terms:
Is there a difference between HEAD and the working tree?
Does HEAD change when I cg-switch/git-checkout?
What is an object? Is it a set of patches? A tree snapshot?
What the heck is a branch? (Why does it have so many different
definitions? I feel like every time I come across "branch" in the man
pages, it means something different.)
More on branches: The wiki says that a group of commits linked
together form a DAG. Does that mean every fork/clone/branch-create
possibly doubles the number of branches. So if I fork and then
remerge, do I have two branches?
A -> B -> D
A -> C -> D
Would D be the head of this branch? If so, then heads do not uniquely
identify a branch?
Is there a standard revision notation? (Where my definition of
"revision" is a tree snapshot. In SVN, it would be identified by a
number.) `cg-diff -r A..B` works fine if A and B are branches, but how
do I diff from an older revision to a newer revision? Can I diff
between two revisions which haven't shared the same parent since 2006?
What about the master branch? Is there anything special about it? By
special I mean, do any of the git or cogito commands implicitly assume
that you are working with master? If git is truly decentralized, then
wouldn't master be on an equal footing with all other branches?
What is a merge? My understanding of merge comes from the SVN book,
where it was described as diff+apply. Diff takes 2 arguments, and
apply takes a 1 argument (if the patch is implicit). However, cg-merge
only appears to take one branch. (There again a use of the word
branch! Wouldn't commit or revision be a more accurate term?) Why does
cg-merge only take one argument? Even if I use the -b switch, I'm
still only up to two arguments. Where is the hidden argument?
Lastly, the most important question of all, which may answer many of
the questions above:
Can you fill in the missing pieces, making corrections where
necessary? (recommend unispace font)
Command | Reads | Writes
cg-fetch | remote branch | corresponding branch in local respository
cg-commit | working copy | HEAD
cg-update | remote branch | working copy AND HEAD
cg-merge | branch & working copy | working copy
cg-diff | arguments | STDOUT
cg-push | | remote branch (usually origin)
cg-pull | remote branch |
cg-restore | |
Perhaps the Reads column should be split into two, like ReadInfo and ReadSafety.
ReadInfo would say which revision/branch/commit/object is being read for actual
content, while ReadSafety is only read to make sure that nothing will be lost
after running the command. (e.g., cg-update reads the working copy to make sure
that you are not in a partial merge, but once it knows that it is safe, it
ignores the contents of working directory. I may have this totally wrong.)
On cg-fetch, is the remote branch necessarily remote? Or can you fetch
from local
cg-switch-branches? What does "corresponding branch in local
repository" mean? Does cg-fetch touch your working copy?
What is the difference between cg-restore and cg-seek?
Please reply even if you can only answer one of my many questions! If
I can grab just one fact and say about it, "This is truth", then it
gives me a rock to stand on amidst all the term-mashing out there.
In the words of Dijkstra, "Since breaking out of bad habits, rather
than acquiring new ones, is the toughest part of learning, we must
expect from that system permanent mental damage for most ... exposed
to it."
May you lead me to a quick recovery. Hail to decentralized version control.
Josh "Ua" Ball
^ permalink raw reply [relevance 2%]
* Re: svn user trying to recover from brain damage
2007-05-09 15:30 2% svn user trying to recover from brain damage Joshua Ball
@ 2007-05-09 16:22 1% ` Petr Baudis
0 siblings, 0 replies; 200+ results
From: Petr Baudis @ 2007-05-09 16:22 UTC (permalink / raw)
To: Joshua Ball; +Cc: git
Hi,
On Wed, May 09, 2007 at 05:30:18PM CEST, Joshua Ball wrote:
> The git page says that this mailing list is for "bug reports, feature
> requests, comments and patches". Is there a mailing list for new users
> crying out for help? If so, forward me there.
I think it fits in the "comments" category. :-)
> OK, I'm feeling very frustrated right now, so let me just say that git
> documentation sucks. All the documentation I can find anywhere falls
> into two categories:
>
> 1. Tutorials for people brand new to version control, with just enough
> information for them to "obey the rules", but completely empty of any
> information that could help them exploit the real power of
> decentralized version control.
> 2. Technical documentation which assumes pre-obtained knowledge.
>
> Now that I've insulted you and am probably not on your good side...
>
> What the heck do these terms mean? The glossary on the Git wiki was
> unhelpful (I'll explain later). BTW, what is wrong with the wiki?
> (Particularly the excessive [grayed-out text [no match, add rest:
> "used by any common UNIX command. The fact that it is a
> mispronunciation of "]]. Is this some new kind of spam, or a buggy
> wiki feature?)
Sorry, it was a bug-ridden wiki. I was desperately trying to debug
some weird behaviour, few moments ago I've finally nailed it down and
all should be fine now.
> HEAD
> HEAD REF
> working tree
> object
> branch
> merge
> master
> commit (as in the phrase "bring the working tree to a given commit")
>
> While the Git wiki does in fact define all of these, it doesn't answer
> any of my questions about those terms:
>
> Is there a difference between HEAD and the working tree?
This is (unfortunately) case-sensitive:
HEAD identifies the commit (our slightly confusing name for a
revision) that corresponds to your working tree - usually the latest
commit in your current branch (by default 'master').
head is just the latest commit in a branch, any branch.
> Does HEAD change when I cg-switch/git-checkout?
Yes, HEAD changes (starts pointing to your new branch) when you
cg-switch or git-checkout -b.
> What is an object? Is it a set of patches? A tree snapshot?
Object is the basic unit of stored data Git works with. object may be
either:
"blob" - file at a particular point of time
"tree" - list of files, corresponding to a particular directory
(again at a particular point of time)
"commit" - one revision in the project history; contains
information about the parent commit(s), who did
the commit, the commit message and link to the
corresponding root tree object
"tag" - links to another object, with additional information
like who/when made the tag and the tag comment
Git does not store patches on a conceptual level, only snapshots. (At
the implementation level, Git uses "patches" for more optimized storage,
but that's not so important.)
> What the heck is a branch? (Why does it have so many different
> definitions? I feel like every time I come across "branch" in the man
> pages, it means something different.)
Because it's hard to define. :-)
To make a cyclical definition, branch is the set of commits
referenced by a given head. Hmm, I'll have to think out some cute
non-confusing definition of branch, I'll follow up unless someone beats
me to it.
> More on branches: The wiki says that a group of commits linked
> together form a DAG. Does that mean every fork/clone/branch-create
> possibly doubles the number of branches. So if I fork and then
> remerge, do I have two branches?
>
> A -> B -> D
> A -> C -> D
>
> Would D be the head of this branch? If so, then heads do not uniquely
> identify a branch?
Branch is a much looser concept than you seem to assume. Branch is
really just a fancy name for a 'head', so let's redefine 'head'. Let's
just say for now that 'head' is a named commit reference.
This means that when you create a "new branch" 'foo' from branch
'master', the _only_ thing you really did was to copy the commit
reference 'master.
> Is there a standard revision notation? (Where my definition of
> "revision" is a tree snapshot. In SVN, it would be identified by a
> number.) `cg-diff -r A..B` works fine if A and B are branches, but how
> do I diff from an older revision to a newer revision? Can I diff
> between two revisions which haven't shared the same parent since 2006?
You can diff between any two revisions. The ultimately "standard"
notation is to use the id of the revision (the long string of
hexadecimal digits), but the syntax is quite rich - see SPECIFYING
REVISIONS section of git-rev-parse(1).
If you specify a branch where revision is expected, it means that the
latest commit (revision) on the branch is used.
> What about the master branch? Is there anything special about it? By
> special I mean, do any of the git or cogito commands implicitly assume
> that you are working with master? If git is truly decentralized, then
> wouldn't master be on an equal footing with all other branches?
'master' is just the default name for the first branch in a
repository, but in theory you can name it any way you wish and use as
many branches as you want, all are equal.
When fetching from a remote repository, some commands might assume in
certain conditions that 'master' is the primary branch of the remote
repository, but I'm not sure about the details and in which cases does
this still hold true.
> What is a merge? My understanding of merge comes from the SVN book,
> where it was described as diff+apply. Diff takes 2 arguments, and
> apply takes a 1 argument (if the patch is implicit). However, cg-merge
> only appears to take one branch. (There again a use of the word
> branch! Wouldn't commit or revision be a more accurate term?) Why does
> cg-merge only take one argument? Even if I use the -b switch, I'm
> still only up to two arguments. Where is the hidden argument?
The hidden argument is your current branch. So cg-merge x will merge
the branch 'x' to your current branch: symbolically, kind of
base=-b argument | base(HEAD, x)
apply(HEAD, diff(base, x))
The word 'branch' is used in an attempt to make it all less confusing
:-). But in fact, you can give cg-merge just id of a commit, it does not
have to be branch name.
> Lastly, the most important question of all, which may answer many of
> the questions above:
>
> Can you fill in the missing pieces, making corrections where
> necessary? (recommend unispace font)
>
> Command | Reads | Writes
> cg-fetch | remote branch | corresponding branch in local respository
> cg-commit | working copy | HEAD
> cg-update | remote branch | working copy AND HEAD
> cg-merge | branch & working copy | working copy
> cg-diff | arguments | STDOUT
> cg-push | | remote branch (usually origin)
> cg-pull | remote branch |
> cg-restore | |
Yes, mostly right. cg-merge calls cg-commit unless there are
conflicts, so it should be "working copy AND HEAD" too. cg-push reads
local branch (HEAD or -r argument). There is no cg-pull since people
coming from different VCSes have different ideas about what pull is; git
pull is equivalent to cg-update.
> Perhaps the Reads column should be split into two, like ReadInfo and
> ReadSafety.
> ReadInfo would say which revision/branch/commit/object is being read for
> actual
> content, while ReadSafety is only read to make sure that nothing will be
> lost
> after running the command. (e.g., cg-update reads the working copy to make
> sure
> that you are not in a partial merge, but once it knows that it is safe, it
> ignores the contents of working directory. I may have this totally wrong.)
It actually does some magic so that you can do a merge while having
uncommitted changes in your working tree. ;-)
> On cg-fetch, is the remote branch necessarily remote? Or can you fetch
> from local
> cg-switch-branches? What does "corresponding branch in local
> repository" mean? Does cg-fetch touch your working copy?
Fetch means that a remote branch's content is transferred to the local
repository; furthermore, all the remote branches have their local
counterparts that "reflect" how the branch looked in the remote
repository at a particular point of time. So e.g. when you clone a
repository, the remote default branch is mirrored locally as branch
'origin' - you can't switch to it (technically you could but that would
be very confusing), but you can merge it.
> What is the difference between cg-restore and cg-seek?
cg-seek will temporarily bring your tree to a different commit to
explore the state back then, but you cannot make commits in this state;
your HEAD points to the seeked commit. On the other hand, cg-restore
only changes files in your working tree - it works on the individual
files, does not touch HEAD and does not make the tree "read-only".
--
Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
Ever try. Ever fail. No matter. // Try again. Fail again. Fail better.
-- Samuel Beckett
^ permalink raw reply [relevance 1%]
* Partial removal of fetching from git-clone
@ 2007-05-20 17:57 6% skimo
0 siblings, 0 replies; 200+ results
From: skimo @ 2007-05-20 17:57 UTC (permalink / raw)
To: git, Junio C Hamano
From: Sven Verdoolaege <skimo@kotnet.org>
This was needed for doing submodules in git-fetch,
but since I moved the cloning of submodules to git-checkout,
I no longer need these changes.
Still, I know Junio wants something like this, so they
could be used as a starting point for completely
removing all fetching from git-clone.
skimo
^ permalink raw reply [relevance 6%]
* [PATCH] Implement git commit as a builtin.
@ 2007-07-18 19:19 1% Kristian Høgsberg
0 siblings, 0 replies; 200+ results
From: Kristian Høgsberg @ 2007-07-18 19:19 UTC (permalink / raw)
To: git; +Cc: Kristian Høgsberg
---
Here's another update on the work in progress. At this point, the C
version is almost complete, there's only a few issues left (look for
FIXME in builtin-commit.c). I've added a commit test case which should
be split out in a patch on its own, but the good news is that it
successfully exercises most of the command line options and the C version
passes.
My plan for the remainder of the work is still to wrap up the last few
pieces of functionality and then start taking this big patch apart in a
number of more manageable pieces. However, the bulk of this work will
still be a big patch that removes git-commit.sh and adds builtin-commit
in one swoop.
Kristian
Makefile | 9 +-
builtin-add.c | 14 +-
builtin-commit-tree.c | 120 +++++---
builtin-commit.c | 746 +++++++++++++++++++++++++++++++++++++++++++++++++
builtin.h | 3 +-
cache.h | 3 +-
color.c | 18 +-
color.h | 4 +-
commit.h | 9 +
git-commit.sh | 658 -------------------------------------------
git.c | 3 +-
mktag.c | 8 +-
sha1_file.c | 44 ++-
t/t7800-commit.sh | 126 +++++++++
wt-status.c | 86 +++---
wt-status.h | 4 +
16 files changed, 1066 insertions(+), 789 deletions(-)
create mode 100644 builtin-commit.c
delete mode 100755 git-commit.sh
create mode 100644 t/t7800-commit.sh
diff --git a/Makefile b/Makefile
index 0f75955..967d5a5 100644
--- a/Makefile
+++ b/Makefile
@@ -198,7 +198,7 @@ BASIC_LDFLAGS =
SCRIPT_SH = \
git-bisect.sh git-checkout.sh \
- git-clean.sh git-clone.sh git-commit.sh \
+ git-clean.sh git-clone.sh \
git-fetch.sh \
git-ls-remote.sh \
git-merge-one-file.sh git-mergetool.sh git-parse-remote.sh \
@@ -257,7 +257,7 @@ EXTRA_PROGRAMS =
BUILT_INS = \
git-format-patch$X git-show$X git-whatchanged$X git-cherry$X \
git-get-tar-commit-id$X git-init$X git-repo-config$X \
- git-fsck-objects$X git-cherry-pick$X \
+ git-fsck-objects$X git-cherry-pick$X git-status$X\
$(patsubst builtin-%.o,git-%$X,$(BUILTIN_OBJS))
# what 'all' will build and 'install' will install, in gitexecdir
@@ -332,6 +332,7 @@ BUILTIN_OBJS = \
builtin-check-attr.o \
builtin-checkout-index.o \
builtin-check-ref-format.o \
+ builtin-commit.o \
builtin-commit-tree.o \
builtin-count-objects.o \
builtin-describe.o \
@@ -367,7 +368,6 @@ BUILTIN_OBJS = \
builtin-rev-parse.o \
builtin-revert.o \
builtin-rm.o \
- builtin-runstatus.o \
builtin-shortlog.o \
builtin-show-branch.o \
builtin-stripspace.o \
@@ -791,9 +791,6 @@ $(patsubst %.perl,%,$(SCRIPT_PERL)): % : %.perl
chmod +x $@+ && \
mv $@+ $@
-git-status: git-commit
- $(QUIET_GEN)cp $< $@+ && mv $@+ $@
-
gitweb/gitweb.cgi: gitweb/gitweb.perl
$(QUIET_GEN)rm -f $@ $@+ && \
sed -e '1s|#!.*perl|#!$(PERL_PATH_SQ)|' \
diff --git a/builtin-add.c b/builtin-add.c
index 1591171..bcd796d 100644
--- a/builtin-add.c
+++ b/builtin-add.c
@@ -8,6 +8,7 @@
#include "dir.h"
#include "exec_cmd.h"
#include "cache-tree.h"
+#include "run-command.h"
#include "diff.h"
#include "diffcore.h"
#include "commit.h"
@@ -148,6 +149,13 @@ static int git_add_config(const char *var, const char *value)
return git_default_config(var, value);
}
+int interactive_add(void)
+{
+ const char *argv[2] = { "add--interactive", NULL };
+
+ return run_command_v_opt(argv, RUN_GIT_CMD);
+}
+
static struct lock_file lock_file;
static const char ignore_warning[] =
@@ -167,11 +175,9 @@ int cmd_add(int argc, const char **argv, const char *prefix)
add_interactive++;
}
if (add_interactive) {
- const char *args[] = { "add--interactive", NULL };
-
- if (add_interactive != 1 || argc != 2)
+ if (argc != 2)
die("add --interactive does not take any parameters");
- execv_git_cmd(args);
+ interactive_add();
exit(1);
}
diff --git a/builtin-commit-tree.c b/builtin-commit-tree.c
index ccbcbe3..bb20470 100644
--- a/builtin-commit-tree.c
+++ b/builtin-commit-tree.c
@@ -20,17 +20,11 @@ static void init_buffer(char **bufp, unsigned int *sizep)
*sizep = 0;
}
-static void add_buffer(char **bufp, unsigned int *sizep, const char *fmt, ...)
+static void add_chunk(char **bufp, unsigned int *sizep, const char *data, int len)
{
- char one_line[2048];
- va_list args;
- int len;
unsigned long alloc, size, newsize;
char *buf;
- va_start(args, fmt);
- len = vsnprintf(one_line, sizeof(one_line), fmt, args);
- va_end(args);
size = *sizep;
newsize = size + len + 1;
alloc = (size + 32767) & ~32767;
@@ -41,7 +35,19 @@ static void add_buffer(char **bufp, unsigned int *sizep, const char *fmt, ...)
*bufp = buf;
}
*sizep = newsize - 1;
- memcpy(buf + size, one_line, len);
+ memcpy(buf + size, data, len);
+}
+
+static void add_buffer(char **bufp, unsigned int *sizep, const char *fmt, ...)
+{
+ char one_line[2048];
+ va_list args;
+ int len;
+
+ va_start(args, fmt);
+ len = vsnprintf(one_line, sizeof(one_line), fmt, args);
+ va_end(args);
+ add_chunk(bufp, sizep, one_line, len);
}
static void check_valid(unsigned char *sha1, enum object_type expect)
@@ -81,39 +87,16 @@ static const char commit_utf8_warn[] =
"You may want to amend it after fixing the message, or set the config\n"
"variable i18n.commitencoding to the encoding your project uses.\n";
-int cmd_commit_tree(int argc, const char **argv, const char *prefix)
+const unsigned char *
+create_commit(const unsigned char *tree_sha1,
+ unsigned char parent_sha1[][20], int parents,
+ const char *author_info, const char *committer_info,
+ const char *message, int length)
{
- int i;
- int parents = 0;
- unsigned char tree_sha1[20];
- unsigned char commit_sha1[20];
- char comment[1000];
+ static unsigned char commit_sha1[20];
+ int encoding_is_utf8, i;
char *buffer;
unsigned int size;
- int encoding_is_utf8;
-
- git_config(git_default_config);
-
- if (argc < 2)
- usage(commit_tree_usage);
- if (get_sha1(argv[1], tree_sha1))
- die("Not a valid object name %s", argv[1]);
-
- check_valid(tree_sha1, OBJ_TREE);
- for (i = 2; i < argc; i += 2) {
- const char *a, *b;
- a = argv[i]; b = argv[i+1];
- if (!b || strcmp(a, "-p"))
- usage(commit_tree_usage);
-
- if (parents >= MAXPARENT)
- die("Too many parents (%d max)", MAXPARENT);
- if (get_sha1(b, parent_sha1[parents]))
- die("Not a valid object name %s", b);
- check_valid(parent_sha1[parents], OBJ_COMMIT);
- if (new_parent(parents))
- parents++;
- }
/* Not having i18n.commitencoding is the same as having utf-8 */
encoding_is_utf8 = is_encoding_utf8(git_commit_encoding);
@@ -130,26 +113,71 @@ int cmd_commit_tree(int argc, const char **argv, const char *prefix)
add_buffer(&buffer, &size, "parent %s\n", sha1_to_hex(parent_sha1[i]));
/* Person/date information */
- add_buffer(&buffer, &size, "author %s\n", git_author_info(1));
- add_buffer(&buffer, &size, "committer %s\n", git_committer_info(1));
+ add_buffer(&buffer, &size, "author %s\n", author_info);
+ add_buffer(&buffer, &size, "committer %s\n", committer_info);
if (!encoding_is_utf8)
add_buffer(&buffer, &size,
"encoding %s\n", git_commit_encoding);
add_buffer(&buffer, &size, "\n");
/* And add the comment */
- while (fgets(comment, sizeof(comment), stdin) != NULL)
- add_buffer(&buffer, &size, "%s", comment);
+ add_chunk(&buffer, &size, message, length);
/* And check the encoding */
buffer[size] = '\0';
if (encoding_is_utf8 && !is_utf8(buffer))
fprintf(stderr, commit_utf8_warn);
- if (!write_sha1_file(buffer, size, commit_type, commit_sha1)) {
- printf("%s\n", sha1_to_hex(commit_sha1));
- return 0;
+ if (!write_sha1_file(buffer, size, commit_type, commit_sha1))
+ return commit_sha1;
+
+ return NULL;
+}
+
+int cmd_commit_tree(int argc, const char **argv, const char *prefix)
+{
+ int i;
+ int parents = 0;
+ unsigned char tree_sha1[20];
+ char *buffer;
+ const unsigned char *commit_sha1;
+ unsigned long length;
+
+ git_config(git_default_config);
+
+ if (argc < 2)
+ usage(commit_tree_usage);
+ if (get_sha1(argv[1], tree_sha1))
+ die("Not a valid object name %s", argv[1]);
+
+ check_valid(tree_sha1, OBJ_TREE);
+ for (i = 2; i < argc; i += 2) {
+ const char *a, *b;
+ a = argv[i]; b = argv[i+1];
+ if (!b || strcmp(a, "-p"))
+ usage(commit_tree_usage);
+
+ if (parents >= MAXPARENT)
+ die("Too many parents (%d max)", MAXPARENT);
+ if (get_sha1(b, parent_sha1[parents]))
+ die("Not a valid object name %s", b);
+ check_valid(parent_sha1[parents], OBJ_COMMIT);
+ if (new_parent(parents))
+ parents++;
}
- else
+
+ if (read_fd(0, &buffer, &length))
+ die("Could not read commit message from standard input");
+
+ commit_sha1 = create_commit(tree_sha1,
+ parent_sha1, parents,
+ git_author_info(1),
+ git_committer_info(1),
+ buffer, length);
+
+ if (!commit_sha1)
return 1;
+
+ printf("%s\n", sha1_to_hex(commit_sha1));
+ return 0;
}
diff --git a/builtin-commit.c b/builtin-commit.c
new file mode 100644
index 0000000..198d5af
--- /dev/null
+++ b/builtin-commit.c
@@ -0,0 +1,746 @@
+/*
+ * Builtin "git commit"
+ *
+ * Copyright (c) 2007 Kristian Høgsberg <krh@redhat.com>
+ * Based on git-commit.sh by Junio C Hamano and Linus Torvalds
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "cache.h"
+#include "cache-tree.h"
+#include "builtin.h"
+#include "diff.h"
+#include "diffcore.h"
+#include "commit.h"
+#include "revision.h"
+#include "wt-status.h"
+#include "run-command.h"
+#include "refs.h"
+#include "log-tree.h"
+
+static const char builtin_commit_usage[] =
+ "[-a | --interactive] [-s] [-v] [--no-verify] [-m <message> | -F <logfile> | (-C|-c) <commit> | --amend] [-u] [-e] [--author <author>] [[-i | -o] <path>...]";
+
+static unsigned char head_sha1[20], merge_head_sha1[20];
+static struct commit *use_message_commit;
+static const char commit_editmsg[] = "COMMIT_EDITMSG";
+static struct lock_file lock_file;
+
+enum option_type {
+ OPTION_NONE,
+ OPTION_STRING,
+ OPTION_INTEGER,
+ OPTION_LAST,
+};
+
+struct option {
+ enum option_type type;
+ const char *long_name;
+ char short_name;
+ void *value;
+};
+
+static int scan_options(const char ***argv, struct option *options)
+{
+ const char *value, *eq;
+ int i;
+
+ if (**argv == NULL)
+ return 0;
+ if ((**argv)[0] != '-')
+ return 0;
+ if (!strcmp(**argv, "--"))
+ return 0;
+
+ value = NULL;
+ for (i = 0; options[i].type != OPTION_LAST; i++) {
+ if ((**argv)[1] == '-') {
+ if (!prefixcmp(options[i].long_name, **argv + 2)) {
+ if (options[i].type != OPTION_NONE)
+ value = *++(*argv);
+ goto match;
+ }
+
+ eq = strchr(**argv + 2, '=');
+ if (eq && options[i].type != OPTION_NONE &&
+ !strncmp(**argv + 2,
+ options[i].long_name, eq - **argv - 2)) {
+ value = eq + 1;
+ goto match;
+ }
+ }
+
+ if ((**argv)[1] == options[i].short_name) {
+ if ((**argv)[2] == '\0') {
+ if (options[i].type != OPTION_NONE)
+ value = *++(*argv);
+ goto match;
+ }
+
+ if (options[i].type != OPTION_NONE) {
+ value = **argv + 2;
+ goto match;
+ }
+ }
+ }
+
+ usage(builtin_commit_usage);
+
+ match:
+ switch (options[i].type) {
+ case OPTION_NONE:
+ *(int *)options[i].value = 1;
+ break;
+ case OPTION_STRING:
+ if (value == NULL)
+ die("option %s requires a value.", (*argv)[-1]);
+ *(const char **)options[i].value = value;
+ break;
+ case OPTION_INTEGER:
+ if (value == NULL)
+ die("option %s requires a value.", (*argv)[-1]);
+ *(int *)options[i].value = atoi(value);
+ break;
+ default:
+ assert(0);
+ }
+
+ (*argv)++;
+
+ return 1;
+}
+
+static char *logfile, *force_author, *message;
+static char *edit_message, *use_message;
+static int all, edit_flag, also, interactive, only, no_verify, amend, signoff;
+static int quiet, verbose, untracked_files;
+
+static int no_edit, initial_commit, in_merge;
+const char *only_include_assumed;
+
+static struct option commit_options[] = {
+ { OPTION_STRING, "file", 'F', (void *) &logfile },
+ { OPTION_NONE, "all", 'a', &all },
+ { OPTION_STRING, "author", 0, (void *) &force_author },
+ { OPTION_NONE, "edit", 0, &edit_flag },
+ { OPTION_NONE, "include", 'i', &also },
+ { OPTION_NONE, "interactive", 0, &interactive },
+ { OPTION_NONE, "only", 'o', &only },
+ { OPTION_STRING, "message", 'm', &message },
+ { OPTION_NONE, "no-verify", 'n', &no_verify },
+ { OPTION_NONE, "amend", 0, &amend },
+ { OPTION_STRING, "reedit-message", 'c', &edit_message },
+ { OPTION_STRING, "reuse-message", 'C', &use_message },
+ { OPTION_NONE, "signoff", 's', &signoff },
+ { OPTION_NONE, "quiet", 'q', &quiet },
+ { OPTION_NONE, "verbose", 'v', &verbose },
+ { OPTION_NONE, "untracked-files", 0, &untracked_files },
+ { OPTION_LAST },
+};
+
+/* FIXME: Taken from builtin-add, should be shared. */
+
+static void update_callback(struct diff_queue_struct *q,
+ struct diff_options *opt, void *cbdata)
+{
+ int i, verbose;
+
+ verbose = *((int *)cbdata);
+ for (i = 0; i < q->nr; i++) {
+ struct diff_filepair *p = q->queue[i];
+ const char *path = p->one->path;
+ switch (p->status) {
+ default:
+ die("unexpacted diff status %c", p->status);
+ case DIFF_STATUS_UNMERGED:
+ case DIFF_STATUS_MODIFIED:
+ add_file_to_cache(path, verbose);
+ break;
+ case DIFF_STATUS_DELETED:
+ remove_file_from_cache(path);
+ if (verbose)
+ printf("remove '%s'\n", path);
+ break;
+ }
+ }
+}
+
+static void
+add_files_to_cache(int fd, const char **files, const char *prefix)
+{
+ struct rev_info rev;
+
+ init_revisions(&rev, "");
+ setup_revisions(0, NULL, &rev, NULL);
+ rev.prune_data = get_pathspec(prefix, files);
+ rev.diffopt.output_format |= DIFF_FORMAT_CALLBACK;
+ rev.diffopt.format_callback = update_callback;
+ rev.diffopt.format_callback_data = &verbose;
+
+ run_diff_files(&rev, 0);
+
+ if (write_cache(fd, active_cache, active_nr) || close(fd))
+ die("unable to write new index file");
+}
+
+static char *
+prepare_index(const char **files, const char *prefix)
+{
+ int fd;
+ struct tree *tree;
+ struct lock_file *next_index_lock;
+
+ fd = hold_locked_index(&lock_file, 1);
+ if (read_cache() < 0)
+ die("index file corrupt");
+
+ if (all) {
+ add_files_to_cache(fd, files, NULL);
+ return lock_file.filename;
+ } else if (also) {
+ add_files_to_cache(fd, files, prefix);
+ return lock_file.filename;
+ }
+
+ if (interactive)
+ interactive_add();
+
+ if (*files == NULL) {
+ /* Commit index as-is. */
+ rollback_lock_file(&lock_file);
+ return get_index_file();
+ }
+
+ /*
+ * FIXME: Warn on unknown files. Shell script does
+ *
+ * commit_only=`git-ls-files --error-unmatch -- "$@"`
+ */
+
+ /*
+ * FIXME: shell script does
+ *
+ * git-read-tree --index-output="$TMP_INDEX" -i -m HEAD
+ *
+ * which warns about unmerged files in the index.
+ */
+
+ /* update the user index file */
+ add_files_to_cache(fd, files, prefix);
+
+ 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");
+
+ /* Uh oh, abusing lock_file to create a garbage collected file */
+ next_index_lock = xmalloc(sizeof(*next_index_lock));
+ fd = hold_lock_file_for_update(next_index_lock,
+ git_path("next-index-%d", getpid()), 1);
+ add_files_to_cache(fd, files, prefix);
+
+ return next_index_lock->filename;
+}
+
+static int strip_lines(char *buffer, int len)
+{
+ int blank_lines, i, j;
+ char *eol;
+
+ blank_lines = 1;
+ for (i = 0, j = 0; i < len; i++) {
+ if (blank_lines > 0 && buffer[i] == '#') {
+ eol = strchr(buffer + i, '\n');
+ if (!eol)
+ break;
+
+ i = eol - buffer;
+ continue;
+ }
+
+ if (buffer[i] == '\n') {
+ blank_lines++;
+ if (blank_lines > 1)
+ continue;
+ } else {
+ if (blank_lines > 2)
+ buffer[j++] = '\n';
+ blank_lines = 0;
+ }
+
+ buffer[j++] = buffer[i];
+ }
+
+ if (buffer[j - 1] != '\n')
+ buffer[j++] = '\n';
+
+ return j;
+}
+
+static int run_status(FILE *fp, const char *index_file)
+{
+ struct wt_status s;
+
+ wt_status_prepare(&s);
+
+ if (amend) {
+ s.amend = 1;
+ s.reference = "HEAD^1";
+ }
+ s.verbose = verbose;
+ s.untracked = untracked_files;
+ s.index_file = index_file;
+ s.fp = fp;
+
+ wt_status_print(&s);
+
+ return s.commitable;
+}
+
+static const char sign_off_header[] = "Signed-off-by: ";
+
+static int prepare_log_message(const char *index_file)
+{
+ char *buffer = NULL;
+ struct stat statbuf;
+ int commitable;
+ unsigned long len;
+ FILE *fp;
+
+ if (message) {
+ buffer = message;
+ len = strlen(message);
+ } else if (logfile && !strcmp(logfile, "-")) {
+ if (isatty(0))
+ fprintf(stderr, "(reading log message from standard input)\n");
+ if (read_fd(0, &buffer, &len))
+ die("could not read log from standard input");
+ } else if (logfile) {
+ if (read_path(logfile, &buffer, &len))
+ die("could not read log file '%s': %s",
+ logfile, strerror(errno));
+ } else if (use_message) {
+ /* FIXME: encoding */
+ buffer = strstr(use_message_commit->buffer, "\n\n");
+ if (!buffer || buffer[2] == '\0')
+ die("commit has empty message");
+ buffer += 2;
+ len = strlen(buffer);
+ } else if (!stat(git_path("MERGE_MSG"), &statbuf)) {
+ if (read_path(git_path("MERGE_MSG"), &buffer, &len))
+ die("could not read MERGE_MSG: %s", strerror(errno));
+ } else if (!stat(git_path("SQUASH_MSG"), &statbuf)) {
+ if (read_path(git_path("SQUASH_MSG"), &buffer, &len))
+ die("could not read SQUASH_MSG: %s", strerror(errno));
+ }
+
+ fp = fopen(git_path(commit_editmsg), "w");
+ if (fp == NULL)
+ die("could not open %s\n", git_path(commit_editmsg));
+
+ if (buffer) {
+ len = strip_lines(buffer, len);
+
+ if (fwrite(buffer, 1, len, fp) < len)
+ die("could not write commit template: %s\n",
+ strerror(errno));
+ }
+
+ if (signoff) {
+ const char *info, *bol;
+
+ info = git_committer_info(1);
+ if (buffer) {
+ bol = strrchr(buffer + len - 1, '\n');
+ if (!bol || prefixcmp(bol, sign_off_header))
+ fprintf(fp, "\n");
+ }
+ fprintf(fp, "Signed-off-by: %s\n", git_committer_info(1));
+ }
+
+ if (in_merge && !no_edit) {
+ fprintf(fp,
+ "#\n"
+ "# It looks like you may be committing a MERGE.\n"
+ "# If this is not correct, please remove the file\n"
+ "# %s\n"
+ "# and try again.\n"
+ "#\n",
+ git_path("MERGE_HEAD"));
+ }
+
+ fprintf(fp,
+ "\n"
+ "# Please enter the commit message for your changes.\n"
+ "# (Comment lines starting with '#' will not be included)\n");
+ if (only_include_assumed)
+ fprintf(fp, "# %s\n", only_include_assumed);
+
+ commitable = run_status(fp, index_file);
+
+ fclose(fp);
+
+ return commitable;
+}
+
+struct commit_info_strings {
+ const char *header, *name_env, *email_env, *date_env;
+} author_info_strings = {
+ "\nauthor ",
+ "GIT_AUTHOR_NAME", "GIT_AUTHOR_EMAIL", "GIT_AUTHOR_DATE"
+}, committer_info_strings = {
+ "\ncommitter ",
+ "GIT_COMMITTER_NAME", "GIT_COMMITER_EMAIL", "GIT_COMMITTER_DATE"
+};
+
+static char *determine_info(struct commit_info_strings *strings)
+{
+ char *p, *eol;
+ char *name = NULL, *email = NULL, *date = NULL;
+
+ if (use_message) {
+ p = strstr(use_message_commit->buffer, strings->header);
+ if (!p)
+ die("invalid commit: %s\n", use_message);
+ p += strlen(strings->header);
+ eol = strchr(p, '\n');
+ if (!eol)
+ die("invalid commit: %s\n", use_message);
+
+ return xstrndup(p, eol - p);
+ } else if (force_author && strings == &author_info_strings) {
+ const char *eoname = strstr(force_author, " <");
+ const char *eomail = strchr(force_author, '>');
+
+ if (!eoname || !eomail)
+ die("malformed --author parameter\n");
+ name = xstrndup(force_author, eoname - force_author);
+ email = xstrndup(eoname + 2, eomail - eoname - 2);
+ }
+
+ if (name == NULL)
+ name = getenv(strings->name_env);
+ if (email == NULL)
+ email = getenv(strings->email_env);
+ if (date == NULL)
+ date = getenv(strings->date_env);
+
+ return xstrdup(fmt_ident(name, email, date, 1));
+}
+
+static void parse_and_validate_options(const char ***argv)
+{
+ int f = 0;
+
+ git_config(git_status_config);
+
+ (*argv)++;
+ while (scan_options(argv, commit_options))
+ ;
+
+ if (logfile || message || use_message)
+ no_edit = 1;
+
+ if (get_sha1("HEAD", head_sha1))
+ initial_commit = 1;
+
+ if (!get_sha1("MERGE_HEAD", merge_head_sha1))
+ in_merge = 1;
+
+ /* Sanity check options */
+ if (amend && initial_commit)
+ die("You have nothing to amend.");
+ if (amend && in_merge)
+ die("You are in the middle of a merger -- cannot amend.");
+
+ if (use_message)
+ f++;
+ if (edit_message)
+ f++;
+ if (logfile)
+ f++;
+ if (amend)
+ f++;
+ if (f > 1)
+ die("Only one of -c/-C/-F/--amend can be used.");
+ if (message && f > 0)
+ die("Option -m cannot be combined with -c/-C/-F/--amend.");
+ if (edit_message)
+ use_message = edit_message;
+ if (amend)
+ use_message = "HEAD";
+ if (use_message) {
+ unsigned char sha1[20];
+
+ if (get_sha1(use_message, sha1))
+ die("could not lookup commit %s", use_message);
+ use_message_commit = lookup_commit(sha1);
+ if (!use_message_commit || parse_commit(use_message_commit))
+ die("could not parse commit %s", use_message);
+ }
+
+ if (also && only)
+ die("Only one of --include/--only can be used.");
+ if (!*argv && (also || (only && !amend)))
+ die("No paths with --include/--only does not make sense.");
+ if (!*argv && only && amend)
+ only_include_assumed = "Clever... amending the last one with dirty index.";
+ if (*argv && !also && !only) {
+ only_include_assumed = "Explicit paths specified without -i nor -o; assuming --only paths...";
+ also = 0;
+ }
+
+ if (all && interactive)
+ die("Cannot use -a, --interactive or -i at the same time.");
+ else if (all && **argv)
+ die("Paths with -a does not make sense.");
+ else if (interactive && **argv)
+ die("Paths with --interactive does not make sense.");
+}
+
+int cmd_status(int argc, const char **argv, const char *prefix)
+{
+ const char *index_file;
+ int commitable;
+
+ parse_and_validate_options(&argv);
+
+ index_file = prepare_index(argv, prefix);
+
+ commitable = run_status(stdout, index_file);
+
+ rollback_lock_file(&lock_file);
+
+ return commitable ? 0 : 1;
+}
+
+static void launch_editor(const char *path)
+{
+ const char *editor, *terminal;
+ struct child_process child;
+ const char *args[3];
+
+ editor = getenv("VISUAL");
+ if (!editor)
+ editor = getenv("EDITOR");
+
+ terminal = getenv("TERM");
+ if (!editor && (!terminal || !strcmp(terminal, "dumb"))) {
+ fprintf(stderr,
+ "Terminal is dumb but no VISUAL nor EDITOR defined.\n"
+ "Please supply the commit log message using either\n"
+ "-m or -F option. A boilerplate log message has\n"
+ "been prepared in $GIT_DIR/COMMIT_EDITMSG\n");
+ exit(1);
+ }
+
+ if (!editor)
+ editor = "vi";
+
+ memset(&child, 0, sizeof(child));
+ child.argv = args;
+ args[0] = editor;
+ args[1] = path;
+ args[2] = NULL;
+
+ if (run_command(&child))
+ die("could not launch editor %s.", editor);
+}
+
+static int message_is_empty(const char *buffer, int len)
+{
+ static const char signed_off_by[] = "Signed-off-by: ";
+ const char *nl;
+ int eol, i;
+
+ for (i = 0; i < len; i++) {
+ nl = memchr(buffer + i, '\n', len - i);
+ if (nl)
+ eol = nl - buffer;
+ else
+ eol = len;
+
+ if (strlen(signed_off_by) <= eol - i &&
+ !prefixcmp(buffer + i, signed_off_by)) {
+ i = eol;
+ continue;
+ }
+ while (i < eol)
+ if (!isspace(buffer[i++]))
+ return 0;
+ }
+
+ return 1;
+}
+
+static int run_hook(const char *index_file, const char *name, const char *arg)
+{
+ struct child_process hook;
+ const char *argv[3], *env[2];
+ char index[PATH_MAX];
+
+ argv[0] = git_path("hooks/%s", name);
+ argv[1] = arg;
+ argv[2] = NULL;
+ snprintf(index, sizeof(index), "GIT_INDEX_FILE=%s", index_file);
+ env[0] = index;
+ env[1] = NULL;
+
+ if (access(argv[0], X_OK) < 0)
+ return 0;
+
+ memset(&hook, 0, sizeof(hook));
+ hook.argv = argv;
+ hook.no_stdin = 1;
+ hook.stdout_to_stderr = 1;
+ hook.env = env;
+
+ return run_command(&hook);
+}
+
+static void print_summary(const char *prefix, const unsigned char *sha1)
+{
+ struct rev_info rev;
+ struct commit *commit;
+
+ commit = lookup_commit(sha1);
+ if (!commit)
+ die("couldn't look up newly created commit\n");
+ if (!commit || parse_commit(commit))
+ die("could not parse newly created commit");
+
+ init_revisions(&rev, prefix);
+ setup_revisions(0, NULL, &rev, NULL);
+
+ rev.abbrev = 0;
+ rev.diff = 1;
+ rev.diffopt.output_format =
+ DIFF_FORMAT_SHORTSTAT | DIFF_FORMAT_SUMMARY;
+
+ rev.verbose_header = 1;
+ rev.show_root_diff = 1;
+ rev.commit_format = get_commit_format("format:%h: %s");
+ rev.always_show_header = 1;
+
+ printf("Created %scommit ", initial_commit ? "initial " : "");
+
+ log_tree_commit(&rev, commit);
+}
+
+#define MAXPARENT (16)
+static unsigned char parent_sha1[MAXPARENT][20];
+
+int cmd_commit(int argc, const char **argv, const char *prefix)
+{
+ int parent_count = 0;
+ unsigned long len;
+ char *buffer;
+ const char *index_file, *reflog_msg;
+ const unsigned char *commit_sha1;
+ struct ref_lock *ref_lock;
+
+ parse_and_validate_options(&argv);
+
+ index_file = prepare_index(argv, prefix);
+
+ if (run_hook(index_file, "pre-commit", NULL))
+ exit(1);
+
+ if (!prepare_log_message(index_file)) {
+ run_status(stdout, index_file);
+ unlink(commit_editmsg);
+ return 1;
+ }
+
+ if (!no_edit)
+ launch_editor(git_path(commit_editmsg));
+
+ if (run_hook(index_file, "commit-msg", commit_editmsg))
+ exit(1);
+
+ if (read_path(git_path(commit_editmsg), &buffer, &len))
+ die("could not read commit message file '%s': %s",
+ git_path(commit_editmsg), strerror(errno));
+
+ len = strip_lines(buffer, len);
+
+ if (message_is_empty(buffer, len))
+ die("* no commit message? aborting commit.");
+
+ /* Determine parents */
+ if (initial_commit) {
+ reflog_msg = "commit (initial)";
+ parent_count = 0;
+ } else if (amend) {
+ struct commit_list *c;
+ struct commit *commit;
+ int i = 0;
+
+ reflog_msg = "commit (amend)";
+ commit = lookup_commit(head_sha1);
+ if (!commit || parse_commit(commit))
+ die("could not parse HEAD commit");
+
+ for (c = commit->parents; c; c = c->next) {
+ hashcpy(parent_sha1[i++], c->item->object.sha1);
+ if (i == MAXPARENT)
+ die("Too many parents (%d max)", MAXPARENT);
+ }
+ parent_count = i;
+ } else if (in_merge) {
+ /* FIXME: how are merges with more than two parents handled? */
+ reflog_msg = "commit (merge)";
+ hashcpy(parent_sha1[0], head_sha1);
+ hashcpy(parent_sha1[1], merge_head_sha1);
+ parent_count = 2;
+ } else {
+ reflog_msg = "commit";
+ hashcpy(parent_sha1[0], head_sha1);
+ parent_count = 1;
+ }
+
+ read_cache_from(index_file);
+ active_cache_tree = cache_tree();
+ if (cache_tree_update(active_cache_tree,
+ active_cache, active_nr, 0, 0) < 0)
+ die("Error building trees");
+
+ commit_sha1 = create_commit(active_cache_tree->sha1,
+ parent_sha1, parent_count,
+ determine_info(&author_info_strings),
+ determine_info(&committer_info_strings),
+ buffer, len);
+
+ ref_lock = lock_any_ref_for_update("HEAD",
+ initial_commit ? NULL : head_sha1,
+ 0);
+ if (!ref_lock)
+ die("cannot lock HEAD ref");
+ if (write_ref_sha1(ref_lock, commit_sha1, reflog_msg) < 0)
+ die("cannot update HEAD ref");
+
+ unlink(git_path("MERGE_HEAD"));
+ unlink(git_path("MERGE_MSG"));
+
+ if (lock_file.filename[0] && commit_locked_index(&lock_file))
+ die("failed to write new index");
+
+ /*
+ * FIXME:
+ * if test -d "$GIT_DIR/rr-cache"
+ * then
+ * git-rerere
+ * fi
+ */
+
+ run_hook(index_file, "post-commit", NULL);
+
+ if (!quiet)
+ print_summary(prefix, commit_sha1);
+
+ return 0;
+}
diff --git a/builtin.h b/builtin.h
index da4834c..7f395da 100644
--- a/builtin.h
+++ b/builtin.h
@@ -23,6 +23,7 @@ extern int cmd_check_attr(int argc, const char **argv, const char *prefix);
extern int cmd_check_ref_format(int argc, const char **argv, const char *prefix);
extern int cmd_cherry(int argc, const char **argv, const char *prefix);
extern int cmd_cherry_pick(int argc, const char **argv, const char *prefix);
+extern int cmd_commit(int argc, const char **argv, const char *prefix);
extern int cmd_commit_tree(int argc, const char **argv, const char *prefix);
extern int cmd_count_objects(int argc, const char **argv, const char *prefix);
extern int cmd_describe(int argc, const char **argv, const char *prefix);
@@ -63,10 +64,10 @@ extern int cmd_rev_list(int argc, const char **argv, const char *prefix);
extern int cmd_rev_parse(int argc, const char **argv, const char *prefix);
extern int cmd_revert(int argc, const char **argv, const char *prefix);
extern int cmd_rm(int argc, const char **argv, const char *prefix);
-extern int cmd_runstatus(int argc, const char **argv, const char *prefix);
extern int cmd_shortlog(int argc, const char **argv, const char *prefix);
extern int cmd_show(int argc, const char **argv, const char *prefix);
extern int cmd_show_branch(int argc, const char **argv, const char *prefix);
+extern int cmd_status(int argc, const char **argv, const char *prefix);
extern int cmd_stripspace(int argc, const char **argv, const char *prefix);
extern int cmd_symbolic_ref(int argc, const char **argv, const char *prefix);
extern int cmd_tar_tree(int argc, const char **argv, const char *prefix);
diff --git a/cache.h b/cache.h
index 5e7381e..0403ada 100644
--- a/cache.h
+++ b/cache.h
@@ -245,7 +245,8 @@ extern int ie_match_stat(struct index_state *, struct cache_entry *, struct stat
extern int ie_modified(struct index_state *, struct cache_entry *, struct stat *, int);
extern int ce_path_match(const struct cache_entry *ce, const char **pathspec);
extern int index_fd(unsigned char *sha1, int fd, struct stat *st, int write_object, enum object_type type, const char *path);
-extern int read_pipe(int fd, char** return_buf, unsigned long* return_size);
+extern int read_fd(int fd, char** return_buf, unsigned long* return_size);
+extern int read_path(const char *path, char** return_buf, unsigned long* return_size);
extern int index_pipe(unsigned char *sha1, int fd, const char *type, int write_object);
extern int index_path(unsigned char *sha1, const char *path, struct stat *st, int write_object);
extern void fill_stat_cache_info(struct cache_entry *ce, struct stat *st);
diff --git a/color.c b/color.c
index 09d82ee..124ba33 100644
--- a/color.c
+++ b/color.c
@@ -135,39 +135,39 @@ int git_config_colorbool(const char *var, const char *value)
return git_config_bool(var, value);
}
-static int color_vprintf(const char *color, const char *fmt,
+static int color_vfprintf(FILE *fp, const char *color, const char *fmt,
va_list args, const char *trail)
{
int r = 0;
if (*color)
- r += printf("%s", color);
- r += vprintf(fmt, args);
+ r += fprintf(fp, "%s", color);
+ r += vfprintf(fp, fmt, args);
if (*color)
- r += printf("%s", COLOR_RESET);
+ r += fprintf(fp, "%s", COLOR_RESET);
if (trail)
- r += printf("%s", trail);
+ r += fprintf(fp, "%s", trail);
return r;
}
-int color_printf(const char *color, const char *fmt, ...)
+int color_fprintf(FILE *fp, const char *color, const char *fmt, ...)
{
va_list args;
int r;
va_start(args, fmt);
- r = color_vprintf(color, fmt, args, NULL);
+ r = color_vfprintf(fp, color, fmt, args, NULL);
va_end(args);
return r;
}
-int color_printf_ln(const char *color, const char *fmt, ...)
+int color_fprintf_ln(FILE *fp, const char *color, const char *fmt, ...)
{
va_list args;
int r;
va_start(args, fmt);
- r = color_vprintf(color, fmt, args, "\n");
+ r = color_vfprintf(fp, color, fmt, args, "\n");
va_end(args);
return r;
}
diff --git a/color.h b/color.h
index 88bb8ff..6809800 100644
--- a/color.h
+++ b/color.h
@@ -6,7 +6,7 @@
int git_config_colorbool(const char *var, const char *value);
void color_parse(const char *var, const char *value, char *dst);
-int color_printf(const char *color, const char *fmt, ...);
-int color_printf_ln(const char *color, const char *fmt, ...);
+int color_fprintf(FILE *fp, const char *color, const char *fmt, ...);
+int color_fprintf_ln(FILE *fp, const char *color, const char *fmt, ...);
#endif /* COLOR_H */
diff --git a/commit.h b/commit.h
index a313b53..a07e379 100644
--- a/commit.h
+++ b/commit.h
@@ -122,4 +122,13 @@ extern struct commit_list *get_shallow_commits(struct object_array *heads,
int depth, int shallow_flag, int not_shallow_flag);
int in_merge_bases(struct commit *, struct commit **, int);
+
+const unsigned char *
+create_commit(const unsigned char *tree_sha1,
+ unsigned char parent_sha1[][20], int parents,
+ const char *author_info, const char *committer_info,
+ const char *message, int length);
+
+int interactive_add(void);
+
#endif /* COMMIT_H */
diff --git a/git-commit.sh b/git-commit.sh
deleted file mode 100755
index 5547a02..0000000
--- a/git-commit.sh
+++ /dev/null
@@ -1,658 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2005 Linus Torvalds
-# Copyright (c) 2006 Junio C Hamano
-
-USAGE='[-a | --interactive] [-s] [-v] [--no-verify] [-m <message> | -F <logfile> | (-C|-c) <commit> | --amend] [-u] [-e] [--author <author>] [[-i | -o] <path>...]'
-SUBDIRECTORY_OK=Yes
-. git-sh-setup
-require_work_tree
-
-git-rev-parse --verify HEAD >/dev/null 2>&1 || initial_commit=t
-
-case "$0" in
-*status)
- status_only=t
- ;;
-*commit)
- status_only=
- ;;
-esac
-
-refuse_partial () {
- echo >&2 "$1"
- echo >&2 "You might have meant to say 'git commit -i paths...', perhaps?"
- exit 1
-}
-
-THIS_INDEX="$GIT_DIR/index"
-NEXT_INDEX="$GIT_DIR/next-index$$"
-rm -f "$NEXT_INDEX"
-save_index () {
- cp -p "$THIS_INDEX" "$NEXT_INDEX"
-}
-
-run_status () {
- # If TMP_INDEX is defined, that means we are doing
- # "--only" partial commit, and that index file is used
- # to build the tree for the commit. Otherwise, if
- # NEXT_INDEX exists, that is the index file used to
- # make the commit. Otherwise we are using as-is commit
- # so the regular index file is what we use to compare.
- if test '' != "$TMP_INDEX"
- then
- GIT_INDEX_FILE="$TMP_INDEX"
- export GIT_INDEX_FILE
- elif test -f "$NEXT_INDEX"
- then
- GIT_INDEX_FILE="$NEXT_INDEX"
- export GIT_INDEX_FILE
- fi
-
- case "$status_only" in
- t) color= ;;
- *) color=--nocolor ;;
- esac
- git-runstatus ${color} \
- ${verbose:+--verbose} \
- ${amend:+--amend} \
- ${untracked_files:+--untracked}
-}
-
-trap '
- test -z "$TMP_INDEX" || {
- test -f "$TMP_INDEX" && rm -f "$TMP_INDEX"
- }
- rm -f "$NEXT_INDEX"
-' 0
-
-################################################################
-# Command line argument parsing and sanity checking
-
-all=
-also=
-interactive=
-only=
-logfile=
-use_commit=
-amend=
-edit_flag=
-no_edit=
-log_given=
-log_message=
-verify=t
-quiet=
-verbose=
-signoff=
-force_author=
-only_include_assumed=
-untracked_files=
-while case "$#" in 0) break;; esac
-do
- case "$1" in
- -F|--F|-f|--f|--fi|--fil|--file)
- case "$#" in 1) usage ;; esac
- shift
- no_edit=t
- log_given=t$log_given
- logfile="$1"
- shift
- ;;
- -F*|-f*)
- no_edit=t
- log_given=t$log_given
- logfile=`expr "z$1" : 'z-[Ff]\(.*\)'`
- shift
- ;;
- --F=*|--f=*|--fi=*|--fil=*|--file=*)
- no_edit=t
- log_given=t$log_given
- logfile=`expr "z$1" : 'z-[^=]*=\(.*\)'`
- shift
- ;;
- -a|--a|--al|--all)
- all=t
- shift
- ;;
- --au=*|--aut=*|--auth=*|--autho=*|--author=*)
- force_author=`expr "z$1" : 'z-[^=]*=\(.*\)'`
- shift
- ;;
- --au|--aut|--auth|--autho|--author)
- case "$#" in 1) usage ;; esac
- shift
- force_author="$1"
- shift
- ;;
- -e|--e|--ed|--edi|--edit)
- edit_flag=t
- shift
- ;;
- -i|--i|--in|--inc|--incl|--inclu|--includ|--include)
- also=t
- shift
- ;;
- --int|--inte|--inter|--intera|--interac|--interact|--interacti|\
- --interactiv|--interactive)
- interactive=t
- shift
- ;;
- -o|--o|--on|--onl|--only)
- only=t
- shift
- ;;
- -m|--m|--me|--mes|--mess|--messa|--messag|--message)
- case "$#" in 1) usage ;; esac
- shift
- log_given=m$log_given
- if test "$log_message" = ''
- then
- log_message="$1"
- else
- log_message="$log_message
-
-$1"
- fi
- no_edit=t
- shift
- ;;
- -m*)
- log_given=m$log_given
- if test "$log_message" = ''
- then
- log_message=`expr "z$1" : 'z-m\(.*\)'`
- else
- log_message="$log_message
-
-`expr "z$1" : 'z-m\(.*\)'`"
- fi
- no_edit=t
- shift
- ;;
- --m=*|--me=*|--mes=*|--mess=*|--messa=*|--messag=*|--message=*)
- log_given=m$log_given
- if test "$log_message" = ''
- then
- log_message=`expr "z$1" : 'z-[^=]*=\(.*\)'`
- else
- log_message="$log_message
-
-`expr "z$1" : 'zq-[^=]*=\(.*\)'`"
- fi
- no_edit=t
- shift
- ;;
- -n|--n|--no|--no-|--no-v|--no-ve|--no-ver|--no-veri|--no-verif|\
- --no-verify)
- verify=
- shift
- ;;
- --a|--am|--ame|--amen|--amend)
- amend=t
- log_given=t$log_given
- use_commit=HEAD
- shift
- ;;
- -c)
- case "$#" in 1) usage ;; esac
- shift
- log_given=t$log_given
- use_commit="$1"
- no_edit=
- shift
- ;;
- --ree=*|--reed=*|--reedi=*|--reedit=*|--reedit-=*|--reedit-m=*|\
- --reedit-me=*|--reedit-mes=*|--reedit-mess=*|--reedit-messa=*|\
- --reedit-messag=*|--reedit-message=*)
- log_given=t$log_given
- use_commit=`expr "z$1" : 'z-[^=]*=\(.*\)'`
- no_edit=
- shift
- ;;
- --ree|--reed|--reedi|--reedit|--reedit-|--reedit-m|--reedit-me|\
- --reedit-mes|--reedit-mess|--reedit-messa|--reedit-messag|\
- --reedit-message)
- case "$#" in 1) usage ;; esac
- shift
- log_given=t$log_given
- use_commit="$1"
- no_edit=
- shift
- ;;
- -C)
- case "$#" in 1) usage ;; esac
- shift
- log_given=t$log_given
- use_commit="$1"
- no_edit=t
- shift
- ;;
- --reu=*|--reus=*|--reuse=*|--reuse-=*|--reuse-m=*|--reuse-me=*|\
- --reuse-mes=*|--reuse-mess=*|--reuse-messa=*|--reuse-messag=*|\
- --reuse-message=*)
- log_given=t$log_given
- use_commit=`expr "z$1" : 'z-[^=]*=\(.*\)'`
- no_edit=t
- shift
- ;;
- --reu|--reus|--reuse|--reuse-|--reuse-m|--reuse-me|--reuse-mes|\
- --reuse-mess|--reuse-messa|--reuse-messag|--reuse-message)
- case "$#" in 1) usage ;; esac
- shift
- log_given=t$log_given
- use_commit="$1"
- no_edit=t
- shift
- ;;
- -s|--s|--si|--sig|--sign|--signo|--signof|--signoff)
- signoff=t
- shift
- ;;
- -q|--q|--qu|--qui|--quie|--quiet)
- quiet=t
- shift
- ;;
- -v|--v|--ve|--ver|--verb|--verbo|--verbos|--verbose)
- verbose=t
- shift
- ;;
- -u|--u|--un|--unt|--untr|--untra|--untrac|--untrack|--untracke|\
- --untracked|--untracked-|--untracked-f|--untracked-fi|--untracked-fil|\
- --untracked-file|--untracked-files)
- untracked_files=t
- shift
- ;;
- --)
- shift
- break
- ;;
- -*)
- usage
- ;;
- *)
- break
- ;;
- esac
-done
-case "$edit_flag" in t) no_edit= ;; esac
-
-################################################################
-# Sanity check options
-
-case "$amend,$initial_commit" in
-t,t)
- die "You do not have anything to amend." ;;
-t,)
- if [ -f "$GIT_DIR/MERGE_HEAD" ]; then
- die "You are in the middle of a merge -- cannot amend."
- fi ;;
-esac
-
-case "$log_given" in
-tt*)
- die "Only one of -c/-C/-F/--amend can be used." ;;
-*tm*|*mt*)
- die "Option -m cannot be combined with -c/-C/-F/--amend." ;;
-esac
-
-case "$#,$also,$only,$amend" in
-*,t,t,*)
- die "Only one of --include/--only can be used." ;;
-0,t,,* | 0,,t,)
- die "No paths with --include/--only does not make sense." ;;
-0,,t,t)
- only_include_assumed="# Clever... amending the last one with dirty index." ;;
-0,,,*)
- ;;
-*,,,*)
- only_include_assumed="# Explicit paths specified without -i nor -o; assuming --only paths..."
- also=
- ;;
-esac
-unset only
-case "$all,$interactive,$also,$#" in
-*t,*t,*)
- die "Cannot use -a, --interactive or -i at the same time." ;;
-t,,[1-9]*)
- die "Paths with -a does not make sense." ;;
-,t,[1-9]*)
- die "Paths with --interactive does not make sense." ;;
-,,t,0)
- die "No paths with -i does not make sense." ;;
-esac
-
-################################################################
-# Prepare index to have a tree to be committed
-
-case "$all,$also" in
-t,)
- if test ! -f "$THIS_INDEX"
- then
- die 'nothing to commit (use "git add file1 file2" to include for commit)'
- fi
- save_index &&
- (
- cd_to_toplevel &&
- GIT_INDEX_FILE="$NEXT_INDEX" &&
- export GIT_INDEX_FILE &&
- git-diff-files --name-only -z |
- git-update-index --remove -z --stdin
- ) || exit
- ;;
-,t)
- save_index &&
- git-ls-files --error-unmatch -- "$@" >/dev/null || exit
-
- git-diff-files --name-only -z -- "$@" |
- (
- cd_to_toplevel &&
- GIT_INDEX_FILE="$NEXT_INDEX" &&
- export GIT_INDEX_FILE &&
- git-update-index --remove -z --stdin
- ) || exit
- ;;
-,)
- if test "$interactive" = t; then
- git add --interactive || exit
- fi
- case "$#" in
- 0)
- ;; # commit as-is
- *)
- if test -f "$GIT_DIR/MERGE_HEAD"
- then
- refuse_partial "Cannot do a partial commit during a merge."
- fi
- TMP_INDEX="$GIT_DIR/tmp-index$$"
- commit_only=`git-ls-files --error-unmatch -- "$@"` || exit
-
- # Build a temporary index and update the real index
- # the same way.
- if test -z "$initial_commit"
- then
- GIT_INDEX_FILE="$THIS_INDEX" \
- git-read-tree --index-output="$TMP_INDEX" -i -m HEAD
- else
- rm -f "$TMP_INDEX"
- fi || exit
-
- printf '%s\n' "$commit_only" |
- GIT_INDEX_FILE="$TMP_INDEX" \
- git-update-index --add --remove --stdin &&
-
- save_index &&
- printf '%s\n' "$commit_only" |
- (
- GIT_INDEX_FILE="$NEXT_INDEX"
- export GIT_INDEX_FILE
- git-update-index --remove --stdin
- ) || exit
- ;;
- esac
- ;;
-esac
-
-################################################################
-# If we do as-is commit, the index file will be THIS_INDEX,
-# otherwise NEXT_INDEX after we make this commit. We leave
-# the index as is if we abort.
-
-if test -f "$NEXT_INDEX"
-then
- USE_INDEX="$NEXT_INDEX"
-else
- USE_INDEX="$THIS_INDEX"
-fi
-
-case "$status_only" in
-t)
- # This will silently fail in a read-only repository, which is
- # what we want.
- GIT_INDEX_FILE="$USE_INDEX" git-update-index -q --unmerged --refresh
- run_status
- exit $?
- ;;
-'')
- GIT_INDEX_FILE="$USE_INDEX" git-update-index -q --refresh || exit
- ;;
-esac
-
-################################################################
-# Grab commit message, write out tree and make commit.
-
-if test t = "$verify" && test -x "$GIT_DIR"/hooks/pre-commit
-then
- if test "$TMP_INDEX"
- then
- GIT_INDEX_FILE="$TMP_INDEX" "$GIT_DIR"/hooks/pre-commit
- else
- GIT_INDEX_FILE="$USE_INDEX" "$GIT_DIR"/hooks/pre-commit
- fi || exit
-fi
-
-if test "$log_message" != ''
-then
- printf '%s\n' "$log_message"
-elif test "$logfile" != ""
-then
- if test "$logfile" = -
- then
- test -t 0 &&
- echo >&2 "(reading log message from standard input)"
- cat
- else
- cat <"$logfile"
- fi
-elif test "$use_commit" != ""
-then
- encoding=$(git config i18n.commitencoding || echo UTF-8)
- git show -s --pretty=raw --encoding="$encoding" "$use_commit" |
- sed -e '1,/^$/d' -e 's/^ //'
-elif test -f "$GIT_DIR/MERGE_MSG"
-then
- cat "$GIT_DIR/MERGE_MSG"
-elif test -f "$GIT_DIR/SQUASH_MSG"
-then
- cat "$GIT_DIR/SQUASH_MSG"
-fi | git-stripspace >"$GIT_DIR"/COMMIT_EDITMSG
-
-case "$signoff" in
-t)
- need_blank_before_signoff=
- tail -n 1 "$GIT_DIR"/COMMIT_EDITMSG |
- grep 'Signed-off-by:' >/dev/null || need_blank_before_signoff=yes
- {
- test -z "$need_blank_before_signoff" || echo
- git-var GIT_COMMITTER_IDENT | sed -e '
- s/>.*/>/
- s/^/Signed-off-by: /
- '
- } >>"$GIT_DIR"/COMMIT_EDITMSG
- ;;
-esac
-
-if test -f "$GIT_DIR/MERGE_HEAD" && test -z "$no_edit"; then
- echo "#"
- echo "# It looks like you may be committing a MERGE."
- echo "# If this is not correct, please remove the file"
- printf '%s\n' "# $GIT_DIR/MERGE_HEAD"
- echo "# and try again"
- echo "#"
-fi >>"$GIT_DIR"/COMMIT_EDITMSG
-
-# Author
-if test '' != "$use_commit"
-then
- pick_author_script='
- /^author /{
- s/'\''/'\''\\'\'\''/g
- h
- s/^author \([^<]*\) <[^>]*> .*$/\1/
- s/'\''/'\''\'\'\''/g
- s/.*/GIT_AUTHOR_NAME='\''&'\''/p
-
- g
- s/^author [^<]* <\([^>]*\)> .*$/\1/
- s/'\''/'\''\'\'\''/g
- s/.*/GIT_AUTHOR_EMAIL='\''&'\''/p
-
- g
- s/^author [^<]* <[^>]*> \(.*\)$/\1/
- s/'\''/'\''\'\'\''/g
- s/.*/GIT_AUTHOR_DATE='\''&'\''/p
-
- q
- }
- '
- encoding=$(git config i18n.commitencoding || echo UTF-8)
- set_author_env=`git show -s --pretty=raw --encoding="$encoding" "$use_commit" |
- LANG=C LC_ALL=C sed -ne "$pick_author_script"`
- eval "$set_author_env"
- export GIT_AUTHOR_NAME
- export GIT_AUTHOR_EMAIL
- export GIT_AUTHOR_DATE
-fi
-if test '' != "$force_author"
-then
- GIT_AUTHOR_NAME=`expr "z$force_author" : 'z\(.*[^ ]\) *<.*'` &&
- GIT_AUTHOR_EMAIL=`expr "z$force_author" : '.*\(<.*\)'` &&
- test '' != "$GIT_AUTHOR_NAME" &&
- test '' != "$GIT_AUTHOR_EMAIL" ||
- die "malformed --author parameter"
- export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL
-fi
-
-PARENTS="-p HEAD"
-if test -z "$initial_commit"
-then
- rloga='commit'
- if [ -f "$GIT_DIR/MERGE_HEAD" ]; then
- rloga='commit (merge)'
- PARENTS="-p HEAD "`sed -e 's/^/-p /' "$GIT_DIR/MERGE_HEAD"`
- elif test -n "$amend"; then
- rloga='commit (amend)'
- PARENTS=$(git-cat-file commit HEAD |
- sed -n -e '/^$/q' -e 's/^parent /-p /p')
- fi
- current="$(git-rev-parse --verify HEAD)"
-else
- if [ -z "$(git-ls-files)" ]; then
- echo >&2 'nothing to commit (use "git add file1 file2" to include for commit)'
- exit 1
- fi
- PARENTS=""
- rloga='commit (initial)'
- current=''
-fi
-set_reflog_action "$rloga"
-
-if test -z "$no_edit"
-then
- {
- echo ""
- echo "# Please enter the commit message for your changes."
- echo "# (Comment lines starting with '#' will not be included)"
- test -z "$only_include_assumed" || echo "$only_include_assumed"
- run_status
- } >>"$GIT_DIR"/COMMIT_EDITMSG
-else
- # we need to check if there is anything to commit
- run_status >/dev/null
-fi
-if [ "$?" != "0" -a ! -f "$GIT_DIR/MERGE_HEAD" -a -z "$amend" ]
-then
- rm -f "$GIT_DIR/COMMIT_EDITMSG" "$GIT_DIR/SQUASH_MSG"
- run_status
- exit 1
-fi
-
-case "$no_edit" in
-'')
- case "${VISUAL:-$EDITOR},$TERM" in
- ,dumb)
- echo >&2 "Terminal is dumb but no VISUAL nor EDITOR defined."
- echo >&2 "Please supply the commit log message using either"
- echo >&2 "-m or -F option. A boilerplate log message has"
- echo >&2 "been prepared in $GIT_DIR/COMMIT_EDITMSG"
- exit 1
- ;;
- esac
- git-var GIT_AUTHOR_IDENT > /dev/null || die
- git-var GIT_COMMITTER_IDENT > /dev/null || die
- ${VISUAL:-${EDITOR:-vi}} "$GIT_DIR/COMMIT_EDITMSG"
- ;;
-esac
-
-case "$verify" in
-t)
- if test -x "$GIT_DIR"/hooks/commit-msg
- then
- "$GIT_DIR"/hooks/commit-msg "$GIT_DIR"/COMMIT_EDITMSG || exit
- fi
-esac
-
-if test -z "$no_edit"
-then
- sed -e '
- /^diff --git a\/.*/{
- s///
- q
- }
- /^#/d
- ' "$GIT_DIR"/COMMIT_EDITMSG
-else
- cat "$GIT_DIR"/COMMIT_EDITMSG
-fi |
-git-stripspace >"$GIT_DIR"/COMMIT_MSG
-
-if cnt=`grep -v -i '^Signed-off-by' "$GIT_DIR"/COMMIT_MSG |
- git-stripspace |
- wc -l` &&
- test 0 -lt $cnt
-then
- if test -z "$TMP_INDEX"
- then
- tree=$(GIT_INDEX_FILE="$USE_INDEX" git-write-tree)
- else
- tree=$(GIT_INDEX_FILE="$TMP_INDEX" git-write-tree) &&
- rm -f "$TMP_INDEX"
- fi &&
- commit=$(cat "$GIT_DIR"/COMMIT_MSG | git-commit-tree $tree $PARENTS) &&
- rlogm=$(sed -e 1q "$GIT_DIR"/COMMIT_MSG) &&
- git-update-ref -m "$GIT_REFLOG_ACTION: $rlogm" HEAD $commit "$current" &&
- rm -f -- "$GIT_DIR/MERGE_HEAD" "$GIT_DIR/MERGE_MSG" &&
- if test -f "$NEXT_INDEX"
- then
- mv "$NEXT_INDEX" "$THIS_INDEX"
- else
- : ;# happy
- fi
-else
- echo >&2 "* no commit message? aborting commit."
- false
-fi
-ret="$?"
-rm -f "$GIT_DIR/COMMIT_MSG" "$GIT_DIR/COMMIT_EDITMSG" "$GIT_DIR/SQUASH_MSG"
-
-cd_to_toplevel
-
-if test -d "$GIT_DIR/rr-cache"
-then
- git-rerere
-fi
-
-if test "$ret" = 0
-then
- if test -x "$GIT_DIR"/hooks/post-commit
- then
- "$GIT_DIR"/hooks/post-commit
- fi
- if test -z "$quiet"
- then
- commit=`git-diff-tree --always --shortstat --pretty="format:%h: %s"\
- --summary --root HEAD --`
- echo "Created${initial_commit:+ initial} commit $commit"
- fi
-fi
-
-exit "$ret"
diff --git a/git.c b/git.c
index 29b55a1..4018e3c 100644
--- a/git.c
+++ b/git.c
@@ -237,6 +237,7 @@ static void handle_internal_command(int argc, const char **argv, char **envp)
{ "check-attr", cmd_check_attr, RUN_SETUP | NOT_BARE },
{ "cherry", cmd_cherry, RUN_SETUP },
{ "cherry-pick", cmd_cherry_pick, RUN_SETUP | NOT_BARE },
+ { "commit", cmd_commit, RUN_SETUP },
{ "commit-tree", cmd_commit_tree, RUN_SETUP },
{ "config", cmd_config },
{ "count-objects", cmd_count_objects, RUN_SETUP },
@@ -279,10 +280,10 @@ static void handle_internal_command(int argc, const char **argv, char **envp)
{ "rev-parse", cmd_rev_parse, RUN_SETUP },
{ "revert", cmd_revert, RUN_SETUP | NOT_BARE },
{ "rm", cmd_rm, RUN_SETUP | NOT_BARE },
- { "runstatus", cmd_runstatus, RUN_SETUP | NOT_BARE },
{ "shortlog", cmd_shortlog, RUN_SETUP | USE_PAGER },
{ "show-branch", cmd_show_branch, RUN_SETUP },
{ "show", cmd_show, RUN_SETUP | USE_PAGER },
+ { "status", cmd_status, RUN_SETUP | NOT_BARE },
{ "stripspace", cmd_stripspace },
{ "symbolic-ref", cmd_symbolic_ref, RUN_SETUP },
{ "tar-tree", cmd_tar_tree },
diff --git a/mktag.c b/mktag.c
index b82e377..26b9ebf 100644
--- a/mktag.c
+++ b/mktag.c
@@ -111,8 +111,8 @@ static int verify_tag(char *buffer, unsigned long size)
int main(int argc, char **argv)
{
- unsigned long size = 4096;
- char *buffer = xmalloc(size);
+ unsigned long size;
+ char *buffer;
unsigned char result_sha1[20];
if (argc != 1)
@@ -120,10 +120,8 @@ int main(int argc, char **argv)
setup_git_directory();
- if (read_pipe(0, &buffer, &size)) {
- free(buffer);
+ if (read_fd(0, &buffer, &size))
die("could not read from stdin");
- }
/* Verify it for some basic sanity: it needs to start with
"object <sha1>\ntype\ntagger " */
diff --git a/sha1_file.c b/sha1_file.c
index 2b86086..91e8854 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -2286,18 +2286,17 @@ int has_sha1_file(const unsigned char *sha1)
}
/*
- * reads from fd as long as possible into a supplied buffer of size bytes.
- * If necessary the buffer's size is increased using realloc()
+ * reads from fd as long as possible and allocates a buffer to hold
+ * the contents. The buffer and size of the contents is returned in
+ * *return_buf and *return_size. In case of failure, the allocated
+ * buffers are freed, otherwise, the buffer must be freed using xfree.
*
* returns 0 if anything went fine and -1 otherwise
- *
- * NOTE: both buf and size may change, but even when -1 is returned
- * you still have to free() it yourself.
*/
-int read_pipe(int fd, char** return_buf, unsigned long* return_size)
+int read_fd(int fd, char** return_buf, unsigned long* return_size)
{
- char* buf = *return_buf;
- unsigned long size = *return_size;
+ unsigned long size = 4096;
+ char* buf = xmalloc(size);
ssize_t iret;
unsigned long off = 0;
@@ -2315,21 +2314,38 @@ int read_pipe(int fd, char** return_buf, unsigned long* return_size)
*return_buf = buf;
*return_size = off;
- if (iret < 0)
+ if (iret < 0) {
+ free(buf);
+ return -1;
+ }
+
+ return 0;
+}
+
+int read_path(const char *path, char** return_buf, unsigned long* return_size)
+{
+ int fd;
+
+ fd = open(path, O_RDONLY);
+ if (fd < 0)
+ return -1;
+ if (read_fd(fd, return_buf, return_size)) {
+ close(fd);
return -1;
+ }
+ close(fd);
+
return 0;
}
int index_pipe(unsigned char *sha1, int fd, const char *type, int write_object)
{
- unsigned long size = 4096;
- char *buf = xmalloc(size);
+ unsigned long size;
+ char *buf;
int ret;
- if (read_pipe(fd, &buf, &size)) {
- free(buf);
+ if (read_fd(fd, &buf, &size))
return -1;
- }
if (!type)
type = blob_type;
diff --git a/t/t7800-commit.sh b/t/t7800-commit.sh
new file mode 100644
index 0000000..1f97caa
--- /dev/null
+++ b/t/t7800-commit.sh
@@ -0,0 +1,126 @@
+#!/bin/sh
+#
+# Copyright (c) 2007 Kristian Høgsberg <krh@redhat.com>
+#
+
+# FIXME: Test the various index usages, -i and -o, test reflog,
+# signoff, hooks
+
+test_description='git-commit'
+. ./test-lib.sh
+
+# Pick a date so we get consistent commits. 7/7/07 means good luck!
+export GIT_AUTHOR_DATE="July 7, 2007"
+export GIT_COMMITTER_DATE="July 7, 2007"
+
+echo "bongo bongo" >file
+test_expect_success \
+ "initial status" \
+ "git-add file && \
+ git-status | grep 'Initial commit'"
+
+test_expect_failure \
+ "fail initial amend" \
+ "git-commit -m initial --amend"
+
+test_expect_success \
+ "initial commit" \
+ "git-commit -m initial"
+
+test_expect_failure \
+ "testing nothing to commit" \
+ "git-commit -m initial"
+
+echo "bongo bongo bongo" >file
+
+test_expect_success \
+ "next commit" \
+ "git-commit -m next -a"
+
+echo "more bongo: bongo bongo bongo bongo" >file
+
+test_expect_failure \
+ "commit message from non-existing file" \
+ "git-commit -F gah -a"
+
+cat >msg <<EOF
+
+
+
+Signed-off-by: hula
+EOF
+test_expect_failure \
+ "empty commit message" \
+ "git-commit -F msg -a"
+
+echo "this is the commit message, coming from a file" >msg
+test_expect_success \
+ "commit message from file" \
+ "git-commit -F msg -a"
+
+cat >editor <<\EOF
+#!/bin/sh
+sed -i -e "s/a file/an amend commit/g" $1
+EOF
+chmod 755 editor
+
+test_expect_success \
+ "amend commit" \
+ "VISUAL=./editor git-commit --amend"
+
+echo "enough with the bongos" >file
+test_expect_failure \
+ "passing --amend and -F" \
+ "git-commit -F msg --amend ."
+
+test_expect_success \
+ "using message from other commit" \
+ "git-commit -C HEAD^ ."
+
+cat >editor <<\EOF
+#!/bin/sh
+sed -i -e "s/amend/older/g" $1
+EOF
+chmod 755 editor
+
+echo "hula hula" >file
+test_expect_success \
+ "editing message from other commit" \
+ "VISUAL=./editor git-commit -c HEAD^ -a"
+
+echo "silly new contents" >file
+test_expect_success \
+ "message from stdin" \
+ "echo commit message from stdin | git-commit -F - -a"
+
+echo "gak" >file
+test_expect_success \
+ "overriding author from command line" \
+ "git-commit -m 'author' --author 'Rubber Duck <rduck@convoy.org>' -a"
+
+test_expect_success \
+ "interactive add" \
+ "echo 7 | git-commit --interactive | grep 'What now'"
+
+test_expect_success \
+ "showing committed revisions" \
+ "git-rev-list HEAD >current"
+
+# We could just check the head sha1, but checking each commit makes it
+# easier to isolate bugs.
+
+cat >expected <<\EOF
+9a7ad90c32f43aecc081722a72f26ead981bd6fa
+d5c6c34f0361d64d3d1b1f26736b1ae98e2baa90
+ca0ddb06fc90f3f857dd623f8418804aad75d9fa
+9cc5d9b9e5a29f1c46d0d0cf2dd716fb8241316a
+ca750e97c137587aa181b6b9526b3b04fb9db667
+4515202a60be41cb1b8f6b89edb3f6948130ac1c
+7cc9a125522fe28b84cd3f6c7aeef6e5c62b3f8b
+EOF
+
+test_expect_success \
+ 'validate git-rev-list output.' \
+ 'diff current expected'
+
+test_done
diff --git a/wt-status.c b/wt-status.c
index 5205420..5bf800a 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -54,29 +54,30 @@ void wt_status_prepare(struct wt_status *s)
s->reference = "HEAD";
}
-static void wt_status_print_cached_header(const char *reference)
+static void wt_status_print_cached_header(struct wt_status *s)
{
const char *c = color(WT_STATUS_HEADER);
- color_printf_ln(c, "# Changes to be committed:");
- if (reference) {
- color_printf_ln(c, "# (use \"git reset %s <file>...\" to unstage)", reference);
+ color_fprintf_ln(s->fp, c, "# Changes to be committed:");
+ if (s->reference) {
+ color_fprintf_ln(s->fp, c, "# (use \"git reset %s <file>...\" to unstage)", s->reference);
} else {
- color_printf_ln(c, "# (use \"git rm --cached <file>...\" to unstage)");
+ color_fprintf_ln(s->fp, c, "# (use \"git rm --cached <file>...\" to unstage)");
}
- color_printf_ln(c, "#");
+ color_fprintf_ln(s->fp, c, "#");
}
-static void wt_status_print_header(const char *main, const char *sub)
+static void wt_status_print_header(struct wt_status *s,
+ const char *main, const char *sub)
{
const char *c = color(WT_STATUS_HEADER);
- color_printf_ln(c, "# %s:", main);
- color_printf_ln(c, "# (%s)", sub);
- color_printf_ln(c, "#");
+ color_fprintf_ln(s->fp, c, "# %s:", main);
+ color_fprintf_ln(s->fp, c, "# (%s)", sub);
+ color_fprintf_ln(s->fp, c, "#");
}
-static void wt_status_print_trailer(void)
+static void wt_status_print_trailer(struct wt_status *s)
{
- color_printf_ln(color(WT_STATUS_HEADER), "#");
+ color_fprintf_ln(s->fp, color(WT_STATUS_HEADER), "#");
}
static const char *quote_crlf(const char *in, char *buf, size_t sz)
@@ -108,7 +109,8 @@ static const char *quote_crlf(const char *in, char *buf, size_t sz)
return ret;
}
-static void wt_status_print_filepair(int t, struct diff_filepair *p)
+static void wt_status_print_filepair(struct wt_status *s,
+ int t, struct diff_filepair *p)
{
const char *c = color(t);
const char *one, *two;
@@ -117,36 +119,36 @@ static void wt_status_print_filepair(int t, struct diff_filepair *p)
one = quote_crlf(p->one->path, onebuf, sizeof(onebuf));
two = quote_crlf(p->two->path, twobuf, sizeof(twobuf));
- color_printf(color(WT_STATUS_HEADER), "#\t");
+ color_fprintf(s->fp, color(WT_STATUS_HEADER), "#\t");
switch (p->status) {
case DIFF_STATUS_ADDED:
- color_printf(c, "new file: %s", one);
+ color_fprintf(s->fp, c, "new file: %s", one);
break;
case DIFF_STATUS_COPIED:
- color_printf(c, "copied: %s -> %s", one, two);
+ color_fprintf(s->fp, c, "copied: %s -> %s", one, two);
break;
case DIFF_STATUS_DELETED:
- color_printf(c, "deleted: %s", one);
+ color_fprintf(s->fp, c, "deleted: %s", one);
break;
case DIFF_STATUS_MODIFIED:
- color_printf(c, "modified: %s", one);
+ color_fprintf(s->fp, c, "modified: %s", one);
break;
case DIFF_STATUS_RENAMED:
- color_printf(c, "renamed: %s -> %s", one, two);
+ color_fprintf(s->fp, c, "renamed: %s -> %s", one, two);
break;
case DIFF_STATUS_TYPE_CHANGED:
- color_printf(c, "typechange: %s", one);
+ color_fprintf(s->fp, c, "typechange: %s", one);
break;
case DIFF_STATUS_UNKNOWN:
- color_printf(c, "unknown: %s", one);
+ color_fprintf(s->fp, c, "unknown: %s", one);
break;
case DIFF_STATUS_UNMERGED:
- color_printf(c, "unmerged: %s", one);
+ color_fprintf(s->fp, c, "unmerged: %s", one);
break;
default:
die("bug: unhandled diff status %c", p->status);
}
- printf("\n");
+ fprintf(s->fp, "\n");
}
static void wt_status_print_updated_cb(struct diff_queue_struct *q,
@@ -160,14 +162,14 @@ static void wt_status_print_updated_cb(struct diff_queue_struct *q,
if (q->queue[i]->status == 'U')
continue;
if (!shown_header) {
- wt_status_print_cached_header(s->reference);
+ wt_status_print_cached_header(s);
s->commitable = 1;
shown_header = 1;
}
- wt_status_print_filepair(WT_STATUS_UPDATED, q->queue[i]);
+ wt_status_print_filepair(s, WT_STATUS_UPDATED, q->queue[i]);
}
if (shown_header)
- wt_status_print_trailer();
+ wt_status_print_trailer(s);
}
static void wt_status_print_changed_cb(struct diff_queue_struct *q,
@@ -184,18 +186,18 @@ static void wt_status_print_changed_cb(struct diff_queue_struct *q,
msg = use_add_rm_msg;
break;
}
- wt_status_print_header("Changed but not updated", msg);
+ wt_status_print_header(s, "Changed but not updated", msg);
}
for (i = 0; i < q->nr; i++)
- wt_status_print_filepair(WT_STATUS_CHANGED, q->queue[i]);
+ wt_status_print_filepair(s, WT_STATUS_CHANGED, q->queue[i]);
if (q->nr)
- wt_status_print_trailer();
+ wt_status_print_trailer(s);
}
static void wt_read_cache(struct wt_status *s)
{
discard_cache();
- read_cache();
+ read_cache_from(s->index_file);
}
static void wt_status_print_initial(struct wt_status *s)
@@ -206,16 +208,16 @@ static void wt_status_print_initial(struct wt_status *s)
wt_read_cache(s);
if (active_nr) {
s->commitable = 1;
- wt_status_print_cached_header(NULL);
+ wt_status_print_cached_header(s);
}
for (i = 0; i < active_nr; i++) {
- color_printf(color(WT_STATUS_HEADER), "#\t");
- color_printf_ln(color(WT_STATUS_UPDATED), "new file: %s",
+ color_fprintf(s->fp, color(WT_STATUS_HEADER), "#\t");
+ color_fprintf_ln(s->fp, color(WT_STATUS_UPDATED), "new file: %s",
quote_crlf(active_cache[i]->name,
buf, sizeof(buf)));
}
if (active_nr)
- wt_status_print_trailer();
+ wt_status_print_trailer(s);
}
static void wt_status_print_updated(struct wt_status *s)
@@ -281,12 +283,12 @@ static void wt_status_print_untracked(struct wt_status *s)
}
if (!shown_header) {
s->workdir_untracked = 1;
- wt_status_print_header("Untracked files",
+ wt_status_print_header(s, "Untracked files",
use_add_to_include_msg);
shown_header = 1;
}
- color_printf(color(WT_STATUS_HEADER), "#\t");
- color_printf_ln(color(WT_STATUS_UNTRACKED), "%.*s",
+ color_fprintf(s->fp, color(WT_STATUS_HEADER), "#\t");
+ color_fprintf_ln(s->fp, color(WT_STATUS_UNTRACKED), "%.*s",
ent->len, ent->name);
}
}
@@ -316,14 +318,14 @@ void wt_status_print(struct wt_status *s)
branch_name = "";
on_what = "Not currently on any branch.";
}
- color_printf_ln(color(WT_STATUS_HEADER),
+ color_fprintf_ln(s->fp, color(WT_STATUS_HEADER),
"# %s%s", on_what, branch_name);
}
if (s->is_initial) {
- color_printf_ln(color(WT_STATUS_HEADER), "#");
- color_printf_ln(color(WT_STATUS_HEADER), "# Initial commit");
- color_printf_ln(color(WT_STATUS_HEADER), "#");
+ color_fprintf_ln(s->fp, color(WT_STATUS_HEADER), "#");
+ color_fprintf_ln(s->fp, color(WT_STATUS_HEADER), "# Initial commit");
+ color_fprintf_ln(s->fp, color(WT_STATUS_HEADER), "#");
wt_status_print_initial(s);
}
else {
@@ -337,7 +339,7 @@ void wt_status_print(struct wt_status *s)
wt_status_print_verbose(s);
if (!s->commitable) {
if (s->amend)
- printf("# No changes\n");
+ fprintf(s->fp, "# No changes\n");
else if (s->workdir_dirty)
printf("no changes added to commit (use \"git add\" and/or \"git commit -a\")\n");
else if (s->workdir_untracked)
diff --git a/wt-status.h b/wt-status.h
index cfea4ae..7744932 100644
--- a/wt-status.h
+++ b/wt-status.h
@@ -1,6 +1,8 @@
#ifndef STATUS_H
#define STATUS_H
+#include <stdio.h>
+
enum color_wt_status {
WT_STATUS_HEADER,
WT_STATUS_UPDATED,
@@ -19,6 +21,8 @@ struct wt_status {
int commitable;
int workdir_dirty;
int workdir_untracked;
+ const char *index_file;
+ FILE *fp;
};
int git_status_config(const char *var, const char *value);
--
1.5.2.GIT
^ permalink raw reply related [relevance 1%]
* Re: index-pack died on pread
@ 2007-07-25 23:15 2% ` Robin Rosenberg
0 siblings, 0 replies; 200+ results
From: Robin Rosenberg @ 2007-07-25 23:15 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Michal Rokos, GIT
måndag 23 juli 2007 skrev Linus Torvalds:
>
> On Mon, 23 Jul 2007, Michal Rokos wrote:
> >
> > fatal: cannot pread pack file: No such file or directory (n=0,
> > errno=2, fd=3, ptr=40452958, len=428, rdy=0, off=123601)
>
> Ok, that's bogus. When "n" is zero, the errno (and thus the error string)
> is not changed by pread, so that's a very misleading error report.
>
> So what seems to have happened is that the pack-file is too short, so we
> got a return value of 0, and then reported it as if it had an errno.
>
> The reason for returning zero from pread would be:
>
> - broken pread. I don't think HPUX should be a problem, so that's
> probably not it.
>
> - the pack-file got truncated
>
> - the offset is corrupt, and points to beyond the size of the packfile.
>
> In this case, since the offset is just 123601, I suspect it's a truncation
> issue, and your pack-file is simply corrupt. Either because of some
> problem with receiving it, or because of problems on the remote side.
>
> > fetch-pack from 'git://git.kernel.org/pub/scm/git/git' failed.
>
> One thing to look out for is that the "git.kernel.org" machines aren't the
> "primary" ones, and the data gets mirrored from other machines. If the
> mirroring is incomplete, I could imagine that the remote side simply ended
> up terminating the connection, and you ended up with a partial pack-file.
>
> Some of the kernel.org machines ran out of disk space the other day, so
> maybe you happened to hit it in an unlucky window. Does it still happen?
Does cygwin have the same pread problem then.. ? after make NO_PREAD=1 with 1.5.2.4
clone works.
Here is my output with pread. Note that I'm cloning from or.cz, not kernel.org .
$ git clone git://repo.or.cz/git.git GIT
Initialized empty Git repository in /roro/GIT/.git/
remote: Generating pack...
remote: Done counting 56038 objects.
remote: Deltifying 56038 objects...
remote: 100% (56038/56038) done
Indexing 56038 objects...
remote: Total 56038 (delta 39190), reused 52555 (delta 36164)
100% (56038/56038) done
Resolving 39190 deltas...
fatal: cannot pread pack file: No such file or directory
fatal: index-pack died with error code 128
fetch-pack from 'git://repo.or.cz/git.git' failed.
-- robin
^ permalink raw reply [relevance 2%]
* Re: People unaware of the importance of "git gc"?
@ 2007-09-05 21:07 3% ` Alex Riesen
0 siblings, 0 replies; 200+ results
From: Alex Riesen @ 2007-09-05 21:07 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Git Mailing List
Linus Torvalds, Wed, Sep 05, 2007 09:09:27 +0200:
> I personally repack everything way more often than is necessary, and I had
> kind of assumed that people did it that way, but I was apparently wrong.
> Comments?
I do it from time to time. Seldom in working repositories, because
they usually come and go before they have a chance to accumulate
enough of loose objects. I do a partial repack (git repack -d) after
every import from p4 repo, because every snapshot of it is an ugly
mess changing files all over the tree. Sometimes, after I merged a big
chunk with the p4 repo and sent it over (the process involves rebase).
It is usually concious decision when to do a repack or gc. The repack
time is seldom a problem: it is fast enough even on windows (and I do
have big repos and binary objects). The gc causes my machines to swap,
though. Some of them heavily, so there my repos stay longer partially
packed. I do use .keep packs for this reason (and because windows or
cygwin or both have more problems with big files the they have with
small).
I used to clone repos with "-s", but quickly stopped after a few
broken histories. This also tought me to think before running
"git gc" or "git repack -a -d".
On a rare occurance I even use "git repack -a -d -l" and "git
pack-refs" separately.
This was all specific to my day-job. At home, on linux systems I just
run git-gc whenever I please, without even thinking why. It finishes
mostly in less than a minute (the kernel: ~40-50 sec on my P4 2.6GHz, 1Gb).
^ permalink raw reply [relevance 3%]
* [PATCH 9/9] Implement git commit as a builtin command.
@ 2007-09-06 0:23 2% ` Kristian Høgsberg
0 siblings, 0 replies; 200+ results
From: Kristian Høgsberg @ 2007-09-06 0:23 UTC (permalink / raw)
To: git; +Cc: Kristian Høgsberg
Move git-commit.sh to contrib/examples.
Signed-off-by: Kristian Høgsberg <krh@redhat.com>
---
Makefile | 9 +-
builtin-commit.c | 742 ++++++++++++++++++++++++++++++++++++++++
builtin.h | 3 +-
contrib/examples/git-commit.sh | 665 +++++++++++++++++++++++++++++++++++
git-commit.sh | 665 -----------------------------------
git.c | 3 +-
6 files changed, 1414 insertions(+), 673 deletions(-)
create mode 100644 builtin-commit.c
create mode 100755 contrib/examples/git-commit.sh
delete mode 100755 git-commit.sh
diff --git a/Makefile b/Makefile
index 4eb4637..beb3cbb 100644
--- a/Makefile
+++ b/Makefile
@@ -201,7 +201,7 @@ BASIC_LDFLAGS =
SCRIPT_SH = \
git-bisect.sh git-checkout.sh \
- git-clean.sh git-clone.sh git-commit.sh \
+ git-clean.sh git-clone.sh \
git-fetch.sh \
git-ls-remote.sh \
git-merge-one-file.sh git-mergetool.sh git-parse-remote.sh \
@@ -250,7 +250,7 @@ EXTRA_PROGRAMS =
BUILT_INS = \
git-format-patch$X git-show$X git-whatchanged$X git-cherry$X \
git-get-tar-commit-id$X git-init$X git-repo-config$X \
- git-fsck-objects$X git-cherry-pick$X \
+ git-fsck-objects$X git-cherry-pick$X git-status$X\
$(patsubst builtin-%.o,git-%$X,$(BUILTIN_OBJS))
# what 'all' will build and 'install' will install, in gitexecdir
@@ -322,6 +322,7 @@ BUILTIN_OBJS = \
builtin-check-attr.o \
builtin-checkout-index.o \
builtin-check-ref-format.o \
+ builtin-commit.o \
builtin-commit-tree.o \
builtin-count-objects.o \
builtin-describe.o \
@@ -357,7 +358,6 @@ BUILTIN_OBJS = \
builtin-rev-parse.o \
builtin-revert.o \
builtin-rm.o \
- builtin-runstatus.o \
builtin-shortlog.o \
builtin-show-branch.o \
builtin-stripspace.o \
@@ -797,9 +797,6 @@ $(patsubst %.perl,%,$(SCRIPT_PERL)): % : %.perl
chmod +x $@+ && \
mv $@+ $@
-git-status: git-commit
- $(QUIET_GEN)cp $< $@+ && mv $@+ $@
-
gitweb/gitweb.cgi: gitweb/gitweb.perl
$(QUIET_GEN)$(RM) $@ $@+ && \
sed -e '1s|#!.*perl|#!$(PERL_PATH_SQ)|' \
diff --git a/builtin-commit.c b/builtin-commit.c
new file mode 100644
index 0000000..aca5ff8
--- /dev/null
+++ b/builtin-commit.c
@@ -0,0 +1,742 @@
+/*
+ * Builtin "git commit"
+ *
+ * Copyright (c) 2007 Kristian Høgsberg <krh@redhat.com>
+ * Based on git-commit.sh by Junio C Hamano and Linus Torvalds
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "cache.h"
+#include "cache-tree.h"
+#include "builtin.h"
+#include "diff.h"
+#include "diffcore.h"
+#include "commit.h"
+#include "revision.h"
+#include "wt-status.h"
+#include "run-command.h"
+#include "refs.h"
+#include "log-tree.h"
+#include "strbuf.h"
+#include "utf8.h"
+
+void launch_editor(const char *path, struct strbuf *sb);
+int rerere(void);
+
+static const char builtin_commit_usage[] =
+ "[-a | --interactive] [-s] [-v] [--no-verify] [-m <message> | -F <logfile> | (-C|-c) <commit> | --amend] [-u] [-e] [--author <author>] [--template <file>] [[-i | -o] <path>...]";
+
+static unsigned char head_sha1[20], merge_head_sha1[20];
+static char *use_message_buffer;
+static const char commit_editmsg[] = "COMMIT_EDITMSG";
+static struct lock_file lock_file;
+
+enum option_type {
+ OPTION_NONE,
+ OPTION_STRING,
+ OPTION_INTEGER,
+ OPTION_LAST,
+};
+
+struct option {
+ enum option_type type;
+ const char *long_name;
+ char short_name;
+ void *value;
+};
+
+static int scan_options(const char ***argv, struct option *options)
+{
+ const char *value, *eq;
+ int i;
+
+ if (**argv == NULL)
+ return 0;
+ if ((**argv)[0] != '-')
+ return 0;
+ if (!strcmp(**argv, "--"))
+ return 0;
+
+ value = NULL;
+ for (i = 0; options[i].type != OPTION_LAST; i++) {
+ if ((**argv)[1] == '-') {
+ if (!prefixcmp(options[i].long_name, **argv + 2)) {
+ if (options[i].type != OPTION_NONE)
+ value = *++(*argv);
+ goto match;
+ }
+
+ eq = strchr(**argv + 2, '=');
+ if (eq && options[i].type != OPTION_NONE &&
+ !strncmp(**argv + 2,
+ options[i].long_name, eq - **argv - 2)) {
+ value = eq + 1;
+ goto match;
+ }
+ }
+
+ if ((**argv)[1] == options[i].short_name) {
+ if ((**argv)[2] == '\0') {
+ if (options[i].type != OPTION_NONE)
+ value = *++(*argv);
+ goto match;
+ }
+
+ if (options[i].type != OPTION_NONE) {
+ value = **argv + 2;
+ goto match;
+ }
+ }
+ }
+
+ usage(builtin_commit_usage);
+
+ match:
+ switch (options[i].type) {
+ case OPTION_NONE:
+ *(int *)options[i].value = 1;
+ break;
+ case OPTION_STRING:
+ if (value == NULL)
+ die("option %s requires a value.", (*argv)[-1]);
+ *(const char **)options[i].value = value;
+ break;
+ case OPTION_INTEGER:
+ if (value == NULL)
+ die("option %s requires a value.", (*argv)[-1]);
+ *(int *)options[i].value = atoi(value);
+ break;
+ default:
+ assert(0);
+ }
+
+ (*argv)++;
+
+ return 1;
+}
+
+static char *logfile, *force_author, *message, *template_file;
+static char *edit_message, *use_message;
+static int all, edit_flag, also, interactive, only, no_verify, amend, signoff;
+static int quiet, verbose, untracked_files;
+
+static int no_edit, initial_commit, in_merge;
+const char *only_include_assumed;
+
+static struct option commit_options[] = {
+ { OPTION_STRING, "file", 'F', (void *) &logfile },
+ { OPTION_NONE, "all", 'a', &all },
+ { OPTION_STRING, "author", 0, (void *) &force_author },
+ { OPTION_NONE, "edit", 'e', &edit_flag },
+ { OPTION_NONE, "include", 'i', &also },
+ { OPTION_NONE, "interactive", 0, &interactive },
+ { OPTION_NONE, "only", 'o', &only },
+ { OPTION_STRING, "message", 'm', &message },
+ { OPTION_NONE, "no-verify", 'n', &no_verify },
+ { OPTION_NONE, "amend", 0, &amend },
+ { OPTION_STRING, "reedit-message", 'c', &edit_message },
+ { OPTION_STRING, "reuse-message", 'C', &use_message },
+ { OPTION_NONE, "signoff", 's', &signoff },
+ { OPTION_NONE, "quiet", 'q', &quiet },
+ { OPTION_NONE, "verbose", 'v', &verbose },
+ { OPTION_NONE, "untracked-files", 0, &untracked_files },
+ { OPTION_STRING, "template", 't', &template_file },
+ { OPTION_LAST },
+};
+
+/* FIXME: Taken from builtin-add, should be shared. */
+
+static void update_callback(struct diff_queue_struct *q,
+ struct diff_options *opt, void *cbdata)
+{
+ int i, verbose;
+
+ verbose = *((int *)cbdata);
+ for (i = 0; i < q->nr; i++) {
+ struct diff_filepair *p = q->queue[i];
+ const char *path = p->one->path;
+ switch (p->status) {
+ default:
+ die("unexpacted diff status %c", p->status);
+ case DIFF_STATUS_UNMERGED:
+ case DIFF_STATUS_MODIFIED:
+ case DIFF_STATUS_TYPE_CHANGED:
+ add_file_to_cache(path, verbose);
+ break;
+ case DIFF_STATUS_DELETED:
+ remove_file_from_cache(path);
+ cache_tree_invalidate_path(active_cache_tree, path);
+ if (verbose)
+ printf("remove '%s'\n", path);
+ break;
+ }
+ }
+}
+
+static void
+add_files_to_cache(int fd, const char **files, const char *prefix)
+{
+ struct rev_info rev;
+
+ init_revisions(&rev, "");
+ setup_revisions(0, NULL, &rev, NULL);
+ rev.prune_data = get_pathspec(prefix, files);
+ rev.diffopt.output_format |= DIFF_FORMAT_CALLBACK;
+ rev.diffopt.format_callback = update_callback;
+ rev.diffopt.format_callback_data = &verbose;
+
+ run_diff_files(&rev, 0);
+ refresh_cache(REFRESH_QUIET);
+
+ if (write_cache(fd, active_cache, active_nr) || close(fd))
+ die("unable to write new index file");
+}
+
+static char *
+prepare_index(const char **files, const char *prefix)
+{
+ int fd;
+ struct tree *tree;
+ struct lock_file *next_index_lock;
+
+ fd = hold_locked_index(&lock_file, 1);
+ if (read_cache() < 0)
+ die("index file corrupt");
+
+ if (all) {
+ add_files_to_cache(fd, files, NULL);
+ return lock_file.filename;
+ } else if (also) {
+ add_files_to_cache(fd, files, prefix);
+ return lock_file.filename;
+ }
+
+ if (interactive)
+ interactive_add();
+
+ if (*files == NULL) {
+ /* Commit index as-is. */
+ rollback_lock_file(&lock_file);
+ return get_index_file();
+ }
+
+ /*
+ * FIXME: Warn on unknown files. Shell script does
+ *
+ * commit_only=`git-ls-files --error-unmatch -- "$@"`
+ */
+
+ /*
+ * FIXME: shell script does
+ *
+ * git-read-tree --index-output="$TMP_INDEX" -i -m HEAD
+ *
+ * which warns about unmerged files in the index.
+ */
+
+ /* 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");
+ }
+
+ /* Uh oh, abusing lock_file to create a garbage collected file */
+ next_index_lock = xmalloc(sizeof(*next_index_lock));
+ fd = hold_lock_file_for_update(next_index_lock,
+ git_path("next-index-%d", getpid()), 1);
+ add_files_to_cache(fd, files, prefix);
+
+ return next_index_lock->filename;
+}
+
+static int run_status(FILE *fp, const char *index_file)
+{
+ struct wt_status s;
+
+ wt_status_prepare(&s);
+
+ if (amend) {
+ s.amend = 1;
+ s.reference = "HEAD^1";
+ }
+ s.verbose = verbose;
+ s.untracked = untracked_files;
+ s.index_file = index_file;
+ s.fp = fp;
+
+ wt_status_print(&s);
+
+ return s.commitable;
+}
+
+static const char sign_off_header[] = "Signed-off-by: ";
+
+static int prepare_log_message(const char *index_file)
+{
+ struct stat statbuf;
+ int commitable;
+ struct strbuf sb;
+ char *buffer;
+ FILE *fp;
+
+ strbuf_init(&sb);
+ if (message) {
+ strbuf_add(&sb, message, strlen(message));
+ } else if (logfile && !strcmp(logfile, "-")) {
+ if (isatty(0))
+ fprintf(stderr, "(reading log message from standard input)\n");
+ if (strbuf_read_fd(&sb, 0) < 0)
+ die("could not read log from standard input");
+ } else if (logfile) {
+ if (strbuf_read_path(&sb, logfile) < 0)
+ die("could not read log file '%s': %s",
+ logfile, strerror(errno));
+ } else if (use_message) {
+ buffer = strstr(use_message_buffer, "\n\n");
+ if (!buffer || buffer[2] == '\0')
+ die("commit has empty message");
+ strbuf_add(&sb, buffer + 2, strlen(buffer + 2));
+ } else if (!stat(git_path("MERGE_MSG"), &statbuf)) {
+ if (strbuf_read_path(&sb, git_path("MERGE_MSG")) < 0)
+ die("could not read MERGE_MSG: %s", strerror(errno));
+ } else if (!stat(git_path("SQUASH_MSG"), &statbuf)) {
+ if (strbuf_read_path(&sb, git_path("SQUASH_MSG")) < 0)
+ die("could not read SQUASH_MSG: %s", strerror(errno));
+ } else if (!stat(template_file, &statbuf)) {
+ if (strbuf_read_path(&sb, template_file) < 0)
+ die("could not read %s: %s",
+ template_file, strerror(errno));
+ }
+
+ fp = fopen(git_path(commit_editmsg), "w");
+ if (fp == NULL)
+ die("could not open %s\n", git_path(commit_editmsg));
+
+ stripspace(&sb, 0);
+ if (fwrite(sb.buf, 1, sb.len, fp) < sb.len)
+ die("could not write commit template: %s\n",
+ strerror(errno));
+
+ if (signoff) {
+ const char *info, *bol;
+
+ info = git_committer_info(1);
+ strbuf_add_char(&sb, '\0');
+ bol = strrchr(sb.buf + sb.len - 1, '\n');
+ if (!bol || prefixcmp(bol, sign_off_header))
+ fprintf(fp, "\n");
+ fprintf(fp, "Signed-off-by: %s\n", git_committer_info(1));
+ }
+
+ strbuf_release(&sb);
+
+ if (in_merge && !no_edit) {
+ fprintf(fp,
+ "#\n"
+ "# It looks like you may be committing a MERGE.\n"
+ "# If this is not correct, please remove the file\n"
+ "# %s\n"
+ "# and try again.\n"
+ "#\n",
+ git_path("MERGE_HEAD"));
+ }
+
+ fprintf(fp,
+ "\n"
+ "# Please enter the commit message for your changes.\n"
+ "# (Comment lines starting with '#' will not be included)\n");
+ if (only_include_assumed)
+ fprintf(fp, "# %s\n", only_include_assumed);
+
+ commitable = run_status(fp, index_file);
+
+ fclose(fp);
+
+ return commitable;
+}
+
+/* Find out if the message starting at position 'start' in the strbuf
+ * contains only whitespace and Signed-off-by lines. */
+static int message_is_empty(struct strbuf *sb, int start)
+{
+ static const char signed_off_by[] = "Signed-off-by: ";
+ struct strbuf tmpl;
+ const char *nl;
+ int eol, i;
+
+ /* See if the template is just a prefix of the message. */
+ strbuf_init(&tmpl);
+ if (template_file && strbuf_read_path(&tmpl, template_file) > 0) {
+ stripspace(&tmpl, 1);
+ if (start + tmpl.len <= sb->len &&
+ memcmp(tmpl.buf, sb->buf + start, tmpl.len) == 0)
+ start += tmpl.len;
+ }
+ strbuf_release(&tmpl);
+
+ /* Check if the rest is just whitespace and Signed-of-by's. */
+ for (i = start; i < sb->len; i++) {
+ nl = memchr(sb->buf + i, '\n', sb->len - i);
+ if (nl)
+ eol = nl - sb->buf;
+ else
+ eol = sb->len;
+
+ if (strlen(signed_off_by) <= eol - i &&
+ !prefixcmp(sb->buf + i, signed_off_by)) {
+ i = eol;
+ continue;
+ }
+ while (i < eol)
+ if (!isspace(sb->buf[i++]))
+ return 0;
+ }
+
+ return 1;
+}
+
+static void determine_author_info(struct strbuf *sb)
+{
+ char *p, *eol;
+ char *name = NULL, *email = NULL;
+
+ if (use_message) {
+ p = strstr(use_message_buffer, "\nauthor");
+ if (!p)
+ die("invalid commit: %s\n", use_message);
+ p++;
+ eol = strchr(p, '\n');
+ if (!eol)
+ die("invalid commit: %s\n", use_message);
+
+ strbuf_add(sb, p, eol + 1 - p);
+ } else if (force_author) {
+ const char *eoname = strstr(force_author, " <");
+ const char *eomail = strchr(force_author, '>');
+
+ if (!eoname || !eomail)
+ die("malformed --author parameter\n");
+ name = xstrndup(force_author, eoname - force_author);
+ email = xstrndup(eoname + 2, eomail - eoname - 2);
+ strbuf_printf(sb, "author %s\n",
+ fmt_ident(name, email,
+ getenv("GIT_AUTHOR_DATE"), 1));
+ free(name);
+ free(email);
+ } else {
+ strbuf_printf(sb, "author %s\n", git_author_info(1));
+ }
+}
+
+static void parse_and_validate_options(const char ***argv)
+{
+ int f = 0;
+
+ (*argv)++;
+ while (scan_options(argv, commit_options))
+ ;
+
+ if (logfile || message || use_message)
+ no_edit = 1;
+ if (edit_flag)
+ no_edit = 0;
+
+ if (get_sha1("HEAD", head_sha1))
+ initial_commit = 1;
+
+ if (!get_sha1("MERGE_HEAD", merge_head_sha1))
+ in_merge = 1;
+
+ /* Sanity check options */
+ if (amend && initial_commit)
+ die("You have nothing to amend.");
+ if (amend && in_merge)
+ die("You are in the middle of a merger -- cannot amend.");
+
+ if (use_message)
+ f++;
+ if (edit_message)
+ f++;
+ if (logfile)
+ f++;
+ if (f > 1)
+ die("Only one of -c/-C/-F can be used.");
+ if (message && f > 0)
+ die("Option -m cannot be combined with -c/-C/-F.");
+ if (edit_message)
+ use_message = edit_message;
+ if (amend)
+ use_message = "HEAD";
+ if (use_message) {
+ unsigned char sha1[20];
+ static char utf8[] = "UTF-8";
+ char *enc, *end, *out_enc;
+ struct commit *commit;
+
+ if (get_sha1(use_message, sha1))
+ die("could not lookup commit %s", use_message);
+ commit = lookup_commit(sha1);
+ if (!commit || parse_commit(commit))
+ die("could not parse commit %s", use_message);
+
+ enc = strstr(commit->buffer, "\nencoding");
+ if (enc) {
+ end = strchr(enc + 10, '\n');
+ enc = xstrndup(enc + 10, end - (enc + 10));
+ } else {
+ enc = utf8;
+ }
+ out_enc = git_commit_encoding ? git_commit_encoding : utf8;
+
+ use_message_buffer =
+ reencode_string(commit->buffer, out_enc, enc);
+ if (enc != utf8)
+ free(enc);
+ }
+
+ if (also && only)
+ die("Only one of --include/--only can be used.");
+ if (!*argv && (also || (only && !amend)))
+ die("No paths with --include/--only does not make sense.");
+ if (!*argv && only && amend)
+ only_include_assumed = "Clever... amending the last one with dirty index.";
+ if (*argv && !also && !only) {
+ only_include_assumed = "Explicit paths specified without -i nor -o; assuming --only paths...";
+ also = 0;
+ }
+
+ if (all && interactive)
+ die("Cannot use -a, --interactive or -i at the same time.");
+ else if (all && **argv)
+ die("Paths with -a does not make sense.");
+ else if (interactive && **argv)
+ die("Paths with --interactive does not make sense.");
+}
+
+int cmd_status(int argc, const char **argv, const char *prefix)
+{
+ const char *index_file;
+ int commitable;
+
+ git_config(git_status_config);
+
+ parse_and_validate_options(&argv);
+
+ index_file = prepare_index(argv, prefix);
+
+ commitable = run_status(stdout, index_file);
+
+ rollback_lock_file(&lock_file);
+
+ return commitable ? 0 : 1;
+}
+
+static int run_hook(const char *index_file, const char *name, const char *arg)
+{
+ struct child_process hook;
+ const char *argv[3], *env[2];
+ char index[PATH_MAX];
+
+ argv[0] = git_path("hooks/%s", name);
+ argv[1] = arg;
+ argv[2] = NULL;
+ snprintf(index, sizeof(index), "GIT_INDEX_FILE=%s", index_file);
+ env[0] = index;
+ env[1] = NULL;
+
+ if (access(argv[0], X_OK) < 0)
+ return 0;
+
+ memset(&hook, 0, sizeof(hook));
+ hook.argv = argv;
+ hook.no_stdin = 1;
+ hook.stdout_to_stderr = 1;
+ hook.env = env;
+
+ return run_command(&hook);
+}
+
+static void print_summary(const char *prefix, const unsigned char *sha1)
+{
+ struct rev_info rev;
+ struct commit *commit;
+
+ commit = lookup_commit(sha1);
+ if (!commit)
+ die("couldn't look up newly created commit\n");
+ if (!commit || parse_commit(commit))
+ die("could not parse newly created commit");
+
+ init_revisions(&rev, prefix);
+ setup_revisions(0, NULL, &rev, NULL);
+
+ rev.abbrev = 0;
+ rev.diff = 1;
+ rev.diffopt.output_format =
+ DIFF_FORMAT_SHORTSTAT | DIFF_FORMAT_SUMMARY;
+
+ rev.verbose_header = 1;
+ rev.show_root_diff = 1;
+ rev.commit_format = get_commit_format("format:%h: %s");
+ rev.always_show_header = 1;
+
+ printf("Created %scommit ", initial_commit ? "initial " : "");
+
+ log_tree_commit(&rev, commit);
+}
+
+int git_commit_config(const char *k, const char *v)
+{
+ if (!strcmp(k, "commit.template")) {
+ template_file = xstrdup(v);
+ return 0;
+ }
+
+ return git_status_config(k, v);
+}
+
+static const char commit_utf8_warn[] =
+"Warning: commit message does not conform to UTF-8.\n"
+"You may want to amend it after fixing the message, or set the config\n"
+"variable i18n.commitencoding to the encoding your project uses.\n";
+
+int cmd_commit(int argc, const char **argv, const char *prefix)
+{
+ int header_len, parent_count = 0;
+ struct strbuf sb;
+ const char *index_file, *reflog_msg;
+ char *nl, *header_line;
+ unsigned char commit_sha1[20];
+ struct ref_lock *ref_lock;
+
+ git_config(git_commit_config);
+
+ parse_and_validate_options(&argv);
+
+ index_file = prepare_index(argv, prefix);
+
+ if (run_hook(index_file, "pre-commit", NULL))
+ exit(1);
+
+ if (!prepare_log_message(index_file)) {
+ run_status(stdout, index_file);
+ unlink(commit_editmsg);
+ return 1;
+ }
+
+ strbuf_init(&sb);
+
+ /* Start building up the commit header */
+ read_cache_from(index_file);
+ active_cache_tree = cache_tree();
+ if (cache_tree_update(active_cache_tree,
+ active_cache, active_nr, 0, 0) < 0)
+ die("Error building trees");
+ strbuf_printf(&sb, "tree %s\n",
+ sha1_to_hex(active_cache_tree->sha1));
+
+ /* Determine parents */
+ if (initial_commit) {
+ reflog_msg = "commit (initial)";
+ parent_count = 0;
+ } else if (amend) {
+ struct commit_list *c;
+ struct commit *commit;
+
+ reflog_msg = "commit (amend)";
+ commit = lookup_commit(head_sha1);
+ if (!commit || parse_commit(commit))
+ die("could not parse HEAD commit");
+
+ for (c = commit->parents; c; c = c->next)
+ strbuf_printf(&sb, "parent %s\n",
+ sha1_to_hex(c->item->object.sha1));
+ } else if (in_merge) {
+ struct strbuf m;
+ FILE *fp;
+
+ reflog_msg = "commit (merge)";
+ strbuf_printf(&sb, "parent %s\n", sha1_to_hex(head_sha1));
+ strbuf_init(&m);
+ fp = fopen(git_path("MERGE_HEAD"), "r");
+ if (fp == NULL)
+ die("could not open %s for reading: %s",
+ git_path("MERGE_HEAD"), strerror(errno));
+ while (!m.eof) {
+ read_line(&m, fp, '\n');
+ if (!m.eof)
+ strbuf_printf(&sb, "parent %s\n", m.buf);
+ }
+ fclose(fp);
+ strbuf_release(&m);
+ } else {
+ reflog_msg = "commit";
+ strbuf_printf(&sb, "parent %s\n", sha1_to_hex(head_sha1));
+ }
+
+ determine_author_info(&sb);
+ strbuf_printf(&sb, "committer %s\n", git_committer_info(1));
+ if (!is_encoding_utf8(git_commit_encoding))
+ strbuf_printf(&sb, "encoding %s\n", git_commit_encoding);
+ strbuf_add_char(&sb, '\n');
+
+ /* Get the commit message and validate it */
+ header_len = sb.len;
+ if (!no_edit) {
+ fprintf(stderr, "launching editor, log %s\n", logfile);
+ launch_editor(git_path(commit_editmsg), &sb);
+ }
+ else if (strbuf_read_path(&sb, git_path(commit_editmsg)) < 0)
+ die("could not read commit message\n");
+ if (run_hook(index_file, "commit-msg", commit_editmsg))
+ exit(1);
+ if (stripspace(&sb, 1) < header_len ||
+ message_is_empty(&sb, header_len))
+ die("* no commit message? aborting commit.");
+ strbuf_add_char(&sb, '\0');
+ if (is_encoding_utf8(git_commit_encoding) && !is_utf8(sb.buf))
+ fprintf(stderr, commit_utf8_warn);
+
+ if (write_sha1_file(sb.buf, sb.len - 1, commit_type, commit_sha1))
+ die("failed to write commit object");
+
+ ref_lock = lock_any_ref_for_update("HEAD",
+ initial_commit ? NULL : head_sha1,
+ 0);
+
+ nl = strchr(sb.buf + header_len, '\n');
+ header_line = xstrndup(sb.buf + header_len,
+ nl - (sb.buf + header_len));
+ strbuf_release(&sb);
+ strbuf_printf(&sb, "%s: %s\n", reflog_msg, header_line);
+ strbuf_add_char(&sb, '\0');
+ free(header_line);
+
+ if (!ref_lock)
+ die("cannot lock HEAD ref");
+ if (write_ref_sha1(ref_lock, commit_sha1, sb.buf) < 0)
+ die("cannot update HEAD ref");
+
+ unlink(git_path("MERGE_HEAD"));
+ unlink(git_path("MERGE_MSG"));
+
+ if (lock_file.filename[0] && commit_locked_index(&lock_file))
+ die("failed to write new index");
+
+ rerere();
+
+ run_hook(index_file, "post-commit", NULL);
+
+ if (!quiet)
+ print_summary(prefix, commit_sha1);
+
+ return 0;
+}
diff --git a/builtin.h b/builtin.h
index 91bc595..c23cd6d 100644
--- a/builtin.h
+++ b/builtin.h
@@ -23,6 +23,7 @@ extern int cmd_check_attr(int argc, const char **argv, const char *prefix);
extern int cmd_check_ref_format(int argc, const char **argv, const char *prefix);
extern int cmd_cherry(int argc, const char **argv, const char *prefix);
extern int cmd_cherry_pick(int argc, const char **argv, const char *prefix);
+extern int cmd_commit(int argc, const char **argv, const char *prefix);
extern int cmd_commit_tree(int argc, const char **argv, const char *prefix);
extern int cmd_count_objects(int argc, const char **argv, const char *prefix);
extern int cmd_describe(int argc, const char **argv, const char *prefix);
@@ -63,10 +64,10 @@ extern int cmd_rev_list(int argc, const char **argv, const char *prefix);
extern int cmd_rev_parse(int argc, const char **argv, const char *prefix);
extern int cmd_revert(int argc, const char **argv, const char *prefix);
extern int cmd_rm(int argc, const char **argv, const char *prefix);
-extern int cmd_runstatus(int argc, const char **argv, const char *prefix);
extern int cmd_shortlog(int argc, const char **argv, const char *prefix);
extern int cmd_show(int argc, const char **argv, const char *prefix);
extern int cmd_show_branch(int argc, const char **argv, const char *prefix);
+extern int cmd_status(int argc, const char **argv, const char *prefix);
extern int cmd_stripspace(int argc, const char **argv, const char *prefix);
extern int cmd_symbolic_ref(int argc, const char **argv, const char *prefix);
extern int cmd_tag(int argc, const char **argv, const char *prefix);
diff --git a/contrib/examples/git-commit.sh b/contrib/examples/git-commit.sh
new file mode 100755
index 0000000..d7e7028
--- /dev/null
+++ b/contrib/examples/git-commit.sh
@@ -0,0 +1,665 @@
+#!/bin/sh
+#
+# Copyright (c) 2005 Linus Torvalds
+# Copyright (c) 2006 Junio C Hamano
+
+USAGE='[-a | --interactive] [-s] [-v] [--no-verify] [-m <message> | -F <logfile> | (-C|-c) <commit> | --amend] [-u] [-e] [--author <author>] [--template <file>] [[-i | -o] <path>...]'
+SUBDIRECTORY_OK=Yes
+. git-sh-setup
+require_work_tree
+
+git rev-parse --verify HEAD >/dev/null 2>&1 || initial_commit=t
+
+case "$0" in
+*status)
+ status_only=t
+ ;;
+*commit)
+ status_only=
+ ;;
+esac
+
+refuse_partial () {
+ echo >&2 "$1"
+ echo >&2 "You might have meant to say 'git commit -i paths...', perhaps?"
+ exit 1
+}
+
+THIS_INDEX="$GIT_DIR/index"
+NEXT_INDEX="$GIT_DIR/next-index$$"
+rm -f "$NEXT_INDEX"
+save_index () {
+ cp -p "$THIS_INDEX" "$NEXT_INDEX"
+}
+
+run_status () {
+ # If TMP_INDEX is defined, that means we are doing
+ # "--only" partial commit, and that index file is used
+ # to build the tree for the commit. Otherwise, if
+ # NEXT_INDEX exists, that is the index file used to
+ # make the commit. Otherwise we are using as-is commit
+ # so the regular index file is what we use to compare.
+ if test '' != "$TMP_INDEX"
+ then
+ GIT_INDEX_FILE="$TMP_INDEX"
+ export GIT_INDEX_FILE
+ elif test -f "$NEXT_INDEX"
+ then
+ GIT_INDEX_FILE="$NEXT_INDEX"
+ export GIT_INDEX_FILE
+ fi
+
+ case "$status_only" in
+ t) color= ;;
+ *) color=--nocolor ;;
+ esac
+ git runstatus ${color} \
+ ${verbose:+--verbose} \
+ ${amend:+--amend} \
+ ${untracked_files:+--untracked}
+}
+
+trap '
+ test -z "$TMP_INDEX" || {
+ test -f "$TMP_INDEX" && rm -f "$TMP_INDEX"
+ }
+ rm -f "$NEXT_INDEX"
+' 0
+
+################################################################
+# Command line argument parsing and sanity checking
+
+all=
+also=
+interactive=
+only=
+logfile=
+use_commit=
+amend=
+edit_flag=
+no_edit=
+log_given=
+log_message=
+verify=t
+quiet=
+verbose=
+signoff=
+force_author=
+only_include_assumed=
+untracked_files=
+templatefile="`git config commit.template`"
+while case "$#" in 0) break;; esac
+do
+ case "$1" in
+ -F|--F|-f|--f|--fi|--fil|--file)
+ case "$#" in 1) usage ;; esac
+ shift
+ no_edit=t
+ log_given=t$log_given
+ logfile="$1"
+ shift
+ ;;
+ -F*|-f*)
+ no_edit=t
+ log_given=t$log_given
+ logfile=`expr "z$1" : 'z-[Ff]\(.*\)'`
+ shift
+ ;;
+ --F=*|--f=*|--fi=*|--fil=*|--file=*)
+ no_edit=t
+ log_given=t$log_given
+ logfile=`expr "z$1" : 'z-[^=]*=\(.*\)'`
+ shift
+ ;;
+ -a|--a|--al|--all)
+ all=t
+ shift
+ ;;
+ --au=*|--aut=*|--auth=*|--autho=*|--author=*)
+ force_author=`expr "z$1" : 'z-[^=]*=\(.*\)'`
+ shift
+ ;;
+ --au|--aut|--auth|--autho|--author)
+ case "$#" in 1) usage ;; esac
+ shift
+ force_author="$1"
+ shift
+ ;;
+ -e|--e|--ed|--edi|--edit)
+ edit_flag=t
+ shift
+ ;;
+ -i|--i|--in|--inc|--incl|--inclu|--includ|--include)
+ also=t
+ shift
+ ;;
+ --int|--inte|--inter|--intera|--interac|--interact|--interacti|\
+ --interactiv|--interactive)
+ interactive=t
+ shift
+ ;;
+ -o|--o|--on|--onl|--only)
+ only=t
+ shift
+ ;;
+ -m|--m|--me|--mes|--mess|--messa|--messag|--message)
+ case "$#" in 1) usage ;; esac
+ shift
+ log_given=m$log_given
+ if test "$log_message" = ''
+ then
+ log_message="$1"
+ else
+ log_message="$log_message
+
+$1"
+ fi
+ no_edit=t
+ shift
+ ;;
+ -m*)
+ log_given=m$log_given
+ if test "$log_message" = ''
+ then
+ log_message=`expr "z$1" : 'z-m\(.*\)'`
+ else
+ log_message="$log_message
+
+`expr "z$1" : 'z-m\(.*\)'`"
+ fi
+ no_edit=t
+ shift
+ ;;
+ --m=*|--me=*|--mes=*|--mess=*|--messa=*|--messag=*|--message=*)
+ log_given=m$log_given
+ if test "$log_message" = ''
+ then
+ log_message=`expr "z$1" : 'z-[^=]*=\(.*\)'`
+ else
+ log_message="$log_message
+
+`expr "z$1" : 'zq-[^=]*=\(.*\)'`"
+ fi
+ no_edit=t
+ shift
+ ;;
+ -n|--n|--no|--no-|--no-v|--no-ve|--no-ver|--no-veri|--no-verif|\
+ --no-verify)
+ verify=
+ shift
+ ;;
+ --a|--am|--ame|--amen|--amend)
+ amend=t
+ use_commit=HEAD
+ shift
+ ;;
+ -c)
+ case "$#" in 1) usage ;; esac
+ shift
+ log_given=t$log_given
+ use_commit="$1"
+ no_edit=
+ shift
+ ;;
+ --ree=*|--reed=*|--reedi=*|--reedit=*|--reedit-=*|--reedit-m=*|\
+ --reedit-me=*|--reedit-mes=*|--reedit-mess=*|--reedit-messa=*|\
+ --reedit-messag=*|--reedit-message=*)
+ log_given=t$log_given
+ use_commit=`expr "z$1" : 'z-[^=]*=\(.*\)'`
+ no_edit=
+ shift
+ ;;
+ --ree|--reed|--reedi|--reedit|--reedit-|--reedit-m|--reedit-me|\
+ --reedit-mes|--reedit-mess|--reedit-messa|--reedit-messag|\
+ --reedit-message)
+ case "$#" in 1) usage ;; esac
+ shift
+ log_given=t$log_given
+ use_commit="$1"
+ no_edit=
+ shift
+ ;;
+ -C)
+ case "$#" in 1) usage ;; esac
+ shift
+ log_given=t$log_given
+ use_commit="$1"
+ no_edit=t
+ shift
+ ;;
+ --reu=*|--reus=*|--reuse=*|--reuse-=*|--reuse-m=*|--reuse-me=*|\
+ --reuse-mes=*|--reuse-mess=*|--reuse-messa=*|--reuse-messag=*|\
+ --reuse-message=*)
+ log_given=t$log_given
+ use_commit=`expr "z$1" : 'z-[^=]*=\(.*\)'`
+ no_edit=t
+ shift
+ ;;
+ --reu|--reus|--reuse|--reuse-|--reuse-m|--reuse-me|--reuse-mes|\
+ --reuse-mess|--reuse-messa|--reuse-messag|--reuse-message)
+ case "$#" in 1) usage ;; esac
+ shift
+ log_given=t$log_given
+ use_commit="$1"
+ no_edit=t
+ shift
+ ;;
+ -s|--s|--si|--sig|--sign|--signo|--signof|--signoff)
+ signoff=t
+ shift
+ ;;
+ -t|--t|--te|--tem|--temp|--templ|--templa|--templat|--template)
+ case "$#" in 1) usage ;; esac
+ shift
+ templatefile="$1"
+ no_edit=
+ shift
+ ;;
+ -q|--q|--qu|--qui|--quie|--quiet)
+ quiet=t
+ shift
+ ;;
+ -v|--v|--ve|--ver|--verb|--verbo|--verbos|--verbose)
+ verbose=t
+ shift
+ ;;
+ -u|--u|--un|--unt|--untr|--untra|--untrac|--untrack|--untracke|\
+ --untracked|--untracked-|--untracked-f|--untracked-fi|--untracked-fil|\
+ --untracked-file|--untracked-files)
+ untracked_files=t
+ shift
+ ;;
+ --)
+ shift
+ break
+ ;;
+ -*)
+ usage
+ ;;
+ *)
+ break
+ ;;
+ esac
+done
+case "$edit_flag" in t) no_edit= ;; esac
+
+################################################################
+# Sanity check options
+
+case "$amend,$initial_commit" in
+t,t)
+ die "You do not have anything to amend." ;;
+t,)
+ if [ -f "$GIT_DIR/MERGE_HEAD" ]; then
+ die "You are in the middle of a merge -- cannot amend."
+ fi ;;
+esac
+
+case "$log_given" in
+tt*)
+ die "Only one of -c/-C/-F can be used." ;;
+*tm*|*mt*)
+ die "Option -m cannot be combined with -c/-C/-F." ;;
+esac
+
+case "$#,$also,$only,$amend" in
+*,t,t,*)
+ die "Only one of --include/--only can be used." ;;
+0,t,,* | 0,,t,)
+ die "No paths with --include/--only does not make sense." ;;
+0,,t,t)
+ only_include_assumed="# Clever... amending the last one with dirty index." ;;
+0,,,*)
+ ;;
+*,,,*)
+ only_include_assumed="# Explicit paths specified without -i nor -o; assuming --only paths..."
+ also=
+ ;;
+esac
+unset only
+case "$all,$interactive,$also,$#" in
+*t,*t,*)
+ die "Cannot use -a, --interactive or -i at the same time." ;;
+t,,[1-9]*)
+ die "Paths with -a does not make sense." ;;
+,t,[1-9]*)
+ die "Paths with --interactive does not make sense." ;;
+,,t,0)
+ die "No paths with -i does not make sense." ;;
+esac
+
+if test ! -z "$templatefile" -a -z "$log_given"
+then
+ if test ! -f "$templatefile"
+ then
+ die "Commit template file does not exist."
+ fi
+fi
+
+################################################################
+# Prepare index to have a tree to be committed
+
+case "$all,$also" in
+t,)
+ if test ! -f "$THIS_INDEX"
+ then
+ die 'nothing to commit (use "git add file1 file2" to include for commit)'
+ fi
+ save_index &&
+ (
+ cd_to_toplevel &&
+ GIT_INDEX_FILE="$NEXT_INDEX" &&
+ export GIT_INDEX_FILE &&
+ git diff-files --name-only -z |
+ git update-index --remove -z --stdin
+ ) || exit
+ ;;
+,t)
+ save_index &&
+ git ls-files --error-unmatch -- "$@" >/dev/null || exit
+
+ git diff-files --name-only -z -- "$@" |
+ (
+ cd_to_toplevel &&
+ GIT_INDEX_FILE="$NEXT_INDEX" &&
+ export GIT_INDEX_FILE &&
+ git update-index --remove -z --stdin
+ ) || exit
+ ;;
+,)
+ if test "$interactive" = t; then
+ git add --interactive || exit
+ fi
+ case "$#" in
+ 0)
+ ;; # commit as-is
+ *)
+ if test -f "$GIT_DIR/MERGE_HEAD"
+ then
+ refuse_partial "Cannot do a partial commit during a merge."
+ fi
+ TMP_INDEX="$GIT_DIR/tmp-index$$"
+ commit_only=`git ls-files --error-unmatch -- "$@"` || exit
+
+ # Build a temporary index and update the real index
+ # the same way.
+ if test -z "$initial_commit"
+ then
+ GIT_INDEX_FILE="$THIS_INDEX" \
+ git read-tree --index-output="$TMP_INDEX" -i -m HEAD
+ else
+ rm -f "$TMP_INDEX"
+ fi || exit
+
+ printf '%s\n' "$commit_only" |
+ GIT_INDEX_FILE="$TMP_INDEX" \
+ git update-index --add --remove --stdin &&
+
+ save_index &&
+ printf '%s\n' "$commit_only" |
+ (
+ GIT_INDEX_FILE="$NEXT_INDEX"
+ export GIT_INDEX_FILE
+ git update-index --remove --stdin
+ ) || exit
+ ;;
+ esac
+ ;;
+esac
+
+################################################################
+# If we do as-is commit, the index file will be THIS_INDEX,
+# otherwise NEXT_INDEX after we make this commit. We leave
+# the index as is if we abort.
+
+if test -f "$NEXT_INDEX"
+then
+ USE_INDEX="$NEXT_INDEX"
+else
+ USE_INDEX="$THIS_INDEX"
+fi
+
+case "$status_only" in
+t)
+ # This will silently fail in a read-only repository, which is
+ # what we want.
+ GIT_INDEX_FILE="$USE_INDEX" git update-index -q --unmerged --refresh
+ run_status
+ exit $?
+ ;;
+'')
+ GIT_INDEX_FILE="$USE_INDEX" git update-index -q --refresh || exit
+ ;;
+esac
+
+################################################################
+# Grab commit message, write out tree and make commit.
+
+if test t = "$verify" && test -x "$GIT_DIR"/hooks/pre-commit
+then
+ if test "$TMP_INDEX"
+ then
+ GIT_INDEX_FILE="$TMP_INDEX" "$GIT_DIR"/hooks/pre-commit
+ else
+ GIT_INDEX_FILE="$USE_INDEX" "$GIT_DIR"/hooks/pre-commit
+ fi || exit
+fi
+
+if test "$log_message" != ''
+then
+ printf '%s\n' "$log_message"
+elif test "$logfile" != ""
+then
+ if test "$logfile" = -
+ then
+ test -t 0 &&
+ echo >&2 "(reading log message from standard input)"
+ cat
+ else
+ cat <"$logfile"
+ fi
+elif test "$use_commit" != ""
+then
+ encoding=$(git config i18n.commitencoding || echo UTF-8)
+ git show -s --pretty=raw --encoding="$encoding" "$use_commit" |
+ sed -e '1,/^$/d' -e 's/^ //'
+elif test -f "$GIT_DIR/MERGE_MSG"
+then
+ cat "$GIT_DIR/MERGE_MSG"
+elif test -f "$GIT_DIR/SQUASH_MSG"
+then
+ cat "$GIT_DIR/SQUASH_MSG"
+elif test "$templatefile" != ""
+then
+ cat "$templatefile"
+fi | git stripspace >"$GIT_DIR"/COMMIT_EDITMSG
+
+case "$signoff" in
+t)
+ sign=$(git-var GIT_COMMITTER_IDENT | sed -e '
+ s/>.*/>/
+ s/^/Signed-off-by: /
+ ')
+ blank_before_signoff=
+ tail -n 1 "$GIT_DIR"/COMMIT_EDITMSG |
+ grep 'Signed-off-by:' >/dev/null || blank_before_signoff='
+'
+ tail -n 1 "$GIT_DIR"/COMMIT_EDITMSG |
+ grep "$sign"$ >/dev/null ||
+ printf '%s%s\n' "$blank_before_signoff" "$sign" \
+ >>"$GIT_DIR"/COMMIT_EDITMSG
+ ;;
+esac
+
+if test -f "$GIT_DIR/MERGE_HEAD" && test -z "$no_edit"; then
+ echo "#"
+ echo "# It looks like you may be committing a MERGE."
+ echo "# If this is not correct, please remove the file"
+ printf '%s\n' "# $GIT_DIR/MERGE_HEAD"
+ echo "# and try again"
+ echo "#"
+fi >>"$GIT_DIR"/COMMIT_EDITMSG
+
+# Author
+if test '' != "$use_commit"
+then
+ eval "$(get_author_ident_from_commit "$use_commit")"
+ export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_AUTHOR_DATE
+fi
+if test '' != "$force_author"
+then
+ GIT_AUTHOR_NAME=`expr "z$force_author" : 'z\(.*[^ ]\) *<.*'` &&
+ GIT_AUTHOR_EMAIL=`expr "z$force_author" : '.*\(<.*\)'` &&
+ test '' != "$GIT_AUTHOR_NAME" &&
+ test '' != "$GIT_AUTHOR_EMAIL" ||
+ die "malformed --author parameter"
+ export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL
+fi
+
+PARENTS="-p HEAD"
+if test -z "$initial_commit"
+then
+ rloga='commit'
+ if [ -f "$GIT_DIR/MERGE_HEAD" ]; then
+ rloga='commit (merge)'
+ PARENTS="-p HEAD "`sed -e 's/^/-p /' "$GIT_DIR/MERGE_HEAD"`
+ elif test -n "$amend"; then
+ rloga='commit (amend)'
+ PARENTS=$(git cat-file commit HEAD |
+ sed -n -e '/^$/q' -e 's/^parent /-p /p')
+ fi
+ current="$(git rev-parse --verify HEAD)"
+else
+ if [ -z "$(git ls-files)" ]; then
+ echo >&2 'nothing to commit (use "git add file1 file2" to include for commit)'
+ exit 1
+ fi
+ PARENTS=""
+ rloga='commit (initial)'
+ current=''
+fi
+set_reflog_action "$rloga"
+
+if test -z "$no_edit"
+then
+ {
+ echo ""
+ echo "# Please enter the commit message for your changes."
+ echo "# (Comment lines starting with '#' will not be included)"
+ test -z "$only_include_assumed" || echo "$only_include_assumed"
+ run_status
+ } >>"$GIT_DIR"/COMMIT_EDITMSG
+else
+ # we need to check if there is anything to commit
+ run_status >/dev/null
+fi
+if [ "$?" != "0" -a ! -f "$GIT_DIR/MERGE_HEAD" -a -z "$amend" ]
+then
+ rm -f "$GIT_DIR/COMMIT_EDITMSG" "$GIT_DIR/SQUASH_MSG"
+ run_status
+ exit 1
+fi
+
+case "$no_edit" in
+'')
+ git-var GIT_AUTHOR_IDENT > /dev/null || die
+ git-var GIT_COMMITTER_IDENT > /dev/null || die
+ git_editor "$GIT_DIR/COMMIT_EDITMSG"
+ ;;
+esac
+
+case "$verify" in
+t)
+ if test -x "$GIT_DIR"/hooks/commit-msg
+ then
+ "$GIT_DIR"/hooks/commit-msg "$GIT_DIR"/COMMIT_EDITMSG || exit
+ fi
+esac
+
+if test -z "$no_edit"
+then
+ sed -e '
+ /^diff --git a\/.*/{
+ s///
+ q
+ }
+ /^#/d
+ ' "$GIT_DIR"/COMMIT_EDITMSG
+else
+ cat "$GIT_DIR"/COMMIT_EDITMSG
+fi |
+git stripspace >"$GIT_DIR"/COMMIT_MSG
+
+# Test whether the commit message has any content we didn't supply.
+have_commitmsg=
+grep -v -i '^Signed-off-by' "$GIT_DIR"/COMMIT_MSG |
+ git stripspace > "$GIT_DIR"/COMMIT_BAREMSG
+
+# Is the commit message totally empty?
+if test -s "$GIT_DIR"/COMMIT_BAREMSG
+then
+ if test "$templatefile" != ""
+ then
+ # Test whether this is just the unaltered template.
+ if cnt=`sed -e '/^#/d' < "$templatefile" |
+ git stripspace |
+ diff "$GIT_DIR"/COMMIT_BAREMSG - |
+ wc -l` &&
+ test 0 -lt $cnt
+ then
+ have_commitmsg=t
+ fi
+ else
+ # No template, so the content in the commit message must
+ # have come from the user.
+ have_commitmsg=t
+ fi
+fi
+
+rm -f "$GIT_DIR"/COMMIT_BAREMSG
+
+if test "$have_commitmsg" = "t"
+then
+ if test -z "$TMP_INDEX"
+ then
+ tree=$(GIT_INDEX_FILE="$USE_INDEX" git write-tree)
+ else
+ tree=$(GIT_INDEX_FILE="$TMP_INDEX" git write-tree) &&
+ rm -f "$TMP_INDEX"
+ fi &&
+ commit=$(git commit-tree $tree $PARENTS <"$GIT_DIR/COMMIT_MSG") &&
+ rlogm=$(sed -e 1q "$GIT_DIR"/COMMIT_MSG) &&
+ git update-ref -m "$GIT_REFLOG_ACTION: $rlogm" HEAD $commit "$current" &&
+ rm -f -- "$GIT_DIR/MERGE_HEAD" "$GIT_DIR/MERGE_MSG" &&
+ if test -f "$NEXT_INDEX"
+ then
+ mv "$NEXT_INDEX" "$THIS_INDEX"
+ else
+ : ;# happy
+ fi
+else
+ echo >&2 "* no commit message? aborting commit."
+ false
+fi
+ret="$?"
+rm -f "$GIT_DIR/COMMIT_MSG" "$GIT_DIR/COMMIT_EDITMSG" "$GIT_DIR/SQUASH_MSG"
+
+cd_to_toplevel
+
+git rerere
+
+if test "$ret" = 0
+then
+ if test -x "$GIT_DIR"/hooks/post-commit
+ then
+ "$GIT_DIR"/hooks/post-commit
+ fi
+ if test -z "$quiet"
+ then
+ commit=`git diff-tree --always --shortstat --pretty="format:%h: %s"\
+ --summary --root HEAD --`
+ echo "Created${initial_commit:+ initial} commit $commit"
+ fi
+fi
+
+exit "$ret"
diff --git a/git-commit.sh b/git-commit.sh
deleted file mode 100755
index d7e7028..0000000
--- a/git-commit.sh
+++ /dev/null
@@ -1,665 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2005 Linus Torvalds
-# Copyright (c) 2006 Junio C Hamano
-
-USAGE='[-a | --interactive] [-s] [-v] [--no-verify] [-m <message> | -F <logfile> | (-C|-c) <commit> | --amend] [-u] [-e] [--author <author>] [--template <file>] [[-i | -o] <path>...]'
-SUBDIRECTORY_OK=Yes
-. git-sh-setup
-require_work_tree
-
-git rev-parse --verify HEAD >/dev/null 2>&1 || initial_commit=t
-
-case "$0" in
-*status)
- status_only=t
- ;;
-*commit)
- status_only=
- ;;
-esac
-
-refuse_partial () {
- echo >&2 "$1"
- echo >&2 "You might have meant to say 'git commit -i paths...', perhaps?"
- exit 1
-}
-
-THIS_INDEX="$GIT_DIR/index"
-NEXT_INDEX="$GIT_DIR/next-index$$"
-rm -f "$NEXT_INDEX"
-save_index () {
- cp -p "$THIS_INDEX" "$NEXT_INDEX"
-}
-
-run_status () {
- # If TMP_INDEX is defined, that means we are doing
- # "--only" partial commit, and that index file is used
- # to build the tree for the commit. Otherwise, if
- # NEXT_INDEX exists, that is the index file used to
- # make the commit. Otherwise we are using as-is commit
- # so the regular index file is what we use to compare.
- if test '' != "$TMP_INDEX"
- then
- GIT_INDEX_FILE="$TMP_INDEX"
- export GIT_INDEX_FILE
- elif test -f "$NEXT_INDEX"
- then
- GIT_INDEX_FILE="$NEXT_INDEX"
- export GIT_INDEX_FILE
- fi
-
- case "$status_only" in
- t) color= ;;
- *) color=--nocolor ;;
- esac
- git runstatus ${color} \
- ${verbose:+--verbose} \
- ${amend:+--amend} \
- ${untracked_files:+--untracked}
-}
-
-trap '
- test -z "$TMP_INDEX" || {
- test -f "$TMP_INDEX" && rm -f "$TMP_INDEX"
- }
- rm -f "$NEXT_INDEX"
-' 0
-
-################################################################
-# Command line argument parsing and sanity checking
-
-all=
-also=
-interactive=
-only=
-logfile=
-use_commit=
-amend=
-edit_flag=
-no_edit=
-log_given=
-log_message=
-verify=t
-quiet=
-verbose=
-signoff=
-force_author=
-only_include_assumed=
-untracked_files=
-templatefile="`git config commit.template`"
-while case "$#" in 0) break;; esac
-do
- case "$1" in
- -F|--F|-f|--f|--fi|--fil|--file)
- case "$#" in 1) usage ;; esac
- shift
- no_edit=t
- log_given=t$log_given
- logfile="$1"
- shift
- ;;
- -F*|-f*)
- no_edit=t
- log_given=t$log_given
- logfile=`expr "z$1" : 'z-[Ff]\(.*\)'`
- shift
- ;;
- --F=*|--f=*|--fi=*|--fil=*|--file=*)
- no_edit=t
- log_given=t$log_given
- logfile=`expr "z$1" : 'z-[^=]*=\(.*\)'`
- shift
- ;;
- -a|--a|--al|--all)
- all=t
- shift
- ;;
- --au=*|--aut=*|--auth=*|--autho=*|--author=*)
- force_author=`expr "z$1" : 'z-[^=]*=\(.*\)'`
- shift
- ;;
- --au|--aut|--auth|--autho|--author)
- case "$#" in 1) usage ;; esac
- shift
- force_author="$1"
- shift
- ;;
- -e|--e|--ed|--edi|--edit)
- edit_flag=t
- shift
- ;;
- -i|--i|--in|--inc|--incl|--inclu|--includ|--include)
- also=t
- shift
- ;;
- --int|--inte|--inter|--intera|--interac|--interact|--interacti|\
- --interactiv|--interactive)
- interactive=t
- shift
- ;;
- -o|--o|--on|--onl|--only)
- only=t
- shift
- ;;
- -m|--m|--me|--mes|--mess|--messa|--messag|--message)
- case "$#" in 1) usage ;; esac
- shift
- log_given=m$log_given
- if test "$log_message" = ''
- then
- log_message="$1"
- else
- log_message="$log_message
-
-$1"
- fi
- no_edit=t
- shift
- ;;
- -m*)
- log_given=m$log_given
- if test "$log_message" = ''
- then
- log_message=`expr "z$1" : 'z-m\(.*\)'`
- else
- log_message="$log_message
-
-`expr "z$1" : 'z-m\(.*\)'`"
- fi
- no_edit=t
- shift
- ;;
- --m=*|--me=*|--mes=*|--mess=*|--messa=*|--messag=*|--message=*)
- log_given=m$log_given
- if test "$log_message" = ''
- then
- log_message=`expr "z$1" : 'z-[^=]*=\(.*\)'`
- else
- log_message="$log_message
-
-`expr "z$1" : 'zq-[^=]*=\(.*\)'`"
- fi
- no_edit=t
- shift
- ;;
- -n|--n|--no|--no-|--no-v|--no-ve|--no-ver|--no-veri|--no-verif|\
- --no-verify)
- verify=
- shift
- ;;
- --a|--am|--ame|--amen|--amend)
- amend=t
- use_commit=HEAD
- shift
- ;;
- -c)
- case "$#" in 1) usage ;; esac
- shift
- log_given=t$log_given
- use_commit="$1"
- no_edit=
- shift
- ;;
- --ree=*|--reed=*|--reedi=*|--reedit=*|--reedit-=*|--reedit-m=*|\
- --reedit-me=*|--reedit-mes=*|--reedit-mess=*|--reedit-messa=*|\
- --reedit-messag=*|--reedit-message=*)
- log_given=t$log_given
- use_commit=`expr "z$1" : 'z-[^=]*=\(.*\)'`
- no_edit=
- shift
- ;;
- --ree|--reed|--reedi|--reedit|--reedit-|--reedit-m|--reedit-me|\
- --reedit-mes|--reedit-mess|--reedit-messa|--reedit-messag|\
- --reedit-message)
- case "$#" in 1) usage ;; esac
- shift
- log_given=t$log_given
- use_commit="$1"
- no_edit=
- shift
- ;;
- -C)
- case "$#" in 1) usage ;; esac
- shift
- log_given=t$log_given
- use_commit="$1"
- no_edit=t
- shift
- ;;
- --reu=*|--reus=*|--reuse=*|--reuse-=*|--reuse-m=*|--reuse-me=*|\
- --reuse-mes=*|--reuse-mess=*|--reuse-messa=*|--reuse-messag=*|\
- --reuse-message=*)
- log_given=t$log_given
- use_commit=`expr "z$1" : 'z-[^=]*=\(.*\)'`
- no_edit=t
- shift
- ;;
- --reu|--reus|--reuse|--reuse-|--reuse-m|--reuse-me|--reuse-mes|\
- --reuse-mess|--reuse-messa|--reuse-messag|--reuse-message)
- case "$#" in 1) usage ;; esac
- shift
- log_given=t$log_given
- use_commit="$1"
- no_edit=t
- shift
- ;;
- -s|--s|--si|--sig|--sign|--signo|--signof|--signoff)
- signoff=t
- shift
- ;;
- -t|--t|--te|--tem|--temp|--templ|--templa|--templat|--template)
- case "$#" in 1) usage ;; esac
- shift
- templatefile="$1"
- no_edit=
- shift
- ;;
- -q|--q|--qu|--qui|--quie|--quiet)
- quiet=t
- shift
- ;;
- -v|--v|--ve|--ver|--verb|--verbo|--verbos|--verbose)
- verbose=t
- shift
- ;;
- -u|--u|--un|--unt|--untr|--untra|--untrac|--untrack|--untracke|\
- --untracked|--untracked-|--untracked-f|--untracked-fi|--untracked-fil|\
- --untracked-file|--untracked-files)
- untracked_files=t
- shift
- ;;
- --)
- shift
- break
- ;;
- -*)
- usage
- ;;
- *)
- break
- ;;
- esac
-done
-case "$edit_flag" in t) no_edit= ;; esac
-
-################################################################
-# Sanity check options
-
-case "$amend,$initial_commit" in
-t,t)
- die "You do not have anything to amend." ;;
-t,)
- if [ -f "$GIT_DIR/MERGE_HEAD" ]; then
- die "You are in the middle of a merge -- cannot amend."
- fi ;;
-esac
-
-case "$log_given" in
-tt*)
- die "Only one of -c/-C/-F can be used." ;;
-*tm*|*mt*)
- die "Option -m cannot be combined with -c/-C/-F." ;;
-esac
-
-case "$#,$also,$only,$amend" in
-*,t,t,*)
- die "Only one of --include/--only can be used." ;;
-0,t,,* | 0,,t,)
- die "No paths with --include/--only does not make sense." ;;
-0,,t,t)
- only_include_assumed="# Clever... amending the last one with dirty index." ;;
-0,,,*)
- ;;
-*,,,*)
- only_include_assumed="# Explicit paths specified without -i nor -o; assuming --only paths..."
- also=
- ;;
-esac
-unset only
-case "$all,$interactive,$also,$#" in
-*t,*t,*)
- die "Cannot use -a, --interactive or -i at the same time." ;;
-t,,[1-9]*)
- die "Paths with -a does not make sense." ;;
-,t,[1-9]*)
- die "Paths with --interactive does not make sense." ;;
-,,t,0)
- die "No paths with -i does not make sense." ;;
-esac
-
-if test ! -z "$templatefile" -a -z "$log_given"
-then
- if test ! -f "$templatefile"
- then
- die "Commit template file does not exist."
- fi
-fi
-
-################################################################
-# Prepare index to have a tree to be committed
-
-case "$all,$also" in
-t,)
- if test ! -f "$THIS_INDEX"
- then
- die 'nothing to commit (use "git add file1 file2" to include for commit)'
- fi
- save_index &&
- (
- cd_to_toplevel &&
- GIT_INDEX_FILE="$NEXT_INDEX" &&
- export GIT_INDEX_FILE &&
- git diff-files --name-only -z |
- git update-index --remove -z --stdin
- ) || exit
- ;;
-,t)
- save_index &&
- git ls-files --error-unmatch -- "$@" >/dev/null || exit
-
- git diff-files --name-only -z -- "$@" |
- (
- cd_to_toplevel &&
- GIT_INDEX_FILE="$NEXT_INDEX" &&
- export GIT_INDEX_FILE &&
- git update-index --remove -z --stdin
- ) || exit
- ;;
-,)
- if test "$interactive" = t; then
- git add --interactive || exit
- fi
- case "$#" in
- 0)
- ;; # commit as-is
- *)
- if test -f "$GIT_DIR/MERGE_HEAD"
- then
- refuse_partial "Cannot do a partial commit during a merge."
- fi
- TMP_INDEX="$GIT_DIR/tmp-index$$"
- commit_only=`git ls-files --error-unmatch -- "$@"` || exit
-
- # Build a temporary index and update the real index
- # the same way.
- if test -z "$initial_commit"
- then
- GIT_INDEX_FILE="$THIS_INDEX" \
- git read-tree --index-output="$TMP_INDEX" -i -m HEAD
- else
- rm -f "$TMP_INDEX"
- fi || exit
-
- printf '%s\n' "$commit_only" |
- GIT_INDEX_FILE="$TMP_INDEX" \
- git update-index --add --remove --stdin &&
-
- save_index &&
- printf '%s\n' "$commit_only" |
- (
- GIT_INDEX_FILE="$NEXT_INDEX"
- export GIT_INDEX_FILE
- git update-index --remove --stdin
- ) || exit
- ;;
- esac
- ;;
-esac
-
-################################################################
-# If we do as-is commit, the index file will be THIS_INDEX,
-# otherwise NEXT_INDEX after we make this commit. We leave
-# the index as is if we abort.
-
-if test -f "$NEXT_INDEX"
-then
- USE_INDEX="$NEXT_INDEX"
-else
- USE_INDEX="$THIS_INDEX"
-fi
-
-case "$status_only" in
-t)
- # This will silently fail in a read-only repository, which is
- # what we want.
- GIT_INDEX_FILE="$USE_INDEX" git update-index -q --unmerged --refresh
- run_status
- exit $?
- ;;
-'')
- GIT_INDEX_FILE="$USE_INDEX" git update-index -q --refresh || exit
- ;;
-esac
-
-################################################################
-# Grab commit message, write out tree and make commit.
-
-if test t = "$verify" && test -x "$GIT_DIR"/hooks/pre-commit
-then
- if test "$TMP_INDEX"
- then
- GIT_INDEX_FILE="$TMP_INDEX" "$GIT_DIR"/hooks/pre-commit
- else
- GIT_INDEX_FILE="$USE_INDEX" "$GIT_DIR"/hooks/pre-commit
- fi || exit
-fi
-
-if test "$log_message" != ''
-then
- printf '%s\n' "$log_message"
-elif test "$logfile" != ""
-then
- if test "$logfile" = -
- then
- test -t 0 &&
- echo >&2 "(reading log message from standard input)"
- cat
- else
- cat <"$logfile"
- fi
-elif test "$use_commit" != ""
-then
- encoding=$(git config i18n.commitencoding || echo UTF-8)
- git show -s --pretty=raw --encoding="$encoding" "$use_commit" |
- sed -e '1,/^$/d' -e 's/^ //'
-elif test -f "$GIT_DIR/MERGE_MSG"
-then
- cat "$GIT_DIR/MERGE_MSG"
-elif test -f "$GIT_DIR/SQUASH_MSG"
-then
- cat "$GIT_DIR/SQUASH_MSG"
-elif test "$templatefile" != ""
-then
- cat "$templatefile"
-fi | git stripspace >"$GIT_DIR"/COMMIT_EDITMSG
-
-case "$signoff" in
-t)
- sign=$(git-var GIT_COMMITTER_IDENT | sed -e '
- s/>.*/>/
- s/^/Signed-off-by: /
- ')
- blank_before_signoff=
- tail -n 1 "$GIT_DIR"/COMMIT_EDITMSG |
- grep 'Signed-off-by:' >/dev/null || blank_before_signoff='
-'
- tail -n 1 "$GIT_DIR"/COMMIT_EDITMSG |
- grep "$sign"$ >/dev/null ||
- printf '%s%s\n' "$blank_before_signoff" "$sign" \
- >>"$GIT_DIR"/COMMIT_EDITMSG
- ;;
-esac
-
-if test -f "$GIT_DIR/MERGE_HEAD" && test -z "$no_edit"; then
- echo "#"
- echo "# It looks like you may be committing a MERGE."
- echo "# If this is not correct, please remove the file"
- printf '%s\n' "# $GIT_DIR/MERGE_HEAD"
- echo "# and try again"
- echo "#"
-fi >>"$GIT_DIR"/COMMIT_EDITMSG
-
-# Author
-if test '' != "$use_commit"
-then
- eval "$(get_author_ident_from_commit "$use_commit")"
- export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_AUTHOR_DATE
-fi
-if test '' != "$force_author"
-then
- GIT_AUTHOR_NAME=`expr "z$force_author" : 'z\(.*[^ ]\) *<.*'` &&
- GIT_AUTHOR_EMAIL=`expr "z$force_author" : '.*\(<.*\)'` &&
- test '' != "$GIT_AUTHOR_NAME" &&
- test '' != "$GIT_AUTHOR_EMAIL" ||
- die "malformed --author parameter"
- export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL
-fi
-
-PARENTS="-p HEAD"
-if test -z "$initial_commit"
-then
- rloga='commit'
- if [ -f "$GIT_DIR/MERGE_HEAD" ]; then
- rloga='commit (merge)'
- PARENTS="-p HEAD "`sed -e 's/^/-p /' "$GIT_DIR/MERGE_HEAD"`
- elif test -n "$amend"; then
- rloga='commit (amend)'
- PARENTS=$(git cat-file commit HEAD |
- sed -n -e '/^$/q' -e 's/^parent /-p /p')
- fi
- current="$(git rev-parse --verify HEAD)"
-else
- if [ -z "$(git ls-files)" ]; then
- echo >&2 'nothing to commit (use "git add file1 file2" to include for commit)'
- exit 1
- fi
- PARENTS=""
- rloga='commit (initial)'
- current=''
-fi
-set_reflog_action "$rloga"
-
-if test -z "$no_edit"
-then
- {
- echo ""
- echo "# Please enter the commit message for your changes."
- echo "# (Comment lines starting with '#' will not be included)"
- test -z "$only_include_assumed" || echo "$only_include_assumed"
- run_status
- } >>"$GIT_DIR"/COMMIT_EDITMSG
-else
- # we need to check if there is anything to commit
- run_status >/dev/null
-fi
-if [ "$?" != "0" -a ! -f "$GIT_DIR/MERGE_HEAD" -a -z "$amend" ]
-then
- rm -f "$GIT_DIR/COMMIT_EDITMSG" "$GIT_DIR/SQUASH_MSG"
- run_status
- exit 1
-fi
-
-case "$no_edit" in
-'')
- git-var GIT_AUTHOR_IDENT > /dev/null || die
- git-var GIT_COMMITTER_IDENT > /dev/null || die
- git_editor "$GIT_DIR/COMMIT_EDITMSG"
- ;;
-esac
-
-case "$verify" in
-t)
- if test -x "$GIT_DIR"/hooks/commit-msg
- then
- "$GIT_DIR"/hooks/commit-msg "$GIT_DIR"/COMMIT_EDITMSG || exit
- fi
-esac
-
-if test -z "$no_edit"
-then
- sed -e '
- /^diff --git a\/.*/{
- s///
- q
- }
- /^#/d
- ' "$GIT_DIR"/COMMIT_EDITMSG
-else
- cat "$GIT_DIR"/COMMIT_EDITMSG
-fi |
-git stripspace >"$GIT_DIR"/COMMIT_MSG
-
-# Test whether the commit message has any content we didn't supply.
-have_commitmsg=
-grep -v -i '^Signed-off-by' "$GIT_DIR"/COMMIT_MSG |
- git stripspace > "$GIT_DIR"/COMMIT_BAREMSG
-
-# Is the commit message totally empty?
-if test -s "$GIT_DIR"/COMMIT_BAREMSG
-then
- if test "$templatefile" != ""
- then
- # Test whether this is just the unaltered template.
- if cnt=`sed -e '/^#/d' < "$templatefile" |
- git stripspace |
- diff "$GIT_DIR"/COMMIT_BAREMSG - |
- wc -l` &&
- test 0 -lt $cnt
- then
- have_commitmsg=t
- fi
- else
- # No template, so the content in the commit message must
- # have come from the user.
- have_commitmsg=t
- fi
-fi
-
-rm -f "$GIT_DIR"/COMMIT_BAREMSG
-
-if test "$have_commitmsg" = "t"
-then
- if test -z "$TMP_INDEX"
- then
- tree=$(GIT_INDEX_FILE="$USE_INDEX" git write-tree)
- else
- tree=$(GIT_INDEX_FILE="$TMP_INDEX" git write-tree) &&
- rm -f "$TMP_INDEX"
- fi &&
- commit=$(git commit-tree $tree $PARENTS <"$GIT_DIR/COMMIT_MSG") &&
- rlogm=$(sed -e 1q "$GIT_DIR"/COMMIT_MSG) &&
- git update-ref -m "$GIT_REFLOG_ACTION: $rlogm" HEAD $commit "$current" &&
- rm -f -- "$GIT_DIR/MERGE_HEAD" "$GIT_DIR/MERGE_MSG" &&
- if test -f "$NEXT_INDEX"
- then
- mv "$NEXT_INDEX" "$THIS_INDEX"
- else
- : ;# happy
- fi
-else
- echo >&2 "* no commit message? aborting commit."
- false
-fi
-ret="$?"
-rm -f "$GIT_DIR/COMMIT_MSG" "$GIT_DIR/COMMIT_EDITMSG" "$GIT_DIR/SQUASH_MSG"
-
-cd_to_toplevel
-
-git rerere
-
-if test "$ret" = 0
-then
- if test -x "$GIT_DIR"/hooks/post-commit
- then
- "$GIT_DIR"/hooks/post-commit
- fi
- if test -z "$quiet"
- then
- commit=`git diff-tree --always --shortstat --pretty="format:%h: %s"\
- --summary --root HEAD --`
- echo "Created${initial_commit:+ initial} commit $commit"
- fi
-fi
-
-exit "$ret"
diff --git a/git.c b/git.c
index cab0e72..62859a2 100644
--- a/git.c
+++ b/git.c
@@ -321,6 +321,7 @@ static void handle_internal_command(int argc, const char **argv)
{ "check-attr", cmd_check_attr, RUN_SETUP | NEED_WORK_TREE },
{ "cherry", cmd_cherry, RUN_SETUP },
{ "cherry-pick", cmd_cherry_pick, RUN_SETUP | NEED_WORK_TREE },
+ { "commit", cmd_commit, RUN_SETUP | NEED_WORK_TREE },
{ "commit-tree", cmd_commit_tree, RUN_SETUP },
{ "config", cmd_config },
{ "count-objects", cmd_count_objects, RUN_SETUP },
@@ -363,10 +364,10 @@ static void handle_internal_command(int argc, const char **argv)
{ "rev-parse", cmd_rev_parse, RUN_SETUP },
{ "revert", cmd_revert, RUN_SETUP | NEED_WORK_TREE },
{ "rm", cmd_rm, RUN_SETUP | NEED_WORK_TREE },
- { "runstatus", cmd_runstatus, RUN_SETUP | NEED_WORK_TREE },
{ "shortlog", cmd_shortlog, RUN_SETUP | USE_PAGER },
{ "show-branch", cmd_show_branch, RUN_SETUP },
{ "show", cmd_show, RUN_SETUP | USE_PAGER },
+ { "status", cmd_status, RUN_SETUP | NEED_WORK_TREE },
{ "stripspace", cmd_stripspace },
{ "symbolic-ref", cmd_symbolic_ref, RUN_SETUP },
{ "tag", cmd_tag, RUN_SETUP },
--
1.5.2.GIT
^ permalink raw reply related [relevance 2%]
* [ANNOUNCE] GIT 1.5.3.2
@ 2007-09-19 19:01 2% Junio C Hamano
0 siblings, 0 replies; 200+ results
From: Junio C Hamano @ 2007-09-19 19:01 UTC (permalink / raw)
To: git; +Cc: linux-kernel
The latest maintenance release GIT 1.5.3.2 is available at the
usual places:
http://www.kernel.org/pub/software/scm/git/
git-1.5.3.2.tar.{gz,bz2} (tarball)
git-htmldocs-1.5.3.2.tar.{gz,bz2} (preformatted docs)
git-manpages-1.5.3.2.tar.{gz,bz2} (preformatted docs)
RPMS/$arch/git-*-1.5.3.2-1.$arch.rpm (RPM)
GIT v1.5.3.2 Release Notes
==========================
Fixes since v1.5.3.1
--------------------
* git-push sent thin packs by default, which was not good for
the public distribution server (no point in saving transfer
while pushing; no point in making the resulting pack less
optimum).
* git-svn sometimes terminated with "Malformed network data" when
talking over svn:// protocol.
* git-send-email re-issued the same message-id about 10% of the
time if you fired off 30 messages within a single second.
* git-stash was not terminating the log message of commits it
internally creates with LF.
* git-apply failed to check the size of the patch hunk when its
beginning part matched the remainder of the preimage exactly,
even though the preimage recorded in the hunk was much larger
(therefore the patch should not have applied), leading to a
segfault.
* "git rm foo && git commit foo" complained that 'foo' needs to
be added first, instead of committing the removal, which was a
nonsense.
* git grep -c said "/dev/null: 0".
* git-add -u failed to recognize a blob whose type changed
between the index and the work tree.
* The limit to rename detection has been tightened a lot to
reduce performance problems with a huge change.
* cvsimport and svnimport barfed when the input tried to move
a tag.
* "git apply -pN" did not chop the right number of directories.
* "git svnimport" did not like SVN tags with funny characters in them.
* git-gui 0.8.3, with assorted fixes, including:
- font-chooser on X11 was unusable with large number of fonts;
- a diff that contained a deleted symlink made it barf;
- an untracked symbolic link to a directory made it fart;
- a file with % in its name made it vomit;
Documentation updates
---------------------
User manual has been somewhat restructured. I think the new
organization is much easier to read.
----------------------------------------------------------------
Changes since v1.5.3.1 are as follows:
Alexandre Julliard (1):
hooks--update: Explicitly check for all zeros for a deleted ref.
Benoit Sigoure (1):
Add test to check recent fix to "git add -u"
Carlos Rica (1):
git-tag -s must fail if gpg cannot sign the tag.
David Kastrup (1):
git-send-email.perl: Add angle brackets to In-Reply-To if necessary
Dmitry V. Levin (2):
Makefile: Add cache-tree.h to the headers list
git-commit: Disallow amend if it is going to produce an empty non-merge commit
Eric Wong (3):
git-svn: fix "Malformed network data" with svn:// servers
git-svn: understand grafts when doing dcommit
Documentation/git-svn: updated design philosophy notes
Gerrit Pape (2):
git-gui: lib/index.tcl: handle files with % in the filename properly
git-clone: improve error message if curl program is missing or not executable
J. Bruce Fields (13):
user-manual: adjust section levels in "git internals"
user-manual: move object format details to hacking-git chapter
user-manual: rename "git internals" to "git concepts"
user-manual: create new "low-level git operations" chapter
user-manual: rewrite index discussion
user-manual: reorder commit, blob, tree discussion
user-manual: rewrite object database discussion
user-manual: move packfile and dangling object discussion
user-manual: fix introduction to packfiles
user-manual: todo updates and cleanup
documentation: replace Discussion section by link to user-manual chapter
core-tutorial: minor cleanup
git-apply: fix whitespace stripping
Jari Aalto (1):
Documentation/git-archive.txt: a couple of clarifications.
Jean-Luc Herren (1):
stash: end index commit log with a newline
Jeff King (1):
git-push: documentation and tests for pushing only branches
Johannes Schindelin (2):
revision walker: --cherry-pick is a limited operation
apply --index-info: fall back to current index for mode changes
Junio C Hamano (13):
git-apply: do not read past the end of buffer
git-add -u: do not barf on type changes
git-format-patch --in-reply-to: accept <message@id> with angle brackets
diff --no-index: do not forget to run diff_setup_done()
Documentation/git-config.txt: AsciiDoc tweak to avoid leading dot
Split grep arguments in a way that does not requires to add /dev/null.
git-sh-setup: typofix in comments
send-email: make message-id generation a bit more robust
git-commit: Allow partial commit of file removal.
git-commit: partial commit of paths only removed from the index
Document ls-files --with-tree=<tree-ish>
t/t4014: test "am -3" with mode-only change.
GIT 1.5.3.2
Linus Torvalds (1):
Fix the rename detection limit checking
Matthias Urlichs (1):
git-svnimport: Use separate arguments in the pipe for git-rev-parse
Michael Smith (1):
(cvs|svn)import: Ask git-tag to overwrite old tags.
Michele Ballabio (2):
git-gui: show unstaged symlinks in diff viewer
git-gui: handle "deleted symlink" diff marker
Mike Ralphson (1):
Documentation / grammer nit
Nicolas Pitre (1):
fix doc for --compression argument to pack-objects
Pierre Habouzit (1):
Fix lapsus in builtin-apply.c
Ramsay Allan Jones (1):
Fix a test failure (t9500-*.sh) on cygwin
Shawn O. Pearce (17):
git-gui: Correct starting of git-remote to handle -w option
git-gui: Fix detaching current branch during checkout
git-gui: Properly set the state of "Stage/Unstage Hunk" action
Don't allow contrib/workdir/git-new-workdir to trash existing dirs
Cleanup unnecessary file modifications in t1400-update-ref
Include a git-push example for creating a remote branch
git-gui: Disable Tk send in all git-gui sessions
git-gui: Avoid use of libdir in Makefile
git-gui: Assume untracked directories are Git submodules
git-gui: Trim trailing slashes from untracked submodule names
Make --no-thin the default in git-push to save server resources
git-gui: Don't delete send on Windows as it doesn't exist
git-gui: Make backporting changes from i18n version easier
git-gui: Font chooser to handle a large number of font families
git-gui: Provide 'uninstall' Makefile target to undo an installation
git-gui: Paper bag fix "Commit->Revert" format arguments
git-gui: Disable native platform text selection in "lists"
Sven Verdoolaege (1):
git-diff: don't squelch the new SHA1 in submodule diffs
Ulrik Sverdrup (1):
Remove duplicate note about removing commits with git-filter-branch
Väinö Järvelä (1):
Fixed update-hook example allow-users format.
^ permalink raw reply [relevance 2%]
* [PATCH] user-manual: Explain what submodules are good for.
@ 2007-09-24 3:14 11% ` Michael Smith
0 siblings, 0 replies; 200+ results
From: Michael Smith @ 2007-09-24 3:14 UTC (permalink / raw)
To: git; +Cc: J. Bruce Fields, Miklos Vajna, Michael Smith
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.
Signed-off-by: Michael Smith <msmith@cbnco.com>
---
Documentation/user-manual.txt | 25 ++++++++++++++-----------
1 files changed, 14 insertions(+), 11 deletions(-)
diff --git a/Documentation/user-manual.txt b/Documentation/user-manual.txt
index a085ca1..bd77e62 100644
--- a/Documentation/user-manual.txt
+++ b/Documentation/user-manual.txt
@@ -2856,8 +2856,7 @@ between two related tree objects, since it can ignore any entries with
identical object names.
(Note: in the presence of submodules, trees may also have commits as
-entries. See gitlink:git-submodule[1] and gitlink:gitmodules.txt[1]
-for partial documentation.)
+entries. See <<submodules>> for documentation.)
Note that the files all have mode 644 or 755: git actually only pays
attention to the executable bit.
@@ -3163,12 +3162,18 @@ information as long as you have the name of the tree that it described.
Submodules
==========
-This tutorial explains how to create and publish a repository with submodules
-using the gitlink:git-submodule[1] command.
+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.
-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.
+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.
To see how submodule support works, create (for example) four example
repositories that can be used later as a submodule:
@@ -3213,8 +3218,8 @@ The `git submodule add` command does a couple of things:
- It clones the submodule under the current directory and by default checks out
the master branch.
-- It adds the submodule's clone path to the `.gitmodules` file and adds this
- file to the index, ready to be committed.
+- It adds the submodule's clone path to the gitlink:gitmodules[5] file and
+ adds this file to the index, ready to be committed.
- It adds the submodule's current commit ID to the index, ready to be
committed.
@@ -4277,5 +4282,3 @@ Write a chapter on using plumbing and writing scripts.
Alternates, clone -reference, etc.
git unpack-objects -r for recovery
-
-submodules
--
1.5.3
^ permalink raw reply related [relevance 11%]
* [PATCH] user-manual: Explain what submodules are good for.
@ 2007-09-25 12:44 14% ` Michael Smith
2007-09-25 16:09 0% ` J. Bruce Fields
0 siblings, 1 reply; 200+ results
From: Michael Smith @ 2007-09-25 12:44 UTC (permalink / raw)
To: J. Bruce Fields; +Cc: Miklos Vajna, git, Michael Smith
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.
Signed-off-by: Michael Smith <msmith@cbnco.com>
---
Documentation/user-manual.txt | 54 +++++++++++++++++++++++++++++++---------
1 files changed, 42 insertions(+), 12 deletions(-)
diff --git a/Documentation/user-manual.txt b/Documentation/user-manual.txt
index a085ca1..c7fdf25 100644
--- a/Documentation/user-manual.txt
+++ b/Documentation/user-manual.txt
@@ -2856,8 +2856,7 @@ between two related tree objects, since it can ignore any entries with
identical object names.
(Note: in the presence of submodules, trees may also have commits as
-entries. See gitlink:git-submodule[1] and gitlink:gitmodules.txt[1]
-for partial documentation.)
+entries. See <<submodules>> for documentation.)
Note that the files all have mode 644 or 755: git actually only pays
attention to the executable bit.
@@ -3163,12 +3162,45 @@ information as long as you have the name of the tree that it described.
Submodules
==========
-This tutorial explains how to create and publish a repository with submodules
-using the gitlink:git-submodule[1] command.
-
-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.
+Large projects are often composed of smaller, self-contained modules. For
+example, an embedded Linux distribution's source tree would include every
+piece of software in the distribution with some local modifications; 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.
+
+With centralized revision control systems this is often accomplished by
+including every module in one single repository. Developers can check out
+all modules or only the modules they need to work with. They can even modify
+files across several modules in a single commit while moving things around
+or updating APIs and translations.
+
+Git does not allow partial checkouts, so duplicating this approach in Git
+would force developers to keep a local copy of modules they are not
+interested in touching. Commits in an enormous checkout would be slower
+than you'd expect as Git would have to scan every directory for changes.
+If modules have a lot of local history, clones would take forever.
+
+On the plus side, distributed revision control systems can much better
+integrate with external sources. In a centralized model, a single arbitrary
+snapshot of the external project is exported from its own revision control
+and then imported into the local revision control on a vendor branch. All
+the history is hidden. With distributed revision control you can clone the
+entire external history and much more easily follow development and re-merge
+local changes.
+
+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 containing project
+("superproject") can easily clone all the submodules at the same revision.
+Partial checkouts of the superproject are possible: you can tell Git to
+clone none, some or all of the submodules.
+
+The gitlink:git-submodule[1] command is available since Git 1.5.3. Users
+with Git 1.5.2 can look up the submodule commits in the repository and
+manually check them out; earlier versions won't recognize the submodules at
+all.
To see how submodule support works, create (for example) four example
repositories that can be used later as a submodule:
@@ -3213,8 +3245,8 @@ The `git submodule add` command does a couple of things:
- It clones the submodule under the current directory and by default checks out
the master branch.
-- It adds the submodule's clone path to the `.gitmodules` file and adds this
- file to the index, ready to be committed.
+- It adds the submodule's clone path to the gitlink:gitmodules[5] file and
+ adds this file to the index, ready to be committed.
- It adds the submodule's current commit ID to the index, ready to be
committed.
@@ -4277,5 +4309,3 @@ Write a chapter on using plumbing and writing scripts.
Alternates, clone -reference, etc.
git unpack-objects -r for recovery
-
-submodules
--
1.5.3
^ permalink raw reply related [relevance 14%]
* Re: [PATCH] user-manual: Explain what submodules are good for.
2007-09-25 12:44 14% ` Michael Smith
@ 2007-09-25 16:09 0% ` J. Bruce Fields
0 siblings, 0 replies; 200+ results
From: J. Bruce Fields @ 2007-09-25 16:09 UTC (permalink / raw)
To: Michael Smith; +Cc: Miklos Vajna, git
On Tue, Sep 25, 2007 at 08:44:38AM -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.
Looks good to me; thanks!
Acked-by: J. Bruce Fields <bfields@citi.umich.edu>
--b.
> Signed-off-by: Michael Smith <msmith@cbnco.com>
> ---
> Documentation/user-manual.txt | 54 +++++++++++++++++++++++++++++++---------
> 1 files changed, 42 insertions(+), 12 deletions(-)
>
> diff --git a/Documentation/user-manual.txt b/Documentation/user-manual.txt
> index a085ca1..c7fdf25 100644
> --- a/Documentation/user-manual.txt
> +++ b/Documentation/user-manual.txt
> @@ -2856,8 +2856,7 @@ between two related tree objects, since it can ignore any entries with
> identical object names.
>
> (Note: in the presence of submodules, trees may also have commits as
> -entries. See gitlink:git-submodule[1] and gitlink:gitmodules.txt[1]
> -for partial documentation.)
> +entries. See <<submodules>> for documentation.)
>
> Note that the files all have mode 644 or 755: git actually only pays
> attention to the executable bit.
> @@ -3163,12 +3162,45 @@ information as long as you have the name of the tree that it described.
> Submodules
> ==========
>
> -This tutorial explains how to create and publish a repository with submodules
> -using the gitlink:git-submodule[1] command.
> -
> -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.
> +Large projects are often composed of smaller, self-contained modules. For
> +example, an embedded Linux distribution's source tree would include every
> +piece of software in the distribution with some local modifications; 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.
> +
> +With centralized revision control systems this is often accomplished by
> +including every module in one single repository. Developers can check out
> +all modules or only the modules they need to work with. They can even modify
> +files across several modules in a single commit while moving things around
> +or updating APIs and translations.
> +
> +Git does not allow partial checkouts, so duplicating this approach in Git
> +would force developers to keep a local copy of modules they are not
> +interested in touching. Commits in an enormous checkout would be slower
> +than you'd expect as Git would have to scan every directory for changes.
> +If modules have a lot of local history, clones would take forever.
> +
> +On the plus side, distributed revision control systems can much better
> +integrate with external sources. In a centralized model, a single arbitrary
> +snapshot of the external project is exported from its own revision control
> +and then imported into the local revision control on a vendor branch. All
> +the history is hidden. With distributed revision control you can clone the
> +entire external history and much more easily follow development and re-merge
> +local changes.
> +
> +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 containing project
> +("superproject") can easily clone all the submodules at the same revision.
> +Partial checkouts of the superproject are possible: you can tell Git to
> +clone none, some or all of the submodules.
> +
> +The gitlink:git-submodule[1] command is available since Git 1.5.3. Users
> +with Git 1.5.2 can look up the submodule commits in the repository and
> +manually check them out; earlier versions won't recognize the submodules at
> +all.
>
> To see how submodule support works, create (for example) four example
> repositories that can be used later as a submodule:
> @@ -3213,8 +3245,8 @@ The `git submodule add` command does a couple of things:
>
> - It clones the submodule under the current directory and by default checks out
> the master branch.
> -- It adds the submodule's clone path to the `.gitmodules` file and adds this
> - file to the index, ready to be committed.
> +- It adds the submodule's clone path to the gitlink:gitmodules[5] file and
> + adds this file to the index, ready to be committed.
> - It adds the submodule's current commit ID to the index, ready to be
> committed.
>
> @@ -4277,5 +4309,3 @@ Write a chapter on using plumbing and writing scripts.
> Alternates, clone -reference, etc.
>
> git unpack-objects -r for recovery
> -
> -submodules
> --
> 1.5.3
>
^ permalink raw reply [relevance 0%]
* [PATCH 3/4] Implement git commit as a builtin command.
@ 2007-09-27 4:50 2% ` Kristian Høgsberg
0 siblings, 0 replies; 200+ results
From: Kristian Høgsberg @ 2007-09-27 4:50 UTC (permalink / raw)
To: gitster; +Cc: git, Kristian Høgsberg
Move git-commit.sh to contrib/examples.
Signed-off-by: Kristian Høgsberg <krh@redhat.com>
---
Makefile | 9 +-
builtin-commit.c | 611 +++++++++++++++++++++++++++++++++++++++
builtin-tag.c | 3 +-
builtin.h | 3 +-
contrib/examples/git-commit.sh | 627 ++++++++++++++++++++++++++++++++++++++++
git-commit.sh | 627 ----------------------------------------
git.c | 3 +-
strbuf.h | 1 +
t/t3501-revert-cherry-pick.sh | 4 +-
t/t3901-i18n-patch.sh | 8 +-
t/test-lib.sh | 4 +-
11 files changed, 1255 insertions(+), 645 deletions(-)
create mode 100644 builtin-commit.c
create mode 100755 contrib/examples/git-commit.sh
delete mode 100755 git-commit.sh
diff --git a/Makefile b/Makefile
index d90e959..6172589 100644
--- a/Makefile
+++ b/Makefile
@@ -206,7 +206,7 @@ BASIC_LDFLAGS =
SCRIPT_SH = \
git-bisect.sh git-checkout.sh \
- git-clean.sh git-clone.sh git-commit.sh \
+ git-clean.sh git-clone.sh \
git-ls-remote.sh \
git-merge-one-file.sh git-mergetool.sh git-parse-remote.sh \
git-pull.sh git-rebase.sh git-rebase--interactive.sh \
@@ -254,7 +254,7 @@ EXTRA_PROGRAMS =
BUILT_INS = \
git-format-patch$X git-show$X git-whatchanged$X git-cherry$X \
git-get-tar-commit-id$X git-init$X git-repo-config$X \
- git-fsck-objects$X git-cherry-pick$X \
+ git-fsck-objects$X git-cherry-pick$X git-status$X\
$(patsubst builtin-%.o,git-%$X,$(BUILTIN_OBJS))
# what 'all' will build and 'install' will install, in gitexecdir
@@ -324,6 +324,7 @@ BUILTIN_OBJS = \
builtin-check-attr.o \
builtin-checkout-index.o \
builtin-check-ref-format.o \
+ builtin-commit.o \
builtin-commit-tree.o \
builtin-count-objects.o \
builtin-describe.o \
@@ -362,7 +363,6 @@ BUILTIN_OBJS = \
builtin-rev-parse.o \
builtin-revert.o \
builtin-rm.o \
- builtin-runstatus.o \
builtin-shortlog.o \
builtin-show-branch.o \
builtin-stripspace.o \
@@ -822,9 +822,6 @@ $(patsubst %.perl,%,$(SCRIPT_PERL)): % : %.perl
chmod +x $@+ && \
mv $@+ $@
-git-status: git-commit
- $(QUIET_GEN)cp $< $@+ && mv $@+ $@
-
gitweb/gitweb.cgi: gitweb/gitweb.perl
$(QUIET_GEN)$(RM) $@ $@+ && \
sed -e '1s|#!.*perl|#!$(PERL_PATH_SQ)|' \
diff --git a/builtin-commit.c b/builtin-commit.c
new file mode 100644
index 0000000..69e8b19
--- /dev/null
+++ b/builtin-commit.c
@@ -0,0 +1,611 @@
+/*
+ * Builtin "git commit"
+ *
+ * Copyright (c) 2007 Kristian Høgsberg <krh@redhat.com>
+ * Based on git-commit.sh by Junio C Hamano and Linus Torvalds
+ */
+
+#include "cache.h"
+#include "cache-tree.h"
+#include "builtin.h"
+#include "diff.h"
+#include "diffcore.h"
+#include "commit.h"
+#include "revision.h"
+#include "wt-status.h"
+#include "run-command.h"
+#include "refs.h"
+#include "log-tree.h"
+#include "strbuf.h"
+#include "utf8.h"
+#include "parse-options.h"
+
+static const char builtin_commit_usage[] =
+ "[-a | --interactive] [-s] [-v] [--no-verify] [-m <message> | -F <logfile> | (-C|-c) <commit> | --amend] [-u] [-e] [--author <author>] [--template <file>] [[-i | -o] <path>...]";
+
+static unsigned char head_sha1[20], merge_head_sha1[20];
+static char *use_message_buffer;
+static const char commit_editmsg[] = "COMMIT_EDITMSG";
+static struct lock_file lock_file;
+
+static char *logfile, *force_author, *message, *template_file;
+static char *edit_message, *use_message;
+static int all, edit_flag, also, interactive, only, no_verify, amend, signoff;
+static int quiet, verbose, untracked_files;
+
+static int no_edit, initial_commit, in_merge;
+const char *only_include_assumed;
+
+static struct option commit_options[] = {
+ { OPTION_STRING, "file", 'F', (void *) &logfile },
+ { OPTION_BOOLEAN, "all", 'a', &all },
+ { OPTION_STRING, "author", 0, (void *) &force_author },
+ { OPTION_BOOLEAN, "edit", 'e', &edit_flag },
+ { OPTION_BOOLEAN, "include", 'i', &also },
+ { OPTION_BOOLEAN, "interactive", 0, &interactive },
+ { OPTION_BOOLEAN, "only", 'o', &only },
+ { OPTION_STRING, "message", 'm', &message },
+ { OPTION_BOOLEAN, "no-verify", 'n', &no_verify },
+ { OPTION_BOOLEAN, "amend", 0, &amend },
+ { OPTION_STRING, "reedit-message", 'c', &edit_message },
+ { OPTION_STRING, "reuse-message", 'C', &use_message },
+ { OPTION_BOOLEAN, "signoff", 's', &signoff },
+ { OPTION_BOOLEAN, "quiet", 'q', &quiet },
+ { OPTION_BOOLEAN, "verbose", 'v', &verbose },
+ { OPTION_BOOLEAN, "untracked-files", 0, &untracked_files },
+ { OPTION_STRING, "template", 't', &template_file },
+ { OPTION_LAST },
+};
+
+static char *
+prepare_index(const char **files, const char *prefix)
+{
+ int fd;
+ struct tree *tree;
+ struct lock_file *next_index_lock;
+
+ fd = hold_locked_index(&lock_file, 1);
+ if (read_cache() < 0)
+ die("index file corrupt");
+
+ if (all) {
+ add_files_to_cache(0, prefix, files);
+ if (write_cache(fd, active_cache, active_nr) || close(fd))
+ die("unable to write new index file");
+ return lock_file.filename;
+ } else if (also) {
+ add_files_to_cache(fd, prefix, files);
+ if (write_cache(fd, active_cache, active_nr) || close(fd))
+ die("unable to write new index file");
+ return lock_file.filename;
+ }
+
+ if (interactive)
+ interactive_add();
+
+ if (*files == NULL) {
+ /* Commit index as-is. */
+ rollback_lock_file(&lock_file);
+ return get_index_file();
+ }
+
+ /*
+ * FIXME: Warn on unknown files. Shell script does
+ *
+ * commit_only=`git-ls-files --error-unmatch -- "$@"`
+ */
+
+ /*
+ * FIXME: shell script does
+ *
+ * git-read-tree --index-output="$TMP_INDEX" -i -m HEAD
+ *
+ * which warns about unmerged files in the index.
+ */
+
+ /* update the user index file */
+ add_files_to_cache(0, prefix, files);
+ if (write_cache(fd, active_cache, active_nr) || close(fd))
+ die("unable to write new index file");
+
+ 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");
+ }
+
+ /* Uh oh, abusing lock_file to create a garbage collected file */
+ next_index_lock = xmalloc(sizeof(*next_index_lock));
+ fd = hold_lock_file_for_update(next_index_lock,
+ git_path("next-index-%d", getpid()), 1);
+ add_files_to_cache(0, prefix, files);
+ if (write_cache(fd, active_cache, active_nr) || close(fd))
+ die("unable to write new index file");
+
+ return next_index_lock->filename;
+}
+
+static int run_status(FILE *fp, const char *index_file)
+{
+ struct wt_status s;
+
+ wt_status_prepare(&s);
+
+ if (amend) {
+ s.amend = 1;
+ s.reference = "HEAD^1";
+ }
+ s.verbose = verbose;
+ s.untracked = untracked_files;
+ s.index_file = index_file;
+ s.fp = fp;
+
+ wt_status_print(&s);
+
+ return s.commitable;
+}
+
+static const char sign_off_header[] = "Signed-off-by: ";
+
+static int prepare_log_message(const char *index_file)
+{
+ struct stat statbuf;
+ int commitable;
+ struct strbuf sb;
+ char *buffer;
+ FILE *fp;
+
+ strbuf_init(&sb, 0);
+ if (message) {
+ strbuf_add(&sb, message, strlen(message));
+ } else if (logfile && !strcmp(logfile, "-")) {
+ if (isatty(0))
+ fprintf(stderr, "(reading log message from standard input)\n");
+ if (strbuf_read(&sb, 0, 0) < 0)
+ die("could not read log from standard input");
+ } else if (logfile) {
+ if (strbuf_read_file(&sb, logfile) < 0)
+ die("could not read log file '%s': %s",
+ logfile, strerror(errno));
+ } else if (use_message) {
+ buffer = strstr(use_message_buffer, "\n\n");
+ if (!buffer || buffer[2] == '\0')
+ die("commit has empty message");
+ strbuf_add(&sb, buffer + 2, strlen(buffer + 2));
+ } else if (!stat(git_path("MERGE_MSG"), &statbuf)) {
+ if (strbuf_read_file(&sb, git_path("MERGE_MSG")) < 0)
+ die("could not read MERGE_MSG: %s", strerror(errno));
+ } else if (!stat(git_path("SQUASH_MSG"), &statbuf)) {
+ if (strbuf_read_file(&sb, git_path("SQUASH_MSG")) < 0)
+ die("could not read SQUASH_MSG: %s", strerror(errno));
+ } else if (!stat(template_file, &statbuf)) {
+ if (strbuf_read_file(&sb, template_file) < 0)
+ die("could not read %s: %s",
+ template_file, strerror(errno));
+ }
+
+ fp = fopen(git_path(commit_editmsg), "w");
+ if (fp == NULL)
+ die("could not open %s\n", git_path(commit_editmsg));
+
+ stripspace(&sb, 0);
+ if (fwrite(sb.buf, 1, sb.len, fp) < sb.len)
+ die("could not write commit template: %s\n",
+ strerror(errno));
+
+ if (signoff) {
+ const char *info, *bol;
+
+ info = git_committer_info(1);
+ strbuf_addch(&sb, '\0');
+ bol = strrchr(sb.buf + sb.len - 1, '\n');
+ if (!bol || prefixcmp(bol, sign_off_header))
+ fprintf(fp, "\n");
+ fprintf(fp, "%s%s\n", sign_off_header, git_committer_info(1));
+ }
+
+ strbuf_release(&sb);
+
+ if (in_merge && !no_edit) {
+ fprintf(fp,
+ "#\n"
+ "# It looks like you may be committing a MERGE.\n"
+ "# If this is not correct, please remove the file\n"
+ "# %s\n"
+ "# and try again.\n"
+ "#\n",
+ git_path("MERGE_HEAD"));
+ }
+
+ fprintf(fp,
+ "\n"
+ "# Please enter the commit message for your changes.\n"
+ "# (Comment lines starting with '#' will not be included)\n");
+ if (only_include_assumed)
+ fprintf(fp, "# %s\n", only_include_assumed);
+
+ commitable = run_status(fp, index_file);
+
+ fclose(fp);
+
+ return commitable;
+}
+
+/* Find out if the message starting at position 'start' in the strbuf
+ * contains only whitespace and Signed-off-by lines. */
+static int message_is_empty(struct strbuf *sb, int start)
+{
+ struct strbuf tmpl;
+ const char *nl;
+ int eol, i;
+
+ /* See if the template is just a prefix of the message. */
+ strbuf_init(&tmpl, 0);
+ if (template_file && strbuf_read_file(&tmpl, template_file) > 0) {
+ stripspace(&tmpl, 1);
+ if (start + tmpl.len <= sb->len &&
+ memcmp(tmpl.buf, sb->buf + start, tmpl.len) == 0)
+ start += tmpl.len;
+ }
+ strbuf_release(&tmpl);
+
+ /* Check if the rest is just whitespace and Signed-of-by's. */
+ for (i = start; i < sb->len; i++) {
+ nl = memchr(sb->buf + i, '\n', sb->len - i);
+ if (nl)
+ eol = nl - sb->buf;
+ else
+ eol = sb->len;
+
+ if (strlen(sign_off_header) <= eol - i &&
+ !prefixcmp(sb->buf + i, sign_off_header)) {
+ i = eol;
+ continue;
+ }
+ while (i < eol)
+ if (!isspace(sb->buf[i++]))
+ return 0;
+ }
+
+ return 1;
+}
+
+static void determine_author_info(struct strbuf *sb)
+{
+ char *p, *eol;
+ char *name = NULL, *email = NULL;
+
+ if (use_message) {
+ p = strstr(use_message_buffer, "\nauthor");
+ if (!p)
+ die("invalid commit: %s\n", use_message);
+ p++;
+ eol = strchr(p, '\n');
+ if (!eol)
+ die("invalid commit: %s\n", use_message);
+
+ strbuf_add(sb, p, eol + 1 - p);
+ } else if (force_author) {
+ const char *eoname = strstr(force_author, " <");
+ const char *eomail = strchr(force_author, '>');
+
+ if (!eoname || !eomail)
+ die("malformed --author parameter\n");
+ name = xstrndup(force_author, eoname - force_author);
+ email = xstrndup(eoname + 2, eomail - eoname - 2);
+ strbuf_addf(sb, "author %s\n",
+ fmt_ident(name, email,
+ getenv("GIT_AUTHOR_DATE"), 1));
+ free(name);
+ free(email);
+ } else {
+ strbuf_addf(sb, "author %s\n", git_author_info(1));
+ }
+}
+
+static void parse_and_validate_options(const char ***argv)
+{
+ int f = 0;
+
+ (*argv)++;
+ while (parse_options(argv, commit_options, ARRAY_SIZE(commit_options),
+ builtin_commit_usage))
+ ;
+
+ if (logfile || message || use_message)
+ no_edit = 1;
+ if (edit_flag)
+ no_edit = 0;
+
+ if (get_sha1("HEAD", head_sha1))
+ initial_commit = 1;
+
+ if (!get_sha1("MERGE_HEAD", merge_head_sha1))
+ in_merge = 1;
+
+ /* Sanity check options */
+ if (amend && initial_commit)
+ die("You have nothing to amend.");
+ if (amend && in_merge)
+ die("You are in the middle of a merger -- cannot amend.");
+
+ if (use_message)
+ f++;
+ if (edit_message)
+ f++;
+ if (logfile)
+ f++;
+ if (f > 1)
+ die("Only one of -c/-C/-F can be used.");
+ if (message && f > 0)
+ die("Option -m cannot be combined with -c/-C/-F.");
+ if (edit_message)
+ use_message = edit_message;
+ if (amend)
+ use_message = "HEAD";
+ if (use_message) {
+ unsigned char sha1[20];
+ static char utf8[] = "UTF-8";
+ const char *out_enc;
+ char *enc, *end;
+ struct commit *commit;
+
+ if (get_sha1(use_message, sha1))
+ die("could not lookup commit %s", use_message);
+ commit = lookup_commit(sha1);
+ if (!commit || parse_commit(commit))
+ die("could not parse commit %s", use_message);
+
+ enc = strstr(commit->buffer, "\nencoding");
+ if (enc) {
+ end = strchr(enc + 10, '\n');
+ enc = xstrndup(enc + 10, end - (enc + 10));
+ } else {
+ enc = utf8;
+ }
+ out_enc = git_commit_encoding ? git_commit_encoding : utf8;
+
+ use_message_buffer =
+ reencode_string(commit->buffer, out_enc, enc);
+ if (enc != utf8)
+ free(enc);
+ }
+
+ if (also && only)
+ die("Only one of --include/--only can be used.");
+ if (!*argv && (also || (only && !amend)))
+ die("No paths with --include/--only does not make sense.");
+ if (!*argv && only && amend)
+ only_include_assumed = "Clever... amending the last one with dirty index.";
+ if (*argv && !also && !only) {
+ only_include_assumed = "Explicit paths specified without -i nor -o; assuming --only paths...";
+ also = 0;
+ }
+
+ if (all && interactive)
+ die("Cannot use -a, --interactive or -i at the same time.");
+ else if (all && **argv)
+ die("Paths with -a does not make sense.");
+ else if (interactive && **argv)
+ die("Paths with --interactive does not make sense.");
+}
+
+int cmd_status(int argc, const char **argv, const char *prefix)
+{
+ const char *index_file;
+ int commitable;
+
+ git_config(git_status_config);
+
+ parse_and_validate_options(&argv);
+
+ index_file = prepare_index(argv, prefix);
+
+ commitable = run_status(stdout, index_file);
+
+ rollback_lock_file(&lock_file);
+
+ return commitable ? 0 : 1;
+}
+
+static int run_hook(const char *index_file, const char *name, const char *arg)
+{
+ struct child_process hook;
+ const char *argv[3], *env[2];
+ char index[PATH_MAX];
+
+ argv[0] = git_path("hooks/%s", name);
+ argv[1] = arg;
+ argv[2] = NULL;
+ snprintf(index, sizeof(index), "GIT_INDEX_FILE=%s", index_file);
+ env[0] = index;
+ env[1] = NULL;
+
+ if (access(argv[0], X_OK) < 0)
+ return 0;
+
+ memset(&hook, 0, sizeof(hook));
+ hook.argv = argv;
+ hook.no_stdin = 1;
+ hook.stdout_to_stderr = 1;
+ hook.env = env;
+
+ return run_command(&hook);
+}
+
+static void print_summary(const char *prefix, const unsigned char *sha1)
+{
+ struct rev_info rev;
+ struct commit *commit;
+
+ commit = lookup_commit(sha1);
+ if (!commit)
+ die("couldn't look up newly created commit\n");
+ if (!commit || parse_commit(commit))
+ die("could not parse newly created commit");
+
+ init_revisions(&rev, prefix);
+ setup_revisions(0, NULL, &rev, NULL);
+
+ rev.abbrev = 0;
+ rev.diff = 1;
+ rev.diffopt.output_format =
+ DIFF_FORMAT_SHORTSTAT | DIFF_FORMAT_SUMMARY;
+
+ rev.verbose_header = 1;
+ rev.show_root_diff = 1;
+ rev.commit_format = get_commit_format("format:%h: %s");
+ rev.always_show_header = 1;
+
+ printf("Created %scommit ", initial_commit ? "initial " : "");
+
+ log_tree_commit(&rev, commit);
+}
+
+int git_commit_config(const char *k, const char *v)
+{
+ if (!strcmp(k, "commit.template")) {
+ template_file = xstrdup(v);
+ return 0;
+ }
+
+ return git_status_config(k, v);
+}
+
+static const char commit_utf8_warn[] =
+"Warning: commit message does not conform to UTF-8.\n"
+"You may want to amend it after fixing the message, or set the config\n"
+"variable i18n.commitencoding to the encoding your project uses.\n";
+
+int cmd_commit(int argc, const char **argv, const char *prefix)
+{
+ int header_len, parent_count = 0;
+ struct strbuf sb;
+ const char *index_file, *reflog_msg;
+ char *nl, *header_line;
+ unsigned char commit_sha1[20];
+ struct ref_lock *ref_lock;
+
+ git_config(git_commit_config);
+
+ parse_and_validate_options(&argv);
+
+ index_file = prepare_index(argv, prefix);
+
+ if (run_hook(index_file, "pre-commit", NULL))
+ exit(1);
+
+ if (!prepare_log_message(index_file) && !in_merge) {
+ run_status(stdout, index_file);
+ unlink(commit_editmsg);
+ return 1;
+ }
+
+ strbuf_init(&sb, 0);
+
+ /* Start building up the commit header */
+ read_cache_from(index_file);
+ active_cache_tree = cache_tree();
+ if (cache_tree_update(active_cache_tree,
+ active_cache, active_nr, 0, 0) < 0)
+ die("Error building trees");
+ strbuf_addf(&sb, "tree %s\n",
+ sha1_to_hex(active_cache_tree->sha1));
+
+ /* Determine parents */
+ if (initial_commit) {
+ reflog_msg = "commit (initial)";
+ parent_count = 0;
+ } else if (amend) {
+ struct commit_list *c;
+ struct commit *commit;
+
+ reflog_msg = "commit (amend)";
+ commit = lookup_commit(head_sha1);
+ if (!commit || parse_commit(commit))
+ die("could not parse HEAD commit");
+
+ for (c = commit->parents; c; c = c->next)
+ strbuf_addf(&sb, "parent %s\n",
+ sha1_to_hex(c->item->object.sha1));
+ } else if (in_merge) {
+ struct strbuf m;
+ FILE *fp;
+
+ reflog_msg = "commit (merge)";
+ strbuf_addf(&sb, "parent %s\n", sha1_to_hex(head_sha1));
+ strbuf_init(&m, 0);
+ fp = fopen(git_path("MERGE_HEAD"), "r");
+ if (fp == NULL)
+ die("could not open %s for reading: %s",
+ git_path("MERGE_HEAD"), strerror(errno));
+ while (strbuf_getline(&m, fp, '\n') != EOF)
+ strbuf_addf(&sb, "parent %s\n", m.buf);
+ fclose(fp);
+ strbuf_release(&m);
+ } else {
+ reflog_msg = "commit";
+ strbuf_addf(&sb, "parent %s\n", sha1_to_hex(head_sha1));
+ }
+
+ determine_author_info(&sb);
+ strbuf_addf(&sb, "committer %s\n", git_committer_info(1));
+ if (!is_encoding_utf8(git_commit_encoding))
+ strbuf_addf(&sb, "encoding %s\n", git_commit_encoding);
+ strbuf_addch(&sb, '\n');
+
+ /* Get the commit message and validate it */
+ header_len = sb.len;
+ if (!no_edit) {
+ fprintf(stderr, "launching editor, log %s\n", logfile);
+ launch_editor(git_path(commit_editmsg), &sb);
+ }
+ else if (strbuf_read_file(&sb, git_path(commit_editmsg)) < 0)
+ die("could not read commit message\n");
+ if (run_hook(index_file, "commit-msg", commit_editmsg))
+ exit(1);
+ stripspace(&sb, 1);
+ if (sb.len < header_len ||
+ message_is_empty(&sb, header_len))
+ die("* no commit message? aborting commit.");
+ strbuf_addch(&sb, '\0');
+ if (is_encoding_utf8(git_commit_encoding) && !is_utf8(sb.buf))
+ fprintf(stderr, commit_utf8_warn);
+
+ if (write_sha1_file(sb.buf, sb.len - 1, commit_type, commit_sha1))
+ die("failed to write commit object");
+
+ ref_lock = lock_any_ref_for_update("HEAD",
+ initial_commit ? NULL : head_sha1,
+ 0);
+
+ nl = strchr(sb.buf + header_len, '\n');
+ header_line = xstrndup(sb.buf + header_len,
+ nl - (sb.buf + header_len));
+ strbuf_release(&sb);
+ strbuf_addf(&sb, "%s: %s\n", reflog_msg, header_line);
+ strbuf_addch(&sb, '\0');
+ free(header_line);
+
+ if (!ref_lock)
+ die("cannot lock HEAD ref");
+ if (write_ref_sha1(ref_lock, commit_sha1, sb.buf) < 0)
+ die("cannot update HEAD ref");
+
+ unlink(git_path("MERGE_HEAD"));
+ unlink(git_path("MERGE_MSG"));
+
+ if (lock_file.filename[0] && commit_locked_index(&lock_file))
+ die("failed to write new index");
+
+ rerere();
+
+ run_hook(index_file, "post-commit", NULL);
+
+ if (!quiet)
+ print_summary(prefix, commit_sha1);
+
+ return 0;
+}
diff --git a/builtin-tag.c b/builtin-tag.c
index a1a2cf0..0a36a5d 100644
--- a/builtin-tag.c
+++ b/builtin-tag.c
@@ -17,12 +17,11 @@ static const char builtin_tag_usage[] =
static char signingkey[1000];
-static void launch_editor(const char *path, struct strbuf *buffer)
+void launch_editor(const char *path, struct strbuf *buffer)
{
const char *editor, *terminal;
struct child_process child;
const char *args[3];
- int fd;
editor = getenv("GIT_EDITOR");
if (!editor && editor_program)
diff --git a/builtin.h b/builtin.h
index 65cc0fb..470a788 100644
--- a/builtin.h
+++ b/builtin.h
@@ -23,6 +23,7 @@ extern int cmd_check_attr(int argc, const char **argv, const char *prefix);
extern int cmd_check_ref_format(int argc, const char **argv, const char *prefix);
extern int cmd_cherry(int argc, const char **argv, const char *prefix);
extern int cmd_cherry_pick(int argc, const char **argv, const char *prefix);
+extern int cmd_commit(int argc, const char **argv, const char *prefix);
extern int cmd_commit_tree(int argc, const char **argv, const char *prefix);
extern int cmd_count_objects(int argc, const char **argv, const char *prefix);
extern int cmd_describe(int argc, const char **argv, const char *prefix);
@@ -67,10 +68,10 @@ extern int cmd_rev_list(int argc, const char **argv, const char *prefix);
extern int cmd_rev_parse(int argc, const char **argv, const char *prefix);
extern int cmd_revert(int argc, const char **argv, const char *prefix);
extern int cmd_rm(int argc, const char **argv, const char *prefix);
-extern int cmd_runstatus(int argc, const char **argv, const char *prefix);
extern int cmd_shortlog(int argc, const char **argv, const char *prefix);
extern int cmd_show(int argc, const char **argv, const char *prefix);
extern int cmd_show_branch(int argc, const char **argv, const char *prefix);
+extern int cmd_status(int argc, const char **argv, const char *prefix);
extern int cmd_stripspace(int argc, const char **argv, const char *prefix);
extern int cmd_symbolic_ref(int argc, const char **argv, const char *prefix);
extern int cmd_tag(int argc, const char **argv, const char *prefix);
diff --git a/contrib/examples/git-commit.sh b/contrib/examples/git-commit.sh
new file mode 100755
index 0000000..44ccc44
--- /dev/null
+++ b/contrib/examples/git-commit.sh
@@ -0,0 +1,627 @@
+#!/bin/sh
+#
+# Copyright (c) 2005 Linus Torvalds
+# Copyright (c) 2006 Junio C Hamano
+
+USAGE='[-a | --interactive] [-s] [-v] [--no-verify] [-m <message> | -F <logfile> | (-C|-c) <commit> | --amend] [-u] [-e] [--author <author>] [--template <file>] [[-i | -o] <path>...]'
+SUBDIRECTORY_OK=Yes
+. git-sh-setup
+require_work_tree
+
+git rev-parse --verify HEAD >/dev/null 2>&1 || initial_commit=t
+
+case "$0" in
+*status)
+ status_only=t
+ ;;
+*commit)
+ status_only=
+ ;;
+esac
+
+refuse_partial () {
+ echo >&2 "$1"
+ echo >&2 "You might have meant to say 'git commit -i paths...', perhaps?"
+ exit 1
+}
+
+THIS_INDEX="$GIT_DIR/index"
+NEXT_INDEX="$GIT_DIR/next-index$$"
+rm -f "$NEXT_INDEX"
+save_index () {
+ cp -p "$THIS_INDEX" "$NEXT_INDEX"
+}
+
+run_status () {
+ # If TMP_INDEX is defined, that means we are doing
+ # "--only" partial commit, and that index file is used
+ # to build the tree for the commit. Otherwise, if
+ # NEXT_INDEX exists, that is the index file used to
+ # make the commit. Otherwise we are using as-is commit
+ # so the regular index file is what we use to compare.
+ if test '' != "$TMP_INDEX"
+ then
+ GIT_INDEX_FILE="$TMP_INDEX"
+ export GIT_INDEX_FILE
+ elif test -f "$NEXT_INDEX"
+ then
+ GIT_INDEX_FILE="$NEXT_INDEX"
+ export GIT_INDEX_FILE
+ fi
+
+ if test "$status_only" = "t" -o "$use_status_color" = "t"; then
+ color=
+ else
+ color=--nocolor
+ fi
+ git runstatus ${color} \
+ ${verbose:+--verbose} \
+ ${amend:+--amend} \
+ ${untracked_files:+--untracked}
+}
+
+trap '
+ test -z "$TMP_INDEX" || {
+ test -f "$TMP_INDEX" && rm -f "$TMP_INDEX"
+ }
+ rm -f "$NEXT_INDEX"
+' 0
+
+################################################################
+# Command line argument parsing and sanity checking
+
+all=
+also=
+interactive=
+only=
+logfile=
+use_commit=
+amend=
+edit_flag=
+no_edit=
+log_given=
+log_message=
+verify=t
+quiet=
+verbose=
+signoff=
+force_author=
+only_include_assumed=
+untracked_files=
+templatefile="`git config commit.template`"
+while test $# != 0
+do
+ case "$1" in
+ -F|--F|-f|--f|--fi|--fil|--file)
+ case "$#" in 1) usage ;; esac
+ shift
+ no_edit=t
+ log_given=t$log_given
+ logfile="$1"
+ ;;
+ -F*|-f*)
+ no_edit=t
+ log_given=t$log_given
+ logfile="${1#-[Ff]}"
+ ;;
+ --F=*|--f=*|--fi=*|--fil=*|--file=*)
+ no_edit=t
+ log_given=t$log_given
+ logfile="${1#*=}"
+ ;;
+ -a|--a|--al|--all)
+ all=t
+ ;;
+ --au=*|--aut=*|--auth=*|--autho=*|--author=*)
+ force_author="${1#*=}"
+ ;;
+ --au|--aut|--auth|--autho|--author)
+ case "$#" in 1) usage ;; esac
+ shift
+ force_author="$1"
+ ;;
+ -e|--e|--ed|--edi|--edit)
+ edit_flag=t
+ ;;
+ -i|--i|--in|--inc|--incl|--inclu|--includ|--include)
+ also=t
+ ;;
+ --int|--inte|--inter|--intera|--interac|--interact|--interacti|\
+ --interactiv|--interactive)
+ interactive=t
+ ;;
+ -o|--o|--on|--onl|--only)
+ only=t
+ ;;
+ -m|--m|--me|--mes|--mess|--messa|--messag|--message)
+ case "$#" in 1) usage ;; esac
+ shift
+ log_given=m$log_given
+ log_message="${log_message:+${log_message}
+
+}$1"
+ no_edit=t
+ ;;
+ -m*)
+ log_given=m$log_given
+ log_message="${log_message:+${log_message}
+
+}${1#-m}"
+ no_edit=t
+ ;;
+ --m=*|--me=*|--mes=*|--mess=*|--messa=*|--messag=*|--message=*)
+ log_given=m$log_given
+ log_message="${log_message:+${log_message}
+
+}${1#*=}"
+ no_edit=t
+ ;;
+ -n|--n|--no|--no-|--no-v|--no-ve|--no-ver|--no-veri|--no-verif|\
+ --no-verify)
+ verify=
+ ;;
+ --a|--am|--ame|--amen|--amend)
+ amend=t
+ use_commit=HEAD
+ ;;
+ -c)
+ case "$#" in 1) usage ;; esac
+ shift
+ log_given=t$log_given
+ use_commit="$1"
+ no_edit=
+ ;;
+ --ree=*|--reed=*|--reedi=*|--reedit=*|--reedit-=*|--reedit-m=*|\
+ --reedit-me=*|--reedit-mes=*|--reedit-mess=*|--reedit-messa=*|\
+ --reedit-messag=*|--reedit-message=*)
+ log_given=t$log_given
+ use_commit="${1#*=}"
+ no_edit=
+ ;;
+ --ree|--reed|--reedi|--reedit|--reedit-|--reedit-m|--reedit-me|\
+ --reedit-mes|--reedit-mess|--reedit-messa|--reedit-messag|\
+ --reedit-message)
+ case "$#" in 1) usage ;; esac
+ shift
+ log_given=t$log_given
+ use_commit="$1"
+ no_edit=
+ ;;
+ -C)
+ case "$#" in 1) usage ;; esac
+ shift
+ log_given=t$log_given
+ use_commit="$1"
+ no_edit=t
+ ;;
+ --reu=*|--reus=*|--reuse=*|--reuse-=*|--reuse-m=*|--reuse-me=*|\
+ --reuse-mes=*|--reuse-mess=*|--reuse-messa=*|--reuse-messag=*|\
+ --reuse-message=*)
+ log_given=t$log_given
+ use_commit="${1#*=}"
+ no_edit=t
+ ;;
+ --reu|--reus|--reuse|--reuse-|--reuse-m|--reuse-me|--reuse-mes|\
+ --reuse-mess|--reuse-messa|--reuse-messag|--reuse-message)
+ case "$#" in 1) usage ;; esac
+ shift
+ log_given=t$log_given
+ use_commit="$1"
+ no_edit=t
+ ;;
+ -s|--s|--si|--sig|--sign|--signo|--signof|--signoff)
+ signoff=t
+ ;;
+ -t|--t|--te|--tem|--temp|--templ|--templa|--templat|--template)
+ case "$#" in 1) usage ;; esac
+ shift
+ templatefile="$1"
+ no_edit=
+ ;;
+ -q|--q|--qu|--qui|--quie|--quiet)
+ quiet=t
+ ;;
+ -v|--v|--ve|--ver|--verb|--verbo|--verbos|--verbose)
+ verbose=t
+ ;;
+ -u|--u|--un|--unt|--untr|--untra|--untrac|--untrack|--untracke|\
+ --untracked|--untracked-|--untracked-f|--untracked-fi|--untracked-fil|\
+ --untracked-file|--untracked-files)
+ untracked_files=t
+ ;;
+ --)
+ shift
+ break
+ ;;
+ -*)
+ usage
+ ;;
+ *)
+ break
+ ;;
+ esac
+ shift
+done
+case "$edit_flag" in t) no_edit= ;; esac
+
+################################################################
+# Sanity check options
+
+case "$amend,$initial_commit" in
+t,t)
+ die "You do not have anything to amend." ;;
+t,)
+ if [ -f "$GIT_DIR/MERGE_HEAD" ]; then
+ die "You are in the middle of a merge -- cannot amend."
+ fi ;;
+esac
+
+case "$log_given" in
+tt*)
+ die "Only one of -c/-C/-F can be used." ;;
+*tm*|*mt*)
+ die "Option -m cannot be combined with -c/-C/-F." ;;
+esac
+
+case "$#,$also,$only,$amend" in
+*,t,t,*)
+ die "Only one of --include/--only can be used." ;;
+0,t,,* | 0,,t,)
+ die "No paths with --include/--only does not make sense." ;;
+0,,t,t)
+ only_include_assumed="# Clever... amending the last one with dirty index." ;;
+0,,,*)
+ ;;
+*,,,*)
+ only_include_assumed="# Explicit paths specified without -i nor -o; assuming --only paths..."
+ also=
+ ;;
+esac
+unset only
+case "$all,$interactive,$also,$#" in
+*t,*t,*)
+ die "Cannot use -a, --interactive or -i at the same time." ;;
+t,,[1-9]*)
+ die "Paths with -a does not make sense." ;;
+,t,[1-9]*)
+ die "Paths with --interactive does not make sense." ;;
+,,t,0)
+ die "No paths with -i does not make sense." ;;
+esac
+
+if test ! -z "$templatefile" -a -z "$log_given"
+then
+ if test ! -f "$templatefile"
+ then
+ die "Commit template file does not exist."
+ fi
+fi
+
+################################################################
+# Prepare index to have a tree to be committed
+
+case "$all,$also" in
+t,)
+ if test ! -f "$THIS_INDEX"
+ then
+ die 'nothing to commit (use "git add file1 file2" to include for commit)'
+ fi
+ save_index &&
+ (
+ cd_to_toplevel &&
+ GIT_INDEX_FILE="$NEXT_INDEX" &&
+ export GIT_INDEX_FILE &&
+ git diff-files --name-only -z |
+ git update-index --remove -z --stdin
+ ) || exit
+ ;;
+,t)
+ save_index &&
+ git ls-files --error-unmatch -- "$@" >/dev/null || exit
+
+ git diff-files --name-only -z -- "$@" |
+ (
+ cd_to_toplevel &&
+ GIT_INDEX_FILE="$NEXT_INDEX" &&
+ export GIT_INDEX_FILE &&
+ git update-index --remove -z --stdin
+ ) || exit
+ ;;
+,)
+ if test "$interactive" = t; then
+ git add --interactive || exit
+ fi
+ case "$#" in
+ 0)
+ ;; # commit as-is
+ *)
+ if test -f "$GIT_DIR/MERGE_HEAD"
+ then
+ refuse_partial "Cannot do a partial commit during a merge."
+ fi
+
+ TMP_INDEX="$GIT_DIR/tmp-index$$"
+ W=
+ test -z "$initial_commit" && W=--with-tree=HEAD
+ commit_only=`git ls-files --error-unmatch $W -- "$@"` || exit
+
+ # Build a temporary index and update the real index
+ # the same way.
+ if test -z "$initial_commit"
+ then
+ GIT_INDEX_FILE="$THIS_INDEX" \
+ git read-tree --index-output="$TMP_INDEX" -i -m HEAD
+ else
+ rm -f "$TMP_INDEX"
+ fi || exit
+
+ printf '%s\n' "$commit_only" |
+ GIT_INDEX_FILE="$TMP_INDEX" \
+ git update-index --add --remove --stdin &&
+
+ save_index &&
+ printf '%s\n' "$commit_only" |
+ (
+ GIT_INDEX_FILE="$NEXT_INDEX"
+ export GIT_INDEX_FILE
+ git update-index --add --remove --stdin
+ ) || exit
+ ;;
+ esac
+ ;;
+esac
+
+################################################################
+# If we do as-is commit, the index file will be THIS_INDEX,
+# otherwise NEXT_INDEX after we make this commit. We leave
+# the index as is if we abort.
+
+if test -f "$NEXT_INDEX"
+then
+ USE_INDEX="$NEXT_INDEX"
+else
+ USE_INDEX="$THIS_INDEX"
+fi
+
+case "$status_only" in
+t)
+ # This will silently fail in a read-only repository, which is
+ # what we want.
+ GIT_INDEX_FILE="$USE_INDEX" git update-index -q --unmerged --refresh
+ run_status
+ exit $?
+ ;;
+'')
+ GIT_INDEX_FILE="$USE_INDEX" git update-index -q --refresh || exit
+ ;;
+esac
+
+################################################################
+# Grab commit message, write out tree and make commit.
+
+if test t = "$verify" && test -x "$GIT_DIR"/hooks/pre-commit
+then
+ GIT_INDEX_FILE="${TMP_INDEX:-${USE_INDEX}}" "$GIT_DIR"/hooks/pre-commit \
+ || exit
+fi
+
+if test "$log_message" != ''
+then
+ printf '%s\n' "$log_message"
+elif test "$logfile" != ""
+then
+ if test "$logfile" = -
+ then
+ test -t 0 &&
+ echo >&2 "(reading log message from standard input)"
+ cat
+ else
+ cat <"$logfile"
+ fi
+elif test "$use_commit" != ""
+then
+ encoding=$(git config i18n.commitencoding || echo UTF-8)
+ git show -s --pretty=raw --encoding="$encoding" "$use_commit" |
+ sed -e '1,/^$/d' -e 's/^ //'
+elif test -f "$GIT_DIR/MERGE_MSG"
+then
+ cat "$GIT_DIR/MERGE_MSG"
+elif test -f "$GIT_DIR/SQUASH_MSG"
+then
+ cat "$GIT_DIR/SQUASH_MSG"
+elif test "$templatefile" != ""
+then
+ cat "$templatefile"
+fi | git stripspace >"$GIT_DIR"/COMMIT_EDITMSG
+
+case "$signoff" in
+t)
+ sign=$(git-var GIT_COMMITTER_IDENT | sed -e '
+ s/>.*/>/
+ s/^/Signed-off-by: /
+ ')
+ blank_before_signoff=
+ tail -n 1 "$GIT_DIR"/COMMIT_EDITMSG |
+ grep 'Signed-off-by:' >/dev/null || blank_before_signoff='
+'
+ tail -n 1 "$GIT_DIR"/COMMIT_EDITMSG |
+ grep "$sign"$ >/dev/null ||
+ printf '%s%s\n' "$blank_before_signoff" "$sign" \
+ >>"$GIT_DIR"/COMMIT_EDITMSG
+ ;;
+esac
+
+if test -f "$GIT_DIR/MERGE_HEAD" && test -z "$no_edit"; then
+ echo "#"
+ echo "# It looks like you may be committing a MERGE."
+ echo "# If this is not correct, please remove the file"
+ printf '%s\n' "# $GIT_DIR/MERGE_HEAD"
+ echo "# and try again"
+ echo "#"
+fi >>"$GIT_DIR"/COMMIT_EDITMSG
+
+# Author
+if test '' != "$use_commit"
+then
+ eval "$(get_author_ident_from_commit "$use_commit")"
+ export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_AUTHOR_DATE
+fi
+if test '' != "$force_author"
+then
+ GIT_AUTHOR_NAME=`expr "z$force_author" : 'z\(.*[^ ]\) *<.*'` &&
+ GIT_AUTHOR_EMAIL=`expr "z$force_author" : '.*\(<.*\)'` &&
+ test '' != "$GIT_AUTHOR_NAME" &&
+ test '' != "$GIT_AUTHOR_EMAIL" ||
+ die "malformed --author parameter"
+ export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL
+fi
+
+PARENTS="-p HEAD"
+if test -z "$initial_commit"
+then
+ rloga='commit'
+ if [ -f "$GIT_DIR/MERGE_HEAD" ]; then
+ rloga='commit (merge)'
+ PARENTS="-p HEAD "`sed -e 's/^/-p /' "$GIT_DIR/MERGE_HEAD"`
+ elif test -n "$amend"; then
+ rloga='commit (amend)'
+ PARENTS=$(git cat-file commit HEAD |
+ sed -n -e '/^$/q' -e 's/^parent /-p /p')
+ fi
+ current="$(git rev-parse --verify HEAD)"
+else
+ if [ -z "$(git ls-files)" ]; then
+ echo >&2 'nothing to commit (use "git add file1 file2" to include for commit)'
+ exit 1
+ fi
+ PARENTS=""
+ rloga='commit (initial)'
+ current=''
+fi
+set_reflog_action "$rloga"
+
+if test -z "$no_edit"
+then
+ {
+ echo ""
+ echo "# Please enter the commit message for your changes."
+ echo "# (Comment lines starting with '#' will not be included)"
+ test -z "$only_include_assumed" || echo "$only_include_assumed"
+ run_status
+ } >>"$GIT_DIR"/COMMIT_EDITMSG
+else
+ # we need to check if there is anything to commit
+ run_status >/dev/null
+fi
+if [ "$?" != "0" -a ! -f "$GIT_DIR/MERGE_HEAD" ]
+then
+ rm -f "$GIT_DIR/COMMIT_EDITMSG" "$GIT_DIR/SQUASH_MSG"
+ use_status_color=t
+ run_status
+ exit 1
+fi
+
+case "$no_edit" in
+'')
+ git-var GIT_AUTHOR_IDENT > /dev/null || die
+ git-var GIT_COMMITTER_IDENT > /dev/null || die
+ git_editor "$GIT_DIR/COMMIT_EDITMSG"
+ ;;
+esac
+
+case "$verify" in
+t)
+ if test -x "$GIT_DIR"/hooks/commit-msg
+ then
+ "$GIT_DIR"/hooks/commit-msg "$GIT_DIR"/COMMIT_EDITMSG || exit
+ fi
+esac
+
+if test -z "$no_edit"
+then
+ sed -e '
+ /^diff --git a\/.*/{
+ s///
+ q
+ }
+ /^#/d
+ ' "$GIT_DIR"/COMMIT_EDITMSG
+else
+ cat "$GIT_DIR"/COMMIT_EDITMSG
+fi |
+git stripspace >"$GIT_DIR"/COMMIT_MSG
+
+# Test whether the commit message has any content we didn't supply.
+have_commitmsg=
+grep -v -i '^Signed-off-by' "$GIT_DIR"/COMMIT_MSG |
+ git stripspace > "$GIT_DIR"/COMMIT_BAREMSG
+
+# Is the commit message totally empty?
+if test -s "$GIT_DIR"/COMMIT_BAREMSG
+then
+ if test "$templatefile" != ""
+ then
+ # Test whether this is just the unaltered template.
+ if cnt=`sed -e '/^#/d' < "$templatefile" |
+ git stripspace |
+ diff "$GIT_DIR"/COMMIT_BAREMSG - |
+ wc -l` &&
+ test 0 -lt $cnt
+ then
+ have_commitmsg=t
+ fi
+ else
+ # No template, so the content in the commit message must
+ # have come from the user.
+ have_commitmsg=t
+ fi
+fi
+
+rm -f "$GIT_DIR"/COMMIT_BAREMSG
+
+if test "$have_commitmsg" = "t"
+then
+ if test -z "$TMP_INDEX"
+ then
+ tree=$(GIT_INDEX_FILE="$USE_INDEX" git write-tree)
+ else
+ tree=$(GIT_INDEX_FILE="$TMP_INDEX" git write-tree) &&
+ rm -f "$TMP_INDEX"
+ fi &&
+ commit=$(git commit-tree $tree $PARENTS <"$GIT_DIR/COMMIT_MSG") &&
+ rlogm=$(sed -e 1q "$GIT_DIR"/COMMIT_MSG) &&
+ git update-ref -m "$GIT_REFLOG_ACTION: $rlogm" HEAD $commit "$current" &&
+ rm -f -- "$GIT_DIR/MERGE_HEAD" "$GIT_DIR/MERGE_MSG" &&
+ if test -f "$NEXT_INDEX"
+ then
+ mv "$NEXT_INDEX" "$THIS_INDEX"
+ else
+ : ;# happy
+ fi
+else
+ echo >&2 "* no commit message? aborting commit."
+ false
+fi
+ret="$?"
+rm -f "$GIT_DIR/COMMIT_MSG" "$GIT_DIR/COMMIT_EDITMSG" "$GIT_DIR/SQUASH_MSG"
+
+cd_to_toplevel
+
+git rerere
+
+if test "$ret" = 0
+then
+ git gc --auto
+ if test -x "$GIT_DIR"/hooks/post-commit
+ then
+ "$GIT_DIR"/hooks/post-commit
+ fi
+ if test -z "$quiet"
+ then
+ commit=`git diff-tree --always --shortstat --pretty="format:%h: %s"\
+ --summary --root HEAD --`
+ echo "Created${initial_commit:+ initial} commit $commit"
+ fi
+fi
+
+exit "$ret"
diff --git a/git-commit.sh b/git-commit.sh
deleted file mode 100755
index 44ccc44..0000000
--- a/git-commit.sh
+++ /dev/null
@@ -1,627 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2005 Linus Torvalds
-# Copyright (c) 2006 Junio C Hamano
-
-USAGE='[-a | --interactive] [-s] [-v] [--no-verify] [-m <message> | -F <logfile> | (-C|-c) <commit> | --amend] [-u] [-e] [--author <author>] [--template <file>] [[-i | -o] <path>...]'
-SUBDIRECTORY_OK=Yes
-. git-sh-setup
-require_work_tree
-
-git rev-parse --verify HEAD >/dev/null 2>&1 || initial_commit=t
-
-case "$0" in
-*status)
- status_only=t
- ;;
-*commit)
- status_only=
- ;;
-esac
-
-refuse_partial () {
- echo >&2 "$1"
- echo >&2 "You might have meant to say 'git commit -i paths...', perhaps?"
- exit 1
-}
-
-THIS_INDEX="$GIT_DIR/index"
-NEXT_INDEX="$GIT_DIR/next-index$$"
-rm -f "$NEXT_INDEX"
-save_index () {
- cp -p "$THIS_INDEX" "$NEXT_INDEX"
-}
-
-run_status () {
- # If TMP_INDEX is defined, that means we are doing
- # "--only" partial commit, and that index file is used
- # to build the tree for the commit. Otherwise, if
- # NEXT_INDEX exists, that is the index file used to
- # make the commit. Otherwise we are using as-is commit
- # so the regular index file is what we use to compare.
- if test '' != "$TMP_INDEX"
- then
- GIT_INDEX_FILE="$TMP_INDEX"
- export GIT_INDEX_FILE
- elif test -f "$NEXT_INDEX"
- then
- GIT_INDEX_FILE="$NEXT_INDEX"
- export GIT_INDEX_FILE
- fi
-
- if test "$status_only" = "t" -o "$use_status_color" = "t"; then
- color=
- else
- color=--nocolor
- fi
- git runstatus ${color} \
- ${verbose:+--verbose} \
- ${amend:+--amend} \
- ${untracked_files:+--untracked}
-}
-
-trap '
- test -z "$TMP_INDEX" || {
- test -f "$TMP_INDEX" && rm -f "$TMP_INDEX"
- }
- rm -f "$NEXT_INDEX"
-' 0
-
-################################################################
-# Command line argument parsing and sanity checking
-
-all=
-also=
-interactive=
-only=
-logfile=
-use_commit=
-amend=
-edit_flag=
-no_edit=
-log_given=
-log_message=
-verify=t
-quiet=
-verbose=
-signoff=
-force_author=
-only_include_assumed=
-untracked_files=
-templatefile="`git config commit.template`"
-while test $# != 0
-do
- case "$1" in
- -F|--F|-f|--f|--fi|--fil|--file)
- case "$#" in 1) usage ;; esac
- shift
- no_edit=t
- log_given=t$log_given
- logfile="$1"
- ;;
- -F*|-f*)
- no_edit=t
- log_given=t$log_given
- logfile="${1#-[Ff]}"
- ;;
- --F=*|--f=*|--fi=*|--fil=*|--file=*)
- no_edit=t
- log_given=t$log_given
- logfile="${1#*=}"
- ;;
- -a|--a|--al|--all)
- all=t
- ;;
- --au=*|--aut=*|--auth=*|--autho=*|--author=*)
- force_author="${1#*=}"
- ;;
- --au|--aut|--auth|--autho|--author)
- case "$#" in 1) usage ;; esac
- shift
- force_author="$1"
- ;;
- -e|--e|--ed|--edi|--edit)
- edit_flag=t
- ;;
- -i|--i|--in|--inc|--incl|--inclu|--includ|--include)
- also=t
- ;;
- --int|--inte|--inter|--intera|--interac|--interact|--interacti|\
- --interactiv|--interactive)
- interactive=t
- ;;
- -o|--o|--on|--onl|--only)
- only=t
- ;;
- -m|--m|--me|--mes|--mess|--messa|--messag|--message)
- case "$#" in 1) usage ;; esac
- shift
- log_given=m$log_given
- log_message="${log_message:+${log_message}
-
-}$1"
- no_edit=t
- ;;
- -m*)
- log_given=m$log_given
- log_message="${log_message:+${log_message}
-
-}${1#-m}"
- no_edit=t
- ;;
- --m=*|--me=*|--mes=*|--mess=*|--messa=*|--messag=*|--message=*)
- log_given=m$log_given
- log_message="${log_message:+${log_message}
-
-}${1#*=}"
- no_edit=t
- ;;
- -n|--n|--no|--no-|--no-v|--no-ve|--no-ver|--no-veri|--no-verif|\
- --no-verify)
- verify=
- ;;
- --a|--am|--ame|--amen|--amend)
- amend=t
- use_commit=HEAD
- ;;
- -c)
- case "$#" in 1) usage ;; esac
- shift
- log_given=t$log_given
- use_commit="$1"
- no_edit=
- ;;
- --ree=*|--reed=*|--reedi=*|--reedit=*|--reedit-=*|--reedit-m=*|\
- --reedit-me=*|--reedit-mes=*|--reedit-mess=*|--reedit-messa=*|\
- --reedit-messag=*|--reedit-message=*)
- log_given=t$log_given
- use_commit="${1#*=}"
- no_edit=
- ;;
- --ree|--reed|--reedi|--reedit|--reedit-|--reedit-m|--reedit-me|\
- --reedit-mes|--reedit-mess|--reedit-messa|--reedit-messag|\
- --reedit-message)
- case "$#" in 1) usage ;; esac
- shift
- log_given=t$log_given
- use_commit="$1"
- no_edit=
- ;;
- -C)
- case "$#" in 1) usage ;; esac
- shift
- log_given=t$log_given
- use_commit="$1"
- no_edit=t
- ;;
- --reu=*|--reus=*|--reuse=*|--reuse-=*|--reuse-m=*|--reuse-me=*|\
- --reuse-mes=*|--reuse-mess=*|--reuse-messa=*|--reuse-messag=*|\
- --reuse-message=*)
- log_given=t$log_given
- use_commit="${1#*=}"
- no_edit=t
- ;;
- --reu|--reus|--reuse|--reuse-|--reuse-m|--reuse-me|--reuse-mes|\
- --reuse-mess|--reuse-messa|--reuse-messag|--reuse-message)
- case "$#" in 1) usage ;; esac
- shift
- log_given=t$log_given
- use_commit="$1"
- no_edit=t
- ;;
- -s|--s|--si|--sig|--sign|--signo|--signof|--signoff)
- signoff=t
- ;;
- -t|--t|--te|--tem|--temp|--templ|--templa|--templat|--template)
- case "$#" in 1) usage ;; esac
- shift
- templatefile="$1"
- no_edit=
- ;;
- -q|--q|--qu|--qui|--quie|--quiet)
- quiet=t
- ;;
- -v|--v|--ve|--ver|--verb|--verbo|--verbos|--verbose)
- verbose=t
- ;;
- -u|--u|--un|--unt|--untr|--untra|--untrac|--untrack|--untracke|\
- --untracked|--untracked-|--untracked-f|--untracked-fi|--untracked-fil|\
- --untracked-file|--untracked-files)
- untracked_files=t
- ;;
- --)
- shift
- break
- ;;
- -*)
- usage
- ;;
- *)
- break
- ;;
- esac
- shift
-done
-case "$edit_flag" in t) no_edit= ;; esac
-
-################################################################
-# Sanity check options
-
-case "$amend,$initial_commit" in
-t,t)
- die "You do not have anything to amend." ;;
-t,)
- if [ -f "$GIT_DIR/MERGE_HEAD" ]; then
- die "You are in the middle of a merge -- cannot amend."
- fi ;;
-esac
-
-case "$log_given" in
-tt*)
- die "Only one of -c/-C/-F can be used." ;;
-*tm*|*mt*)
- die "Option -m cannot be combined with -c/-C/-F." ;;
-esac
-
-case "$#,$also,$only,$amend" in
-*,t,t,*)
- die "Only one of --include/--only can be used." ;;
-0,t,,* | 0,,t,)
- die "No paths with --include/--only does not make sense." ;;
-0,,t,t)
- only_include_assumed="# Clever... amending the last one with dirty index." ;;
-0,,,*)
- ;;
-*,,,*)
- only_include_assumed="# Explicit paths specified without -i nor -o; assuming --only paths..."
- also=
- ;;
-esac
-unset only
-case "$all,$interactive,$also,$#" in
-*t,*t,*)
- die "Cannot use -a, --interactive or -i at the same time." ;;
-t,,[1-9]*)
- die "Paths with -a does not make sense." ;;
-,t,[1-9]*)
- die "Paths with --interactive does not make sense." ;;
-,,t,0)
- die "No paths with -i does not make sense." ;;
-esac
-
-if test ! -z "$templatefile" -a -z "$log_given"
-then
- if test ! -f "$templatefile"
- then
- die "Commit template file does not exist."
- fi
-fi
-
-################################################################
-# Prepare index to have a tree to be committed
-
-case "$all,$also" in
-t,)
- if test ! -f "$THIS_INDEX"
- then
- die 'nothing to commit (use "git add file1 file2" to include for commit)'
- fi
- save_index &&
- (
- cd_to_toplevel &&
- GIT_INDEX_FILE="$NEXT_INDEX" &&
- export GIT_INDEX_FILE &&
- git diff-files --name-only -z |
- git update-index --remove -z --stdin
- ) || exit
- ;;
-,t)
- save_index &&
- git ls-files --error-unmatch -- "$@" >/dev/null || exit
-
- git diff-files --name-only -z -- "$@" |
- (
- cd_to_toplevel &&
- GIT_INDEX_FILE="$NEXT_INDEX" &&
- export GIT_INDEX_FILE &&
- git update-index --remove -z --stdin
- ) || exit
- ;;
-,)
- if test "$interactive" = t; then
- git add --interactive || exit
- fi
- case "$#" in
- 0)
- ;; # commit as-is
- *)
- if test -f "$GIT_DIR/MERGE_HEAD"
- then
- refuse_partial "Cannot do a partial commit during a merge."
- fi
-
- TMP_INDEX="$GIT_DIR/tmp-index$$"
- W=
- test -z "$initial_commit" && W=--with-tree=HEAD
- commit_only=`git ls-files --error-unmatch $W -- "$@"` || exit
-
- # Build a temporary index and update the real index
- # the same way.
- if test -z "$initial_commit"
- then
- GIT_INDEX_FILE="$THIS_INDEX" \
- git read-tree --index-output="$TMP_INDEX" -i -m HEAD
- else
- rm -f "$TMP_INDEX"
- fi || exit
-
- printf '%s\n' "$commit_only" |
- GIT_INDEX_FILE="$TMP_INDEX" \
- git update-index --add --remove --stdin &&
-
- save_index &&
- printf '%s\n' "$commit_only" |
- (
- GIT_INDEX_FILE="$NEXT_INDEX"
- export GIT_INDEX_FILE
- git update-index --add --remove --stdin
- ) || exit
- ;;
- esac
- ;;
-esac
-
-################################################################
-# If we do as-is commit, the index file will be THIS_INDEX,
-# otherwise NEXT_INDEX after we make this commit. We leave
-# the index as is if we abort.
-
-if test -f "$NEXT_INDEX"
-then
- USE_INDEX="$NEXT_INDEX"
-else
- USE_INDEX="$THIS_INDEX"
-fi
-
-case "$status_only" in
-t)
- # This will silently fail in a read-only repository, which is
- # what we want.
- GIT_INDEX_FILE="$USE_INDEX" git update-index -q --unmerged --refresh
- run_status
- exit $?
- ;;
-'')
- GIT_INDEX_FILE="$USE_INDEX" git update-index -q --refresh || exit
- ;;
-esac
-
-################################################################
-# Grab commit message, write out tree and make commit.
-
-if test t = "$verify" && test -x "$GIT_DIR"/hooks/pre-commit
-then
- GIT_INDEX_FILE="${TMP_INDEX:-${USE_INDEX}}" "$GIT_DIR"/hooks/pre-commit \
- || exit
-fi
-
-if test "$log_message" != ''
-then
- printf '%s\n' "$log_message"
-elif test "$logfile" != ""
-then
- if test "$logfile" = -
- then
- test -t 0 &&
- echo >&2 "(reading log message from standard input)"
- cat
- else
- cat <"$logfile"
- fi
-elif test "$use_commit" != ""
-then
- encoding=$(git config i18n.commitencoding || echo UTF-8)
- git show -s --pretty=raw --encoding="$encoding" "$use_commit" |
- sed -e '1,/^$/d' -e 's/^ //'
-elif test -f "$GIT_DIR/MERGE_MSG"
-then
- cat "$GIT_DIR/MERGE_MSG"
-elif test -f "$GIT_DIR/SQUASH_MSG"
-then
- cat "$GIT_DIR/SQUASH_MSG"
-elif test "$templatefile" != ""
-then
- cat "$templatefile"
-fi | git stripspace >"$GIT_DIR"/COMMIT_EDITMSG
-
-case "$signoff" in
-t)
- sign=$(git-var GIT_COMMITTER_IDENT | sed -e '
- s/>.*/>/
- s/^/Signed-off-by: /
- ')
- blank_before_signoff=
- tail -n 1 "$GIT_DIR"/COMMIT_EDITMSG |
- grep 'Signed-off-by:' >/dev/null || blank_before_signoff='
-'
- tail -n 1 "$GIT_DIR"/COMMIT_EDITMSG |
- grep "$sign"$ >/dev/null ||
- printf '%s%s\n' "$blank_before_signoff" "$sign" \
- >>"$GIT_DIR"/COMMIT_EDITMSG
- ;;
-esac
-
-if test -f "$GIT_DIR/MERGE_HEAD" && test -z "$no_edit"; then
- echo "#"
- echo "# It looks like you may be committing a MERGE."
- echo "# If this is not correct, please remove the file"
- printf '%s\n' "# $GIT_DIR/MERGE_HEAD"
- echo "# and try again"
- echo "#"
-fi >>"$GIT_DIR"/COMMIT_EDITMSG
-
-# Author
-if test '' != "$use_commit"
-then
- eval "$(get_author_ident_from_commit "$use_commit")"
- export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_AUTHOR_DATE
-fi
-if test '' != "$force_author"
-then
- GIT_AUTHOR_NAME=`expr "z$force_author" : 'z\(.*[^ ]\) *<.*'` &&
- GIT_AUTHOR_EMAIL=`expr "z$force_author" : '.*\(<.*\)'` &&
- test '' != "$GIT_AUTHOR_NAME" &&
- test '' != "$GIT_AUTHOR_EMAIL" ||
- die "malformed --author parameter"
- export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL
-fi
-
-PARENTS="-p HEAD"
-if test -z "$initial_commit"
-then
- rloga='commit'
- if [ -f "$GIT_DIR/MERGE_HEAD" ]; then
- rloga='commit (merge)'
- PARENTS="-p HEAD "`sed -e 's/^/-p /' "$GIT_DIR/MERGE_HEAD"`
- elif test -n "$amend"; then
- rloga='commit (amend)'
- PARENTS=$(git cat-file commit HEAD |
- sed -n -e '/^$/q' -e 's/^parent /-p /p')
- fi
- current="$(git rev-parse --verify HEAD)"
-else
- if [ -z "$(git ls-files)" ]; then
- echo >&2 'nothing to commit (use "git add file1 file2" to include for commit)'
- exit 1
- fi
- PARENTS=""
- rloga='commit (initial)'
- current=''
-fi
-set_reflog_action "$rloga"
-
-if test -z "$no_edit"
-then
- {
- echo ""
- echo "# Please enter the commit message for your changes."
- echo "# (Comment lines starting with '#' will not be included)"
- test -z "$only_include_assumed" || echo "$only_include_assumed"
- run_status
- } >>"$GIT_DIR"/COMMIT_EDITMSG
-else
- # we need to check if there is anything to commit
- run_status >/dev/null
-fi
-if [ "$?" != "0" -a ! -f "$GIT_DIR/MERGE_HEAD" ]
-then
- rm -f "$GIT_DIR/COMMIT_EDITMSG" "$GIT_DIR/SQUASH_MSG"
- use_status_color=t
- run_status
- exit 1
-fi
-
-case "$no_edit" in
-'')
- git-var GIT_AUTHOR_IDENT > /dev/null || die
- git-var GIT_COMMITTER_IDENT > /dev/null || die
- git_editor "$GIT_DIR/COMMIT_EDITMSG"
- ;;
-esac
-
-case "$verify" in
-t)
- if test -x "$GIT_DIR"/hooks/commit-msg
- then
- "$GIT_DIR"/hooks/commit-msg "$GIT_DIR"/COMMIT_EDITMSG || exit
- fi
-esac
-
-if test -z "$no_edit"
-then
- sed -e '
- /^diff --git a\/.*/{
- s///
- q
- }
- /^#/d
- ' "$GIT_DIR"/COMMIT_EDITMSG
-else
- cat "$GIT_DIR"/COMMIT_EDITMSG
-fi |
-git stripspace >"$GIT_DIR"/COMMIT_MSG
-
-# Test whether the commit message has any content we didn't supply.
-have_commitmsg=
-grep -v -i '^Signed-off-by' "$GIT_DIR"/COMMIT_MSG |
- git stripspace > "$GIT_DIR"/COMMIT_BAREMSG
-
-# Is the commit message totally empty?
-if test -s "$GIT_DIR"/COMMIT_BAREMSG
-then
- if test "$templatefile" != ""
- then
- # Test whether this is just the unaltered template.
- if cnt=`sed -e '/^#/d' < "$templatefile" |
- git stripspace |
- diff "$GIT_DIR"/COMMIT_BAREMSG - |
- wc -l` &&
- test 0 -lt $cnt
- then
- have_commitmsg=t
- fi
- else
- # No template, so the content in the commit message must
- # have come from the user.
- have_commitmsg=t
- fi
-fi
-
-rm -f "$GIT_DIR"/COMMIT_BAREMSG
-
-if test "$have_commitmsg" = "t"
-then
- if test -z "$TMP_INDEX"
- then
- tree=$(GIT_INDEX_FILE="$USE_INDEX" git write-tree)
- else
- tree=$(GIT_INDEX_FILE="$TMP_INDEX" git write-tree) &&
- rm -f "$TMP_INDEX"
- fi &&
- commit=$(git commit-tree $tree $PARENTS <"$GIT_DIR/COMMIT_MSG") &&
- rlogm=$(sed -e 1q "$GIT_DIR"/COMMIT_MSG) &&
- git update-ref -m "$GIT_REFLOG_ACTION: $rlogm" HEAD $commit "$current" &&
- rm -f -- "$GIT_DIR/MERGE_HEAD" "$GIT_DIR/MERGE_MSG" &&
- if test -f "$NEXT_INDEX"
- then
- mv "$NEXT_INDEX" "$THIS_INDEX"
- else
- : ;# happy
- fi
-else
- echo >&2 "* no commit message? aborting commit."
- false
-fi
-ret="$?"
-rm -f "$GIT_DIR/COMMIT_MSG" "$GIT_DIR/COMMIT_EDITMSG" "$GIT_DIR/SQUASH_MSG"
-
-cd_to_toplevel
-
-git rerere
-
-if test "$ret" = 0
-then
- git gc --auto
- if test -x "$GIT_DIR"/hooks/post-commit
- then
- "$GIT_DIR"/hooks/post-commit
- fi
- if test -z "$quiet"
- then
- commit=`git diff-tree --always --shortstat --pretty="format:%h: %s"\
- --summary --root HEAD --`
- echo "Created${initial_commit:+ initial} commit $commit"
- fi
-fi
-
-exit "$ret"
diff --git a/git.c b/git.c
index d7c6bca..9565555 100644
--- a/git.c
+++ b/git.c
@@ -320,6 +320,7 @@ static void handle_internal_command(int argc, const char **argv)
{ "check-attr", cmd_check_attr, RUN_SETUP | NEED_WORK_TREE },
{ "cherry", cmd_cherry, RUN_SETUP },
{ "cherry-pick", cmd_cherry_pick, RUN_SETUP | NEED_WORK_TREE },
+ { "commit", cmd_commit, RUN_SETUP | NEED_WORK_TREE },
{ "commit-tree", cmd_commit_tree, RUN_SETUP },
{ "config", cmd_config },
{ "count-objects", cmd_count_objects, RUN_SETUP },
@@ -368,10 +369,10 @@ static void handle_internal_command(int argc, const char **argv)
{ "rev-parse", cmd_rev_parse, RUN_SETUP },
{ "revert", cmd_revert, RUN_SETUP | NEED_WORK_TREE },
{ "rm", cmd_rm, RUN_SETUP | NEED_WORK_TREE },
- { "runstatus", cmd_runstatus, RUN_SETUP | NEED_WORK_TREE },
{ "shortlog", cmd_shortlog, RUN_SETUP | USE_PAGER },
{ "show-branch", cmd_show_branch, RUN_SETUP },
{ "show", cmd_show, RUN_SETUP | USE_PAGER },
+ { "status", cmd_status, RUN_SETUP | NEED_WORK_TREE },
{ "stripspace", cmd_stripspace },
{ "symbolic-ref", cmd_symbolic_ref, RUN_SETUP },
{ "tag", cmd_tag, RUN_SETUP },
diff --git a/strbuf.h b/strbuf.h
index 5657e3d..eef4e6d 100644
--- a/strbuf.h
+++ b/strbuf.h
@@ -113,5 +113,6 @@ extern int strbuf_read_file(struct strbuf *sb, const char *path);
extern int strbuf_getline(struct strbuf *, FILE *, int);
extern void stripspace(struct strbuf *buf, int skip_comments);
+extern void launch_editor(const char *path, struct strbuf *buffer);
#endif /* STRBUF_H */
diff --git a/t/t3501-revert-cherry-pick.sh b/t/t3501-revert-cherry-pick.sh
index 552af1c..2dbe04f 100755
--- a/t/t3501-revert-cherry-pick.sh
+++ b/t/t3501-revert-cherry-pick.sh
@@ -44,7 +44,7 @@ test_expect_success setup '
test_expect_success 'cherry-pick after renaming branch' '
git checkout rename2 &&
- EDITOR=: VISUAL=: git cherry-pick added &&
+ git cherry-pick added &&
test -f opos &&
grep "Add extra line at the end" opos
@@ -53,7 +53,7 @@ test_expect_success 'cherry-pick after renaming branch' '
test_expect_success 'revert after renaming branch' '
git checkout rename1 &&
- EDITOR=: VISUAL=: git revert added &&
+ git revert added &&
test -f spoo &&
! grep "Add extra line at the end" spoo
diff --git a/t/t3901-i18n-patch.sh b/t/t3901-i18n-patch.sh
index 28e9e37..235f372 100755
--- a/t/t3901-i18n-patch.sh
+++ b/t/t3901-i18n-patch.sh
@@ -154,7 +154,7 @@ test_expect_success 'cherry-pick(U/U)' '
git reset --hard master &&
git cherry-pick side^ &&
git cherry-pick side &&
- EDITOR=: VISUAL=: git revert HEAD &&
+ git revert HEAD &&
check_encoding 3
'
@@ -169,7 +169,7 @@ test_expect_success 'cherry-pick(L/L)' '
git reset --hard master &&
git cherry-pick side^ &&
git cherry-pick side &&
- EDITOR=: VISUAL=: git revert HEAD &&
+ git revert HEAD &&
check_encoding 3 8859
'
@@ -184,7 +184,7 @@ test_expect_success 'cherry-pick(U/L)' '
git reset --hard master &&
git cherry-pick side^ &&
git cherry-pick side &&
- EDITOR=: VISUAL=: git revert HEAD &&
+ git revert HEAD &&
check_encoding 3
'
@@ -200,7 +200,7 @@ test_expect_success 'cherry-pick(L/U)' '
git reset --hard master &&
git cherry-pick side^ &&
git cherry-pick side &&
- EDITOR=: VISUAL=: git revert HEAD &&
+ git revert HEAD &&
check_encoding 3 8859
'
diff --git a/t/test-lib.sh b/t/test-lib.sh
index cc1253c..a232bd6 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -9,8 +9,8 @@ LC_ALL=C
PAGER=cat
TZ=UTC
export LANG LC_ALL PAGER TZ
-EDITOR=:
-VISUAL=:
+EDITOR=/bin/true
+VISUAL=/bin/true
unset GIT_EDITOR
unset AUTHOR_DATE
unset AUTHOR_EMAIL
--
1.5.2.GIT
^ permalink raw reply related [relevance 2%]
* Git User's Survey 2007 unfinished summary (long)
@ 2007-10-04 9:12 2% Jakub Narebski
0 siblings, 0 replies; 200+ results
From: Jakub Narebski @ 2007-10-04 9:12 UTC (permalink / raw)
To: git
This is partial summary of Git User's Survey 2007,
ending at state from 28 September 2007.
The survey can be found here:
http://www.survey.net.nz/survey.php?94e135ff41e871a1ea5bcda3ee1856d9
http://tinyurl.com/26774s
----
There were 683 individual responses
About you
~~~~~~~~~
01. What country are you in?
Answer | Count
------------------------------------------
Algeria | 1
Argentina | 3
Australia | 25
Austria | 9
Belgium | 5
Brazil | 20
Bulgaria | 1
Canada | 44
Chile | 2
China | 4
Colombia | 2
Czech Republic | 10
Denmark | 7
Ecuador | 1
Estonia | 1
European Union | 1
Finland | 23
France | 36
Germany | 64
Greece | 3
Hungary | 2
India | 13
Ireland | 2
Israel | 6
Italy | 14
Japan | 4
Jersey | 1
Latvia | 1
Malaysia | 1
Mexico | 1
Netherlands | 15
New Zealand | 5
Norway | 14
Philippines | 3
Poland | 6
Portugal | 2
Puerto Rico | 1
Romania | 1
Russian Federation | 6
Samoa | 1
Serbia | 1
Singapore | 2
Slovak Republic | 1
Slovenia | 2
South Africa | 4
Spain | 11
Sri Lanka | 1
Sweden | 14
Switzerland | 15
UK / US | 1
United Kingdom | 40
United States of America | 218
Venezuela | 1
Vietnam | 1
------------------------------------------
Base | 673 / 683
Total (sum) | 673
England and Scotland counts as United Kingdom here.
Table is sorted in alphabetical order.
As one can easily see, slightly less than third of GIT users
are in the USA (those who answered this survey).
02. What is your preferred non-programming language?
This is multiple answers question, although most people
gave only one preferred language.
Answer | Count
------------------------------------------
Afrikaans | 1
Bulgarian | 1
Castellano | 2
Catalan | 1
Chinese | 2
Czech | 10
Danish | 6
Dutch | 12
English | 416
Finnish | 16
French | 33
Galician | 1
German | 58
Greek | 2
Hebrew | 1
HibernoEnglish | 1
Hungarian | 3
Italian | 9
Japanese | 1
LSF (French sign language) | 1
Norwegian | 4
Polish | 5
Portuguese | 11
Romanian | 1
Russian | 13
Serbian | 1
Slovenian | 2
Spanish | 13
Swedish | 13
Swiss | 1
Ukrainian | 1
Vietnamese | 1
------------------------------------------
invalid (computer language) | 37
not understood | 4
------------------------------------------
Base | 662 / 683
Total (sum) | 684
The question itself is not well formulated, as one can see from the
number of answers with computer language, and "not understood"
answers. I am not native English speaker, but there were suggestions
to use "natural language" instead of "non-programming language".
Around two third of git users prefer English language, at least for
dealing with computers.
03. How old are you?
Answer | Count
------------------------------------------
< 18 | 11
18-21 | 75
22-25 | 174
26-30 | 203
31-40 | 146
41-50 | 45
51-75 | 13
76+ | 0
------------------------------------------
Base | 667 / 683
Total (sum) | 667
Youngest git user who answered this survey is 14 years old,
oldest is 74 years old. This is quite a span, I'd say, The age of 25
got most count (51 answers).
04. Which programming languages you are proficient with?
Answer | Count
------------------------------------------
C | 582
shell | 449
Perl | 244
Python | 316
Tcl/Tk | 26
------------------------------------------
Base | 648 / 683
Total (sum) | 1617
The choices include programming languages used by git. This is
multiple choice question (you can be proficient in more than one
programming language).
It look like there is only around 3/4 people proficient in Perl as
compared to Python; it looks like Python is more popular. C is most
popular; shell is more popular than Perl or Python. The fewest people
are proficient in Tcl/Tk. I'm sorry, git-gui and gitk guys; it looks
like not many developers... around 4% of git users.
Getting started with GIT
~~~~~~~~~~~~~~~~~~~~~~~~
05. How did you hear about GIT?
Answer | Count
------------------------------------------
LKML | 109
LWN (Linux Weekly News) | 39
KernelTrap | 15
KernelTraffic | 1
kernel.org | 9
freedesktop.org | 5
Linus presentation at Google | 48
Slashdot | 28
blog | 19
community site[*1*] | 12
news site | 34
searching Internet[*2*] | 6
other SCM / SCM research[*3*] | 20
Internet | 32
IRC | 6
Linux kernel uses it | 73
some project uses git | 47
developer by name[*4*] | 21
friend | 39
word of mouth | 15
work / coworker | 22
initial GIT announcement | 12
BitKeeper news | 24
------------------------------------------
don't remember | 13
other / uncategorized | 44
------------------------------------------
Base | 658 / 683
Total (sum) | 693
[*1*] Community site are sites like Digg, Reddit and "planet" sites.
[*2*] This includes answer of "Google"
[*3*] This includes some other SCM mailing list, VCS comparison,
and searching for an SCM.
[*4*] Linus Torvalds, Carl Worth, Keith Packard, Randal Schwartz,...
This was free-form question, and tabularizing answers was quite a work.
It is taken as multiple choice question (for example link to Linus
presentation at Google found at Slashdot).
Other / uncategorized includes for example GoogleTalk IM, 3 answers
IIRC.
Note that Linus Torvalds presentation at Google / YouTube got it's
own category, and generated quite a bit of git users.
06. Did you find GIT easy to learn?
Answer | Count
------------------------------------------
very easy | 38
easy | 136
reasonably | 318
hard | 131
very hard | 33
------------------------------------------
Base | 656 / 683
Total (sum) | 656
Nice gaussian curve. Most users find it reasonably easy to use.
On the other hand git is not considered easy...
07. What helped you most in learning to use it?
TO DO
646 / 683 non-empty responses
08. What did you find hardest?
TO DO
596 / 683 non-empty responses
09. When did you start using git? From which version?
Answer | Count
------------------------------------------
(no version string) | 165
0.99x | 26
0.x | 12
1.0x | 31
1.1x | 9
1.2x | 12
1.3x | 22
1.4x | 147
1.5x | 198
------------------------------------------
Base | 626 / 683
Total (sum) | 626
NOTE! This table shows _only_ answers in which there was given git
version explicitely. Some people gave date, some people wrote how long
they have used git. Those answers needs also processing; they are
skipped here.
It looks like the git users community is divided into part of users
who started using it from beginning, or almost from beginning, and
users which started using git post v1.3.0 (post e.g. making separate
remotes the default layout of branches).
Other SCMs
~~~~~~~~~~
10. What other SCMs did/do you use?
This question is not well thought, as it gathers together (in the
free-form which is not easy to tabularize with large number of
responses we got) SCMs which one used and no longer uses, SCMs which
are used in parallel with git, and SCMs which are used instead of git
(which are chosen as main SCM for a project). Nevertheless it shows
with which VCS, and its conceps, are users familiar with.
Answer | Count
------------------------------------------
AccuRev | 3
Aegis | 1
Bazaar | 19
Bazaar-NG | 50
BitKeeper | 27
CCC | 1
CMS (Digital) | 1
CMS (VAX) | 1
CMS (VMS) | 1
CVCS | 1
CVS | 454
ClearCase | 43
CodeMgr | 1
Continuus | 1
Darcs | 78
DesignSync | 1
GNU Arch | 57
Mercurial | 92
Monotone | 31
Omniworks | 1
OpenCM | 1
PRCS | 1
PVCS | 12
Perforce | 50
Quilt | 2
RCS | 61
SCCS | 18
SCM | 1
SCSS | 1
SVK | 19
Serena Version Manager | 1
SourceForge | 1
Sourcerer's Apprentice | 1
StarTeam | 4
Subversion | 524
Sun NSE | 2
Sun TeamWare | 4
VCS | 1
VMS | 1
VSS | 26
'cp -a' | 1
akpm patch scripts | 1
custom in-house tools | 1
diff patch | 2
none | 9
notes-on-paper-made-by-hand | 1
really horrible stuff | 1
scripts for 'shadow trees' | 1
tarballs | 1
tlib | 1
undisclosed | 1
------------------------------------------
Base | 654 / 683
Total (sum) | 1615
The above table is in alphabetical order. It was generated from
free-form answers, tabularized as multiple choice answer.
Note that this question does not distinguish between SCMs/VCSs which
were used prior to Git and used no longer, SCMs which are used beside
(in parallel) to Git perhaps interacting with Git, and SCMs which are
used instead of Git. Also note that this is _Git User's_ survey, so it
those number for example do not represent number of e.g. users of
Mercurial as compared to e.g. users of Subversion.
Below there is table of SCM used, sorted by the number of responses.
Note that annotations (like "a little CVS") were not weighted here.
Only SCMs which has count more that 10 are shown. One person can (and
usually did) chose more than one SCM.
Answer | Count
------------------------------------------
Subversion | 524
CVS | 454
Mercurial | 92
Darcs | 78
RCS | 61
GNU Arch | 57
Bazaar-NG | 50
Perforce | 50
ClearCase | 43
Monotone | 31
BitKeeper | 27
VSS (MS Visual SourceSafe) | 26
Bazaar | 19
SVK | 19
SCCS | 18
PVCS | 12
tla+baz+bzr | 129
------------------------------------------
Base | 654 / 683
As you can see two most popular SCMs are Subversion ('svn') and CVS,
with Subversion being a bit more popular. Among distributed SCMs
with most count are Mercurial ('hg') and Arch and its descendants
('tla', 'baz', 'bzr'). From proprietary (non-OSS) revision control
systems Perforce ('p4'), ClearCase (and ClearCase UCM), BitKeeper ('bk')
and Visual SourceSafe (aka. that awful M$ one ;-) got most count.
Note that the count for given version control system does not reflect
_preferences_ of git users. One can be forced to use specified SCM.
See also question 35: "How does GIT compare to other SCM?".
11. Why did you choose GIT?
TO DO
643 / 683 non-empty responses
12. Why did you choose other SCMs?
TO DO
606 / 683 non-empty responses
13. What would you require from GIT to enable you to change,
if you use other SCM for your project?
TO DO
474 / 683 non-empty responses
14. Did you import your repository from foreign SCM? What SCM?
Answer | Count
------------------------------------------
N/A | 15
No | 169
Yes | 372
------------------------------------------
Base | 556 / 683
Total (sum) | 556
This is anly partial analysis, as it deals only with first part of
question (which, because of second part, has free-form structure and
needed processing).
One can see that around half of git users have imported (at least one
project) from foreign SCM.
15. What tool did you use for import?
Answer | Count
------------------------------------------
by hand | 7
custom script | 21
fast-import script | 3
Tailor | 28
-------------------------------------------
git-cvsimport | 81
parsecvs | 12
fromcvs | 2
cvs2git | 1
cvstogit | 1
git-svn | 150
git-svnimport | 66
git-archimport | 15
bk2git (customized) | 1
darcs2git | 4
git-p4 | 4
git-p4import | 1
git-ucmimport | 1
hg-to-git | 2
hg2git | 2
hgpullsvn | 1
hgsvn | 1
moin2git | 1
------------------------------------------
unspecified | 18
N/A | 114
------------------------------------------
Base | 467 / 683
Total (sum) | 538
16. Do your GIT repository interact with other SCM? Which SCM?
Answer | Count
------------------------------------------
N/A | 35
No | 228
Yes | 228
------------------------------------------
Base | 491 / 683
Total (sum) | 491
This is anly partial analysis, as it deals only with first part of
question (which, because of second part, has free-form structure and
needed processing).
One can see that around third of git users interacts (for at least one
project) with foreign SCM, as compared to half of git users which have
imported other SCM.
17. What tool did/do you use to interact?
Answer | Count
------------------------------------------
by hand | 10
custom script | 16
Tailor | 4
convert-repo | 1
fromcvs | 1
git-cvsexportcommit | 8
git-cvsimport | 19
git-cvsserver | 2
git-svn | 164
git-svnimport | 2
git-p4 | 4
git-p4import | 1
-----------------------------------------
unspecified | 2
N/A | 153
------------------------------------------
Base | 385 / 683
Total (sum) | 388
The only tool which really allows to interact (two-way) with other SCM
is git-svn (164 / 232).
How you use GIT
~~~~~~~~~~~~~~~
18. Do you use GIT for work, unpaid projects, or both?
Answer | Count
------------------------------------------
work | 56
unpaid projects | 212
both | 377
work + both | 433
------------------------------------------
Base | 645 / 683
Total (sum) | 645
Around two third of people use git at work, or for work.
See also question 55: "Would commerical (paid) support from a support
vendor be of interest to you/your organization?"
19. How do you obtain GIT?
Answer | Count
------------------------------------------
binary package | 283
source tarball | 210
pull from main repository | 153
------------------------------------------
Base | 646 / 683
Total (sum) | 646
Around half more people use binary packages than source tarball (or
source package, I think). More than half of people compile its own git
(pull is also followed by compilation).
In earlier partial survey summary, from 27-08-2004 (a month earlier)
there were twice as many people installing git from binary packages.
20. What hardware platforms do you use GIT on?
(on Unices: result of "uname -i")
Note: 'uname -i' does not work on all Unices. I'm sorry for this
mistake.
Answer | Count
------------------------------------------
Intel | 73
Athlon | 2
i386 | 171
i586 | 9
i686 | 60
IA-32 | 6
IA-64 | 8
AMD | 35
amd64 | 48
x86 | 156
x86-64 | 112
Apple | 8
iMac | 1
MacBook | 7
PowerBook | 10
PPC | 52
ppc64 | 7
ARM | 6
Alpha | 2
PA-RISC | 1
parisc64 | 1
MIPS | 1
mips64 | 1
mipsel | 2
SPARC | 8
sparc64 | 6
SUNW | 6
Sun-Fire | 4
sun4u | 3
sun4v | 1
k8 | 1
------------------------------------------
unknown | 67
------------------------------------------
Base | 637 / 683
Total (sum) | 875
The above table is in some arbitrary order. It was generated from
free-form answers, tabularized as multiple choice answer, as one
person can use git on more than one architecture.
Those results probably needs further processing to reduce number of
choices, by gathering architectures.
"Unknown" usually means that something else instead of architecture
was given (like operating system), or architecture was too generic,
like "PC".
21. What OS (please include the version) do you use GIT on?
Answer | Count
------------------------------------------
AIX | 1
FreeBSD | 16
OpenBSD | 3
HP-UX | 1
Linux | 582
MS Windows (Cygwin) | 22
MS Windows (msys) | 1
MS Windows (unsp.) | 35
MacOS X / Darwin | 94
Solaris | 11
SunOS | 5
UNIX (unsp.) | 1
too many to list | 1
------------------------------------------
MS Windows (together) | 58
FreeBSD / OpenBSD | 19
Unices (together) | 19
------------------------------------------
Base | 645 / 683
Total (sum) | 775
The above was generated from free-form answers, tabularized as
multiple choice answer, as one person can use git on more than one
operating system.
This is only rough analysis, because it does not include operating
system version, or for Linux distribution(s) used.
22. What projects do you track (or download) using GIT (or git web interface)?
TO TABULARIZE
560 / 683 non-empty responses
23. How many people do you collaborate with using GIT?
TO TABULARIZE
575 / 683 non-empty responses
What ranges should be used here: 1, 2-9, 10-99, 100-999, 1000+ or
perhaps 1, 2-5, 6-15, 16-25, 26-50, 50-100, 100-1000, 1000+, or yet
another?
24. How big are the repositories that you work on?
TO DO
525 / 683 non-empty responses
Some git repositories have more than 50k files, more than 150k
commits, more than 100mb largest file (although not single directory
has all those).
25. How many different projects do you manage using GIT?
TO TABULARIZE
577 / 683 non-empty responses
26. Which porcelains do you use?
Multiple answers (one can use more than one porcelain).
Answer (multiple choice) | Count
------------------------------------------
core-git | 558
cogito (deprecated) | 56
Patch management interface: : 57
...........................................
StGIT | 41
Guilt (formerly gq) | 13
pg (deprecated) | 3
own scripts | 95
other | 14
------------------------------------------
Base | 593 / 683
Total (sum) | 780
Those 14 "other" answers make me wish to have provided "if other,
what it was?" (sub)question; actually not only for this question.
It is understandable that Cogito still has some users, even though it is
deprecated, and [I think] all of its functionality can be found in
git-core porcelain. It was meant as SCM / porcelain layer when git-core
didn't have it and consisted almost only of plumbing commands.
Quite a bit of people use patch management interface: StGIT, Guilt,
even deprecated and abandoned pg (Patchy Git). StGIT has more users
than Guilt (formerly gq), although that might be caused by the fact
that StGIT was here longer... Some say that it is because of Guilt
having non-standalone documentation; it needs reading hgbook, as Guilt
concepts are based on mq (Mercurial [patch] queues) extension.
Large number of users use their own scripts, more than any
non-standard porcelain. One wonders if this is a result of good
git scriptability.
14 users choose other... and there is no "what other" question,
unfortunately...
If you are reading this: what were those other porcelains?
27. Which git GUI do you use?
Multiple answers (one can use more than one GUI). Note that for the
first week and a bit of survey "CLI" answer had no explanation that it
means command line interface, so results might be bit skewed.
Answer (multiple choice) | Count
------------------------------------------
CLI (command line) | 398
gitk | 347
git-gui | 123
qgit | 82
gitview | 15
giggle | 48
tig | 41
instaweb | 16
(h)gct | 3
qct | 3
KGit | 6
git.el | 31
other | 15
giggle + gitview | 63
------------------------------------------
Base | 572 / 683
Total (sum) | 1128
As one can see almost as many people use gitk as CLI. Most used GUI
are gitk and git-gui, most probably because they are distributed with
git, and because they are portable. QGit is also quite popular,
although GTK+ viewers, namely giggle and gitview are also quite
popular (note that there might be instances of users using both giggle
and gitview). I am a bit suprised about popularity of Giggle, I'd say.
Tig (text-mode interface for git) and git.el (GIT mode for Emacs) are
also quite popular.
I wonder what are those 15 other GUI. Why oh why there were no "What
is this 'other GUI'?" question.
28. Which (main) git web interface do you use for your projects?
Answer | Count
------------------------------------------
gitweb | 382
cgit | 7
wit (Ruby) | 5
git-php | 1
other | 27
------------------------------------------
Base | 422 / 683
Total (sum) | 422
Around two third (closer to 4/7) of git users use some kind of web
interface for their projects.
Most use gitweb (which is distributed with git), 7 use cgit, 5 wit
(Ruby), most probably projects sharing site with XMMS2, 1 git-php
(I wonder who...), and there are 27 "other" answers, which I am most
curious about. What are they?
Some answered "other" as "N/A" (meaning they do not use web interface)
instead, what it is not obvious, not answering this question. The
explanation that this is possible was added later during duration of
survey.
29. How do you publish/propagate your changes?
Multiple choices, as one can use different methods for different
projects, for example pushing to public repo for a project maintained,
and sending patches via email to participate in third person project
development.
Answer | Count
------------------------------------------
push | 456
pull | 220
format-patch + email | 172
pull request | 65
bundle | 13
other | 70
------------------------------------------
Base | 589 / 683
Total (sum) | 996
Here "other" means just not listed workflow, although it would be also
interesting to know details.
Most popular is push, I guess to public "publishing" repository
(and/or probably to mirror repositories). It is twice as popular
as next method, gathering more than 3/4 of users.
Pull was supposed to mean logging to public server and pulling
changes from private repo, not pulling someone other changes.
It is second most popular method.
Sending patches via email is two to three times as popular
as sending pull request.
30. Does git.git repository include code produced by you?
Answer | Count
------------------------------------------
Yes | 99
No | 512
------------------------------------------
Base | 611 / 683
Total (sum) | 611
As it can be seen, only (or perhaps it is that many?) around
a 6th to 7th of git users participate in its development by
providing code.
Internationalization
~~~~~~~~~~~~~~~~~~~~
31. Is translating GIT required for wider adoption?
Answer | Count
------------------------------------------
Yes | 49
No | 383
Somewhat | 158
------------------------------------------
Base | 590 / 683
Total (sum) | 590
More than half of responders doesn't think that translating GIT
is required for wider adoption.
32. What do you need translated?
TO TABULARIZE
172 / 683 non-empty responses
33. For what language do you need translation for?
In alphabetic order, free-form question, treated as multiple choice.
Answer | Count
------------------------------------------
Afrikaans | 1
Belorussian | 1
Chinese | 5
Dutch | 2
English[*1*] | 3
Filipino | 1
Finnish | 3
French | 21
German | 17
Greek | 1
Hebrew | 1
Hindi | 1
Hungarian | 1
Italian | 4
Japanese | 5
Mandarin | 1
Norwegian | 2
Polish | 2
Portuguese | 6
Russian | 6
Serbian | 2
Slovenian | 1
Spanish | 9
Swedish | 2
Tagalog | 1
Ukrainian | 1
------------------------------------------
Base | 143 / 683
Total (sum) [*2*] | 100
[*1*] Git messages and documentation _is_ in English
[*2*] Some answers were: "do not translate".
German and French are most popular. Spanish, Portuguese, Russian,
Chinese + Mandarin and Japanese have count 5 or more.
What you think of GIT
~~~~~~~~~~~~~~~~~~~~~
34. Overall, how happy are you with GIT?
Answer | Count
------------------------------------------
unhappy | 13
not so happy | 36
happy | 179
very happy | 302
completely ecstatic | 112
------------------------------------------
Base | 642 / 683
Total (sum) | 642
Nice, git users are mostly very happy with git.
13 grumpy users, hmmm...
35. How does GIT compare to other SCM tools you have used?
Answer | Count
------------------------------------------
Better | 505
Equal (comparable) | 96
Worse | 30
N/A | 52
------------------------------------------
Base | 631 / 683
Total (sum) | 631
Clearly Git is superior SCM! (In the minds of Git users at least) ;-)
Seriously, one should take into consideration that those results are
biased, because it is _Git User's_ Survey, and people usually choose
SCM because they think it is best choice.
No answer (null answer) might mean that responder does not use and did
not use other SCMs to compare, or at least think that he/she does not
have sufficient basis for a comparison.
NOTE: I have to check if number of non-empty responses is calculated
properly. I think it is, but I will make sure.
36. What do you like about using GIT?
TO DO
578 / 683 non-empty responses
No full analysis yet, and no count of answers, but it seems that the
following are encountered most often (or at least those I remember
best):
* clean design
* performance (speed)
* size of repository
* reliability, robustness, data integrity
* flexibility, scriptable
* command set, features (git-bisect)
* history rewriting (amend, rebase, interactive rebase, reset)
* history viewers, searching and browsing history
* distributed nature, offline work, full history locally,
"local commits"
* easy and in-place branching
* easy merging, includes renames detection
* push/pull via ssh, pull via plain http -- no server needed
* easy to install: few dependencies, portable, lightweight
37. What would you most like to see improved about GIT?
(features, bugs, plug-ins, documentation, ...)
TO DO
512 / 683 non-empty responses
So many suggestions...
First, some of suggestions are actually implemented already, for
example git development Changelog (present in the form of RelNotes),
shallow clone support, submodules support. This means that new
features are not very well announced (which was one of comments here,
too).
Some of features and improvements mentioned:
* generic behavior:
- less chatter, clean distinction between success or fail
(it it was about git-pull, it is addressed already)
- better, more verbose error messages, with link to documentation
- diagnostic output in case of problems;
something like git-explain / git-state
- more universal undo / continue
- command line consistency, option consistency: getopt / gitopt
* documentation:
- unified, organized, searchable documentation
- The Git Book (c.f. cvs/svn/hgbook);
tutorial leading to advanced concepts like rebase, filter-branch,
grafts, submodules, gitattributes
- Git Cookbook / Git Recipies;
best practices document, usage scenarios, workflows used, HOWTO
- Git for Dummies (for people who haven't used SCM at all)
- more hooks and hook examples
- mid-level (script / plugin writer leve) docs
- git1line docs a la sed1line.txt
- "git <cmd> --help" returning one page of short command summary,
not manpage; "git help --all --summary" for all command with
oneline description
* other SCMs:
- cogito migration guide / tutorial (!)
- other SCM to git (concept, commands) cheat sheet
- git-bzr (and other SCMs) two-way integration
- git-svnserve: git functioning as Subversion server
* git-svn:
- automatic handling svn:externals using submodules and vice versa
- svnmerge and svk merge markers tracking/marking of merges
* more --interactive:
- git add --interactive in git-gui: allow to divide hunks
- git rebase -interactive: graphical interactive rebase in git-gui
- ncurses-based remote editing
* tools:
- better Emacs support; Vim plugin; IDE plugins (Eclipse, KDevelop,
IntelliJ IDEA,...)
- MS Windows explorer shell integration; filemanagers integration
(Nautilus, Konqueror)
- side by side diffs in gitweb, a la KDiff3/Meld/ediff etc.
* code:
- port scripts to C (builtinification)
- git library (libification)
- gitbox: single static, pre-packaged binary
* other:
- bisect dunno / skip / next
- partial checkout
- light working copies; multiple working copies per repo
- git-notes, to annotate commit messages
- push over sftp
- option to track empty directories
- option to track permissions and metainfo: ACL, EA, forks
- rebase and blame merge strategies
- merge / rebase into dirty tree
- resumable git-clone; faster and less CPU hungry git-clone
- checkout/merge/diff/hunk header handlers in distribution for
ChangeLog, XML, odf, jar and xul, po files
This is only [large] excerpt, not a list of all requested features.
As one can see tabularizing (dividing into categories) this data will
be not an easy task.
38. If you want to see GIT more widely used, what do you think
we could do to make this happen?
TO DO
459 / 683 non-empty responses
So many suggestions...
One of the more striking (and funny):
* Big fat posters world-wide with Catherine Zeta-Jones stating how
happy she is since she switched to git ;-)
She can actually write C-code.
* Offer Git stickers to put on laptops and such
Changes in GIT (since year ago, or since you started using it)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
39. Did you participate in previous Git User's Survey?
Answer | Count
------------------------------------------
Yes | 51
No | 583
------------------------------------------
Base | 634 / 683
Total (sum) | 634
51 people did out of 634 who answered this question, out of 115 (?)
who did participate in the previous survey. Around half. Bit curious.
40. What improvements you wanted got implemented?
TO TABULARIZE
129 / 683 non-empty responses
41. What improvements you wanted didn't get implemented?
TO TABULARIZE
104 / 683 non-empty responses
42. How do you compare current version with version from year ago?
Should be: from year ago, or since you started using this.
No responses (303 / 683) migh be caused by the fact that one
do not use git for a year, so he/she doesn't know what git
looked like year ago.
Answer | Count
------------------------------------------
Better | 319
No changes | 60
Worse | 1
------------------------------------------
Base | 380 / 683
Total (sum) | 380
Most think that git has improved. One user thinks that it is worse
than year ago; I wonder why...
43. Which of the new features do you use?
Multiple choice; the list does not include all new features.
Some new features are not visible at first glance, and one
uses them without conscious choice.
Answer | Count
------------------------------------------
git-gui | 103
blame improvements | 74
detached HEAD | 71
stash | 68
mergetool | 67
interactive rebase | 66
reflog | 54
submodules | 52
shallow clone | 31
commit template | 24
eol conversion | 22
gitattributes | 21
bundle | 17
worktree | 17
------------------------------------------
Base | 259 / 683
Total (sum) | 687
This table is sorted by count.
Detached HEAD support and stash command were long requested;
no wonder they are popular.
Documentation
~~~~~~~~~~~~~
Usefulness of | Yes / Some / No | Base
----------------------------------------------
GIT wiki | 191 / 69 / 198 | 458
on-line help | 377 / 172 / 28 | 577
distributed help | 425 / 154 / 22 | 601
----------------------------------------------
individual responses : 683
44. Do you use the GIT wiki?
Answer | Count
------------------------------------------
Yes | 316
No | 300
------------------------------------------
Base | 616 / 683
Total (sum) | 616
45. Do you find GIT wiki useful?
Answer | Count
------------------------------------------
Yes | 191
No | 69
Somewhat | 198
------------------------------------------
Base | 458 / 683
Total (sum) | 458
46. Do you contribute to GIT wiki?
Answer | Count
------------------------------------------
Yes | 17
No | 460
Corrections and removing spam | 45
Some contribution | 62
------------------------------------------
Base | 522 / 683
Total (sum) | 522
47. Do you find GIT's on-line help (homepage, documentation) useful?
Answer | Count
------------------------------------------
Yes | 377
No | 28
Somewhat | 172
------------------------------------------
Base | 577 / 683
Total (sum) | 577
48. Do you find help distributed with GIT useful
(manpages, manual, tutorial, HOWTO, release notes)?
Answer | Count
------------------------------------------
Yes | 425
No | 22
Somewhat | 154
------------------------------------------
Base | 601 / 683
Total (sum) | 601
49. Did/Do you contribute to GIT documentation?
Answer | Count
------------------------------------------
Yes | 43
No | 551
------------------------------------------
Base | 594 / 683
Total (sum) | 594
50. What could be improved on the GIT homepage?
TO DO
171 / 683 non-empty responses
51. What topics would you like to have on GIT wiki?
TO DO
134 / 683 non-empty responses
52. What could be improved in GIT documentation?
TO DO
190 / 683 non-empty responses
Getting help, staying in touch
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Do you use | Yes / No | Base
----------------------------------------------
GIT wiki | 316 / 300 | 616
mailing list | 204 / 406 | 610
IRC channel | 182 / 376 | 558
----------------------------------------------
Usefulness of | Yes / Some / No | Base
----------------------------------------------
GIT wiki | 191 / 69 / 198 | 458
mailing list | 146 / 79 / 34 | 259
IRC channel | 127 / 59 / 26 | 212
----------------------------------------------
individual responses : 683
As one can see mailing list is the primary medium for git,
and IRC secondary one.
53. Have you tried to get GIT help from other people?
Answer | Count
------------------------------------------
Yes | 357
No | 261
------------------------------------------
Base | 618 / 683
Total (sum) | 618
It might be that Git is not documented enough; it might be that
version control is not an easy task.
54. If yes, did you get these problems resolved quickly
and to your liking?
Answer | Count
------------------------------------------
Yes | 326
No | 53
------------------------------------------
Base | 379 / 683
Total (sum) | 379
That is I think very good (around 86%) percentage.
55. Would commerical (paid) support from a support vendor
be of interest to you/your organization?
Answer | Count
------------------------------------------
Not Applicable | 203
Yes | 69
No | 322
Yes + No | 391
------------------------------------------
Base | 594 / 683
Total (sum) | 594
Only 69 (12%) answers yes, 322 no, 203 not applicable (which meant
to encompass people who do not use git at and for work).
433 = 56 + 377 people participating in this survey use git for work,
or for both work and unpaid projects (as compared to 391 who answered
this question not with N/A).
Note that Git is GPLv2, and it will probably stay that forever, so you
are _free_ to start a commercial support scheme for Git, but others
are free not to choose it. This question is to get to know if there is
sufficient demand for commercial Git support for it to be viable.
56. Do you read the mailing list?
Answer | Count
------------------------------------------
Yes | 204
No | 406
------------------------------------------
Base | 610 / 683
Total (sum) | 610
The fact that only one third of git users are reading mailing list
(which is nevertheless quite large percentage) means that features
_have_ to be documented somewhere besides mailing list archive and
logs (commit messages).
57. If yes, do you find the mailing list useful?
Answer | Count
------------------------------------------
Yes | 146
No | 34
Somewhat | 79
------------------------------------------
Base | 259 / 683
Total (sum) | 259
58. Do you find traffic levels on GIT mailing list OK?
Answer | Count
------------------------------------------
Yes | 193
No | 50
------------------------------------------
Base | 243 / 683
Total (sum) | 243
59. Do you use the IRC channel (#git on irc.freenode.net)?
Answer | Count
------------------------------------------
Yes | 182
No | 376
------------------------------------------
Base | 558 / 683
Total (sum) | 558
60. If yes, do you find IRC channel useful?
Answer | Count
------------------------------------------
Yes | 127
No | 26
Somewhat | 59
------------------------------------------
Base | 212 / 683
Total (sum) | 212
61. Did you have problems getting GIT help on mailing list
or on IRC channel? What were it? What could be improved?
TO TABULARIZE
99 / 683 non-empty responses
Open forum
~~~~~~~~~~
62. What other comments or suggestions do you have, that are not
covered by the questions above?
TO DO
141 / 683 non-empty responses
--
Jakub Narebski
^ permalink raw reply [relevance 2%]
* Re: Trying to use git-filter-branch to compress history by removing large, obsolete binary files
@ 2007-10-08 2:28 2% ` Sam Vilain
0 siblings, 0 replies; 200+ results
From: Sam Vilain @ 2007-10-08 2:28 UTC (permalink / raw)
To: Elijah Newren; +Cc: Johannes Schindelin, Frank Lichtenheld, git
Elijah Newren wrote:
> On 10/7/07, Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:
>> It should be as easy as git filter-branch and git clone.
>
> Yes, a git filter-branch, git clone, AND git gc in the clone avoids
> all those funny ref editing commands. However, cloning a 5.6GB repo
> (the size of one of the real repos I'm dealing with) will likely take
> a long time (and may push me past the limits of disk space), so using
> other steps to avoid the need to clone actually seems nicer.
You can just delete the logs and references that you don't want and run
git gc --prune.
However.
git gc creates a new pack before deleting the old one. Garbage
collection usually does this; make a copy of everything to a new place
and then free all of the old space. If *that* is a problem, ie you
don't have enough space for two copies of the repository and the junk,
you'll have to do a partial import, leave the junk you don't want
unpacked, cleanup and prune, then finish the import. Which sounds like
a lot of hassle when you should really just find a place with more space
to work with!
Sam.
^ permalink raw reply [relevance 2%]
* [PATCH] Fixing path quoting issues
@ 2007-10-10 21:22 11% maillist
0 siblings, 0 replies; 200+ results
From: maillist @ 2007-10-10 21:22 UTC (permalink / raw)
To: git; +Cc: Jonathan del Strother
From: Jonathan del Strother <jon.delStrother@bestbefore.tv>
git-rebase and a number of tests didn't properly quote paths, leading to problems when run from a path with a space in.
Signed-off-by: Jonathan del Strother <jon.delStrother@bestbefore.tv>
---
git-rebase.sh | 26 +++++-----
t/t1020-subdirectory.sh | 22 ++++----
t/t3050-subprojects-fetch.sh | 2 +-
t/t3404-rebase-interactive.sh | 2 +-
t/t5500-fetch-pack.sh | 2 +-
t/t5700-clone-reference.sh | 2 +-
t/t7003-filter-branch.sh | 2 +-
t/t7501-commit.sh | 74 +++++++++++++++---------------
t/t9100-git-svn-basic.sh | 18 ++++----
t/t9101-git-svn-props.sh | 6 +-
t/t9102-git-svn-deep-rmdir.sh | 6 +-
t/t9104-git-svn-follow-parent.sh | 50 ++++++++++----------
t/t9105-git-svn-commit-diff.sh | 10 ++--
t/t9106-git-svn-commit-diff-clobber.sh | 14 +++---
t/t9107-git-svn-migrate.sh | 40 ++++++++--------
t/t9108-git-svn-glob.sh | 8 ++--
t/t9110-git-svn-use-svm-props.sh | 8 ++--
t/t9111-git-svn-use-svnsync-props.sh | 8 ++--
t/t9112-git-svn-md5less-file.sh | 4 +-
t/t9113-git-svn-dcommit-new-file.sh | 6 +-
t/t9114-git-svn-dcommit-merge.sh | 4 +-
t/t9115-git-svn-dcommit-funky-renames.sh | 4 +-
t/t9116-git-svn-log.sh | 4 +-
t/test-lib.sh | 2 +-
24 files changed, 162 insertions(+), 162 deletions(-)
diff --git a/git-rebase.sh b/git-rebase.sh
index 1583402..b48397e 100755
--- a/git-rebase.sh
+++ b/git-rebase.sh
@@ -59,7 +59,7 @@ continue_merge () {
die "$RESOLVEMSG"
fi
- cmt=`cat $dotest/current`
+ cmt=`cat "$dotest/current"`
if ! git diff-index --quiet HEAD
then
if ! git-commit -C "$cmt"
@@ -84,14 +84,14 @@ continue_merge () {
}
call_merge () {
- cmt="$(cat $dotest/cmt.$1)"
+ cmt="$(cat "$dotest/cmt.$1")"
echo "$cmt" > "$dotest/current"
hd=$(git rev-parse --verify HEAD)
cmt_name=$(git symbolic-ref HEAD)
- msgnum=$(cat $dotest/msgnum)
- end=$(cat $dotest/end)
+ msgnum=$(cat "$dotest/msgnum")
+ end=$(cat "$dotest/end")
eval GITHEAD_$cmt='"${cmt_name##refs/heads/}~$(($end - $msgnum))"'
- eval GITHEAD_$hd='"$(cat $dotest/onto_name)"'
+ eval GITHEAD_$hd='"$(cat \"$dotest/onto_name\")"'
export GITHEAD_$cmt GITHEAD_$hd
git-merge-$strategy "$cmt^" -- "$hd" "$cmt"
rv=$?
@@ -140,10 +140,10 @@ do
}
if test -d "$dotest"
then
- prev_head="`cat $dotest/prev_head`"
- end="`cat $dotest/end`"
- msgnum="`cat $dotest/msgnum`"
- onto="`cat $dotest/onto`"
+ prev_head="`cat \"$dotest/prev_head\"`"
+ end="`cat \"$dotest/end\"`"
+ msgnum="`cat \"$dotest/msgnum\"`"
+ onto="`cat \"$dotest/onto\"`"
continue_merge
while test "$msgnum" -le "$end"
do
@@ -160,11 +160,11 @@ do
if test -d "$dotest"
then
git rerere clear
- prev_head="`cat $dotest/prev_head`"
- end="`cat $dotest/end`"
- msgnum="`cat $dotest/msgnum`"
+ prev_head="`cat \"$dotest/prev_head\"`"
+ end="`cat \"$dotest/end\"`"
+ msgnum="`cat \"$dotest/msgnum\"`"
msgnum=$(($msgnum + 1))
- onto="`cat $dotest/onto`"
+ onto="`cat \"$dotest/onto\"`"
while test "$msgnum" -le "$end"
do
call_merge "$msgnum"
diff --git a/t/t1020-subdirectory.sh b/t/t1020-subdirectory.sh
index b9cef34..5ed7fa4 100755
--- a/t/t1020-subdirectory.sh
+++ b/t/t1020-subdirectory.sh
@@ -21,7 +21,7 @@ LF='
'
test_expect_success 'update-index and ls-files' '
- cd $HERE &&
+ cd "$HERE" &&
git update-index --add one &&
case "`git ls-files`" in
one) echo ok one ;;
@@ -41,7 +41,7 @@ test_expect_success 'update-index and ls-files' '
'
test_expect_success 'cat-file' '
- cd $HERE &&
+ cd "$HERE" &&
two=`git ls-files -s dir/two` &&
two=`expr "$two" : "[0-7]* \\([0-9a-f]*\\)"` &&
echo "$two" &&
@@ -54,7 +54,7 @@ test_expect_success 'cat-file' '
rm -f actual dir/actual
test_expect_success 'diff-files' '
- cd $HERE &&
+ cd "$HERE" &&
echo a >>one &&
echo d >>dir/two &&
case "`git diff-files --name-only`" in
@@ -74,7 +74,7 @@ test_expect_success 'diff-files' '
'
test_expect_success 'write-tree' '
- cd $HERE &&
+ cd "$HERE" &&
top=`git write-tree` &&
echo $top &&
cd dir &&
@@ -84,7 +84,7 @@ test_expect_success 'write-tree' '
'
test_expect_success 'checkout-index' '
- cd $HERE &&
+ cd "$HERE" &&
git checkout-index -f -u one &&
cmp one original.one &&
cd dir &&
@@ -93,7 +93,7 @@ test_expect_success 'checkout-index' '
'
test_expect_success 'read-tree' '
- cd $HERE &&
+ cd "$HERE" &&
rm -f one dir/two &&
tree=`git write-tree` &&
git read-tree --reset -u "$tree" &&
@@ -107,27 +107,27 @@ test_expect_success 'read-tree' '
'
test_expect_success 'no file/rev ambiguity check inside .git' '
- cd $HERE &&
+ cd "$HERE" &&
git commit -a -m 1 &&
- cd $HERE/.git &&
+ cd "$HERE/.git" &&
git show -s HEAD
'
test_expect_success 'no file/rev ambiguity check inside a bare repo' '
- cd $HERE &&
+ cd "$HERE" &&
git clone -s --bare .git foo.git &&
cd foo.git && GIT_DIR=. git show -s HEAD
'
# This still does not work as it should...
: test_expect_success 'no file/rev ambiguity check inside a bare repo' '
- cd $HERE &&
+ cd "$HERE" &&
git clone -s --bare .git foo.git &&
cd foo.git && git show -s HEAD
'
test_expect_success 'detection should not be fooled by a symlink' '
- cd $HERE &&
+ cd "$HERE" &&
rm -fr foo.git &&
git clone -s .git another &&
ln -s another yetanother &&
diff --git a/t/t3050-subprojects-fetch.sh b/t/t3050-subprojects-fetch.sh
index 34f26a8..4b74cc6 100755
--- a/t/t3050-subprojects-fetch.sh
+++ b/t/t3050-subprojects-fetch.sh
@@ -20,7 +20,7 @@ test_expect_success setup '
'
test_expect_success clone '
- git clone file://`pwd`/.git cloned &&
+ git clone "file://`pwd`/.git" cloned &&
(git rev-parse HEAD; git ls-files -s) >expected &&
(
cd cloned &&
diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh
index 1113904..f321787 100755
--- a/t/t3404-rebase-interactive.sh
+++ b/t/t3404-rebase-interactive.sh
@@ -92,7 +92,7 @@ done
EOF
chmod a+x fake-editor.sh
-VISUAL="$(pwd)/fake-editor.sh"
+VISUAL="'$(pwd)/fake-editor.sh'"
export VISUAL
test_expect_success 'no changes are a nop' '
diff --git a/t/t5500-fetch-pack.sh b/t/t5500-fetch-pack.sh
index 7b6798d..5489ffe 100755
--- a/t/t5500-fetch-pack.sh
+++ b/t/t5500-fetch-pack.sh
@@ -129,7 +129,7 @@ pull_to_client 2nd "B" $((64*3))
pull_to_client 3rd "A" $((1*3)) # old fails
-test_expect_success "clone shallow" "git-clone --depth 2 file://`pwd`/. shallow"
+test_expect_success "clone shallow" "git-clone --depth 2 \"file://`pwd`/.\" shallow"
(cd shallow; git count-objects -v) > count.shallow
diff --git a/t/t5700-clone-reference.sh b/t/t5700-clone-reference.sh
index 4e93aaa..8bb34f9 100755
--- a/t/t5700-clone-reference.sh
+++ b/t/t5700-clone-reference.sh
@@ -51,7 +51,7 @@ diff expected current'
cd "$base_dir"
test_expect_success 'cloning with reference (no -l -s)' \
-'git clone --reference B file://`pwd`/A D'
+'git clone --reference B "file://`pwd`/A" D'
cd "$base_dir"
diff --git a/t/t7003-filter-branch.sh b/t/t7003-filter-branch.sh
index e935b20..1ab5392 100755
--- a/t/t7003-filter-branch.sh
+++ b/t/t7003-filter-branch.sh
@@ -107,7 +107,7 @@ test_expect_success 'use index-filter to move into a subdirectory' '
"git ls-files -s | sed \"s-\\t-&newsubdir/-\" |
GIT_INDEX_FILE=\$GIT_INDEX_FILE.new \
git update-index --index-info &&
- mv \$GIT_INDEX_FILE.new \$GIT_INDEX_FILE" directorymoved &&
+ mv \"\$GIT_INDEX_FILE.new\" \"\$GIT_INDEX_FILE\"" directorymoved &&
test -z "$(git diff HEAD directorymoved:newsubdir)"'
test_expect_success 'stops when msg filter fails' '
diff --git a/t/t7501-commit.sh b/t/t7501-commit.sh
index b151b51..f3d0ab9 100644
--- a/t/t7501-commit.sh
+++ b/t/t7501-commit.sh
@@ -69,7 +69,7 @@ test_expect_success \
cat >editor <<\EOF
#!/bin/sh
-sed -i -e "s/a file/an amend commit/g" $1
+sed -i -e "s/a file/an amend commit/g" "$1"
EOF
chmod 755 editor
@@ -80,40 +80,40 @@ test_expect_success \
test_expect_failure \
"passing -m and -F" \
"echo 'enough with the bongos' >file && \
- git-commit -F msg -m amending ."
+ git-commit -F msg -m amending ."
test_expect_success \
- "using message from other commit" \
- "git-commit -C HEAD^ ."
+ "using message from other commit" \
+ "git-commit -C HEAD^ ."
cat >editor <<\EOF
#!/bin/sh
-sed -i -e "s/amend/older/g" $1
+sed -i -e "s/amend/older/g" "$1"
EOF
chmod 755 editor
test_expect_success \
- "editing message from other commit" \
- "echo 'hula hula' >file && \
- VISUAL=./editor git-commit -c HEAD^ -a"
+ "editing message from other commit" \
+ "echo 'hula hula' >file && \
+ VISUAL=./editor git-commit -c HEAD^ -a"
test_expect_success \
- "message from stdin" \
- "echo 'silly new contents' >file && \
- echo commit message from stdin | git-commit -F - -a"
+ "message from stdin" \
+ "echo 'silly new contents' >file && \
+ echo commit message from stdin | git-commit -F - -a"
test_expect_success \
- "overriding author from command line" \
- "echo 'gak' >file && \
- git-commit -m 'author' --author 'Rubber Duck <rduck@convoy.org>' -a"
+ "overriding author from command line" \
+ "echo 'gak' >file && \
+ git-commit -m 'author' --author 'Rubber Duck <rduck@convoy.org>' -a"
test_expect_success \
- "interactive add" \
- "echo 7 | git-commit --interactive | grep 'What now'"
+ "interactive add" \
+ "echo 7 | git-commit --interactive | grep 'What now'"
test_expect_success \
- "showing committed revisions" \
- "git-rev-list HEAD >current"
+ "showing committed revisions" \
+ "git-rev-list HEAD >current"
# We could just check the head sha1, but checking each commit makes it
# easier to isolate bugs.
@@ -128,38 +128,38 @@ d381ac431806e53f3dd7ac2f1ae0534f36d738b9
EOF
test_expect_success \
- 'validate git-rev-list output.' \
- 'diff current expected'
+ 'validate git-rev-list output.' \
+ 'diff current expected'
test_expect_success 'partial commit that involves removal (1)' '
- git rm --cached file &&
- mv file elif &&
- git add elif &&
- git commit -m "Partial: add elif" elif &&
- git diff-tree --name-status HEAD^ HEAD >current &&
- echo "A elif" >expected &&
- diff expected current
+ git rm --cached file &&
+ mv file elif &&
+ git add elif &&
+ git commit -m "Partial: add elif" elif &&
+ git diff-tree --name-status HEAD^ HEAD >current &&
+ echo "A elif" >expected &&
+ diff -b expected current
'
test_expect_success 'partial commit that involves removal (2)' '
- git commit -m "Partial: remove file" file &&
- git diff-tree --name-status HEAD^ HEAD >current &&
- echo "D file" >expected &&
- diff expected current
+ git commit -m "Partial: remove file" file &&
+ git diff-tree --name-status HEAD^ HEAD >current &&
+ echo "D file" >expected &&
+ diff -b expected current
'
test_expect_success 'partial commit that involves removal (3)' '
- git rm --cached elif &&
- echo elif >elif &&
- git commit -m "Partial: modify elif" elif &&
- git diff-tree --name-status HEAD^ HEAD >current &&
- echo "M elif" >expected &&
- diff expected current
+ git rm --cached elif &&
+ echo elif >elif &&
+ git commit -m "Partial: modify elif" elif &&
+ git diff-tree --name-status HEAD^ HEAD >current &&
+ echo "M elif" >expected &&
+ diff -b expected current
'
diff --git a/t/t9100-git-svn-basic.sh b/t/t9100-git-svn-basic.sh
index 614cf50..c3585da 100755
--- a/t/t9100-git-svn-basic.sh
+++ b/t/t9100-git-svn-basic.sh
@@ -31,16 +31,16 @@ test_expect_success \
echo 'zzz' > bar/zzz &&
echo '#!/bin/sh' > exec.sh &&
chmod +x exec.sh &&
- svn import -m 'import for git-svn' . $svnrepo >/dev/null &&
+ svn import -m 'import for git-svn' . '$svnrepo' >/dev/null &&
cd .. &&
rm -rf import &&
- git-svn init $svnrepo"
+ git-svn init '$svnrepo'"
test_expect_success \
'import an SVN revision into git' \
'git-svn fetch'
-test_expect_success "checkout from svn" "svn co $svnrepo '$SVN_TREE'"
+test_expect_success "checkout from svn" "svn co '$svnrepo' '$SVN_TREE'"
name='try a deep --rmdir with a commit'
test_expect_success "$name" "
@@ -169,7 +169,7 @@ test_expect_success "$name" "
svn up '$SVN_TREE' &&
test -f '$SVN_TREE'/exec-2.sh &&
test ! -L '$SVN_TREE'/exec-2.sh &&
- git diff help $SVN_TREE/exec-2.sh"
+ git diff help '$SVN_TREE/exec-2.sh'"
if test "$have_utf8" = t
then
@@ -190,7 +190,7 @@ name='test fetch functionality (svn => git) with alternate GIT_SVN_ID'
GIT_SVN_ID=alt
export GIT_SVN_ID
test_expect_success "$name" \
- "git-svn init $svnrepo && git-svn fetch &&
+ "git-svn init '$svnrepo' && git-svn fetch &&
git rev-list --pretty=raw remotes/git-svn | grep ^tree | uniq > a &&
git rev-list --pretty=raw remotes/alt | grep ^tree | uniq > b &&
git diff a b"
@@ -220,16 +220,16 @@ test_expect_failure 'exit if remote refs are ambigious' "
"
test_expect_failure 'exit if init-ing a would clobber a URL' "
- svnadmin create ${PWD}/svnrepo2 &&
- svn mkdir -m 'mkdir bar' ${svnrepo}2/bar &&
+ svnadmin create '${PWD}/svnrepo2' &&
+ svn mkdir -m 'mkdir bar' '${svnrepo}2/bar' &&
git config --unset svn-remote.svn.fetch \
'^bar:refs/remotes/git-svn$' &&
- git-svn init ${svnrepo}2/bar
+ git-svn init '${svnrepo}2/bar'
"
test_expect_success \
'init allows us to connect to another directory in the same repo' "
- git-svn init --minimize-url -i bar $svnrepo/bar &&
+ git-svn init --minimize-url -i bar '$svnrepo/bar' &&
git config --get svn-remote.svn.fetch \
'^bar:refs/remotes/bar$' &&
git config --get svn-remote.svn.fetch \
diff --git a/t/t9101-git-svn-props.sh b/t/t9101-git-svn-props.sh
index 5aac644..a1c85e0 100755
--- a/t/t9101-git-svn-props.sh
+++ b/t/t9101-git-svn-props.sh
@@ -52,7 +52,7 @@ EOF
cd ..
rm -rf import
-test_expect_success 'checkout working copy from svn' "svn co $svnrepo test_wc"
+test_expect_success 'checkout working copy from svn' "svn co '$svnrepo' test_wc"
test_expect_success 'setup some commits to svn' \
'cd test_wc &&
echo Greetings >> kw.c &&
@@ -66,7 +66,7 @@ test_expect_success 'setup some commits to svn' \
svn commit -m "Propset Id" &&
cd ..'
-test_expect_success 'initialize git-svn' "git-svn init $svnrepo"
+test_expect_success 'initialize git-svn' "git-svn init '$svnrepo'"
test_expect_success 'fetch revisions from svn' 'git-svn fetch'
name='test svn:keywords ignoring'
@@ -92,7 +92,7 @@ test_expect_success "propset CR on crlf files" \
test_expect_success 'fetch and pull latest from svn and checkout a new wc' \
"git-svn fetch &&
git pull . remotes/git-svn &&
- svn co $svnrepo new_wc"
+ svn co '$svnrepo' new_wc"
for i in crlf ne_crlf lf ne_lf cr ne_cr empty_cr empty_lf empty empty_crlf
do
diff --git a/t/t9102-git-svn-deep-rmdir.sh b/t/t9102-git-svn-deep-rmdir.sh
index 4e08083..99c8840 100755
--- a/t/t9102-git-svn-deep-rmdir.sh
+++ b/t/t9102-git-svn-deep-rmdir.sh
@@ -9,12 +9,12 @@ test_expect_success 'initialize repo' "
mkdir -p deeply/nested/directory/number/2 &&
echo foo > deeply/nested/directory/number/1/file &&
echo foo > deeply/nested/directory/number/2/another &&
- svn import -m 'import for git-svn' . $svnrepo &&
+ svn import -m 'import for git-svn' . '$svnrepo' &&
cd ..
"
test_expect_success 'mirror via git-svn' "
- git-svn init $svnrepo &&
+ git-svn init '$svnrepo' &&
git-svn fetch &&
git checkout -f -b test-rmdir remotes/git-svn
"
@@ -23,7 +23,7 @@ test_expect_success 'Try a commit on rmdir' "
git rm -f deeply/nested/directory/number/2/another &&
git commit -a -m 'remove another' &&
git-svn set-tree --rmdir HEAD &&
- svn ls -R $svnrepo | grep ^deeply/nested/directory/number/1
+ svn ls -R '$svnrepo' | grep ^deeply/nested/directory/number/1
"
diff --git a/t/t9104-git-svn-follow-parent.sh b/t/t9104-git-svn-follow-parent.sh
index 7ba7630..aa2bfe2 100755
--- a/t/t9104-git-svn-follow-parent.sh
+++ b/t/t9104-git-svn-follow-parent.sh
@@ -11,9 +11,9 @@ test_expect_success 'initialize repo' "
cd import &&
mkdir -p trunk &&
echo hello > trunk/readme &&
- svn import -m 'initial' . $svnrepo &&
+ svn import -m 'initial' . '$svnrepo' &&
cd .. &&
- svn co $svnrepo wc &&
+ svn co '$svnrepo' wc &&
cd wc &&
echo world >> trunk/readme &&
poke trunk/readme &&
@@ -27,7 +27,7 @@ test_expect_success 'initialize repo' "
"
test_expect_success 'init and fetch a moved directory' "
- git-svn init --minimize-url -i thunk $svnrepo/thunk &&
+ git-svn init --minimize-url -i thunk '$svnrepo/thunk' &&
git-svn fetch -i thunk &&
test \"\`git rev-parse --verify refs/remotes/thunk@2\`\" \
= \"\`git rev-parse --verify refs/remotes/thunk~1\`\" &&
@@ -38,7 +38,7 @@ test_expect_success 'init and fetch a moved directory' "
"
test_expect_success 'init and fetch from one svn-remote' "
- git config svn-remote.svn.url $svnrepo &&
+ git config svn-remote.svn.url '$svnrepo' &&
git config --add svn-remote.svn.fetch \
trunk:refs/remotes/svn/trunk &&
git config --add svn-remote.svn.fetch \
@@ -52,9 +52,9 @@ test_expect_success 'init and fetch from one svn-remote' "
test_expect_success 'follow deleted parent' "
(svn cp -m 'resurrecting trunk as junk' \
- $svnrepo/trunk@2 $svnrepo/junk ||
+ '$svnrepo/trunk@2' '$svnrepo'/junk ||
svn cp -m 'resurrecting trunk as junk' \
- -r2 $svnrepo/trunk $svnrepo/junk) &&
+ -r2 '$svnrepo/trunk' '$svnrepo/junk') &&
git config --add svn-remote.svn.fetch \
junk:refs/remotes/svn/junk &&
git-svn fetch -i svn/thunk &&
@@ -67,10 +67,10 @@ test_expect_success 'follow deleted parent' "
test_expect_success 'follow larger parent' "
mkdir -p import/trunk/thunk/bump/thud &&
echo hi > import/trunk/thunk/bump/thud/file &&
- svn import -m 'import a larger parent' import $svnrepo/larger-parent &&
- svn cp -m 'hi' $svnrepo/larger-parent $svnrepo/another-larger &&
+ svn import -m 'import a larger parent' import '$svnrepo/larger-parent' &&
+ svn cp -m 'hi' '$svnrepo/larger-parent' '$svnrepo/another-larger' &&
git-svn init --minimize-url -i larger \
- $svnrepo/another-larger/trunk/thunk/bump/thud &&
+ '$svnrepo/another-larger/trunk/thunk/bump/thud' &&
git-svn fetch -i larger &&
git rev-parse --verify refs/remotes/larger &&
git rev-parse --verify \
@@ -83,23 +83,23 @@ test_expect_success 'follow larger parent' "
"
test_expect_success 'follow higher-level parent' "
- svn mkdir -m 'follow higher-level parent' $svnrepo/blob &&
- svn co $svnrepo/blob blob &&
+ svn mkdir -m 'follow higher-level parent' '$svnrepo/blob' &&
+ svn co '$svnrepo/blob' blob &&
cd blob &&
echo hi > hi &&
svn add hi &&
svn commit -m 'hihi' &&
cd ..
- svn mkdir -m 'new glob at top level' $svnrepo/glob &&
- svn mv -m 'move blob down a level' $svnrepo/blob $svnrepo/glob/blob &&
- git-svn init --minimize-url -i blob $svnrepo/glob/blob &&
+ svn mkdir -m 'new glob at top level' '$svnrepo/glob' &&
+ svn mv -m 'move blob down a level' '$svnrepo/blob' '$svnrepo/glob/blob' &&
+ git-svn init --minimize-url -i blob '$svnrepo/glob/blob' &&
git-svn fetch -i blob
"
test_expect_success 'follow deleted directory' "
- svn mv -m 'bye!' $svnrepo/glob/blob/hi $svnrepo/glob/blob/bye &&
- svn rm -m 'remove glob' $svnrepo/glob &&
- git-svn init --minimize-url -i glob $svnrepo/glob &&
+ svn mv -m 'bye!' '$svnrepo/glob/blob/hi' '$svnrepo/glob/blob/bye' &&
+ svn rm -m 'remove glob' '$svnrepo/glob' &&
+ git-svn init --minimize-url -i glob '$svnrepo/glob' &&
git-svn fetch -i glob &&
test \"\`git cat-file blob refs/remotes/glob:blob/bye\`\" = hi &&
test \"\`git ls-tree refs/remotes/glob | wc -l \`\" -eq 1
@@ -118,9 +118,9 @@ test_expect_success 'follow-parent avoids deleting relevant info' "
echo 'bad delete test 2' > \
import/trunk/subversion/bindings/swig/perl/another-larger &&
cd import &&
- svn import -m 'r9270 test' . $svnrepo/r9270 &&
+ svn import -m 'r9270 test' . '$svnrepo/r9270' &&
cd .. &&
- svn co $svnrepo/r9270/trunk/subversion/bindings/swig/perl r9270 &&
+ svn co '$svnrepo/r9270/trunk/subversion/bindings/swig/perl' r9270 &&
cd r9270 &&
svn mkdir native &&
svn mv t native/t &&
@@ -130,7 +130,7 @@ test_expect_success 'follow-parent avoids deleting relevant info' "
svn commit -m 'reorg test' &&
cd .. &&
git-svn init --minimize-url -i r9270-t \
- $svnrepo/r9270/trunk/subversion/bindings/swig/perl/native/t &&
+ '$svnrepo/r9270/trunk/subversion/bindings/swig/perl/native/t' &&
git-svn fetch -i r9270-t &&
test \`git rev-list r9270-t | wc -l\` -eq 2 &&
test \"\`git ls-tree --name-only r9270-t~1\`\" = \
@@ -138,9 +138,9 @@ test_expect_success 'follow-parent avoids deleting relevant info' "
"
test_expect_success "track initial change if it was only made to parent" "
- svn cp -m 'wheee!' $svnrepo/r9270/trunk $svnrepo/r9270/drunk &&
+ svn cp -m 'wheee!' '$svnrepo/r9270/trunk' '$svnrepo/r9270/drunk' &&
git-svn init --minimize-url -i r9270-d \
- $svnrepo/r9270/drunk/subversion/bindings/swig/perl/native/t &&
+ '$svnrepo/r9270/drunk/subversion/bindings/swig/perl/native/t' &&
git-svn fetch -i r9270-d &&
test \`git rev-list r9270-d | wc -l\` -eq 3 &&
test \"\`git ls-tree --name-only r9270-t\`\" = \
@@ -150,7 +150,7 @@ test_expect_success "track initial change if it was only made to parent" "
"
test_expect_success "track multi-parent paths" "
- svn cp -m 'resurrect /glob' $svnrepo/r9270 $svnrepo/glob &&
+ svn cp -m 'resurrect /glob' '$svnrepo/r9270' '$svnrepo/glob' &&
git-svn multi-fetch &&
test \`git cat-file commit refs/remotes/glob | \
grep '^parent ' | wc -l\` -eq 2
@@ -161,8 +161,8 @@ test_expect_success "multi-fetch continues to work" "
"
test_expect_success "multi-fetch works off a 'clean' repository" "
- rm -r $GIT_DIR/svn $GIT_DIR/refs/remotes $GIT_DIR/logs &&
- mkdir $GIT_DIR/svn &&
+ rm -r '$GIT_DIR/svn' '$GIT_DIR/refs/remotes' '$GIT_DIR/logs' &&
+ mkdir '$GIT_DIR/svn' &&
git-svn multi-fetch
"
diff --git a/t/t9105-git-svn-commit-diff.sh b/t/t9105-git-svn-commit-diff.sh
index 318e172..2e1eb75 100755
--- a/t/t9105-git-svn-commit-diff.sh
+++ b/t/t9105-git-svn-commit-diff.sh
@@ -8,7 +8,7 @@ test_expect_success 'initialize repo' "
mkdir import &&
cd import &&
echo hello > readme &&
- svn import -m 'initial' . $svnrepo &&
+ svn import -m 'initial' . '$svnrepo' &&
cd .. &&
echo hello > readme &&
git update-index --add readme &&
@@ -27,16 +27,16 @@ prev=`git rev-parse --verify HEAD^1`
test_expect_success 'test the commit-diff command' "
test -n '$prev' && test -n '$head' &&
git-svn commit-diff -r1 '$prev' '$head' '$svnrepo' &&
- svn co $svnrepo wc &&
+ svn co '$svnrepo' wc &&
cmp readme wc/readme
"
test_expect_success 'commit-diff to a sub-directory (with git-svn config)' "
- svn import -m 'sub-directory' import $svnrepo/subdir &&
- git-svn init --minimize-url $svnrepo/subdir &&
+ svn import -m 'sub-directory' import '$svnrepo/subdir' &&
+ git-svn init --minimize-url '$svnrepo/subdir' &&
git-svn fetch &&
git-svn commit-diff -r3 '$prev' '$head' &&
- svn cat $svnrepo/subdir/readme > readme.2 &&
+ svn cat '$svnrepo/subdir/readme' > readme.2 &&
cmp readme readme.2
"
diff --git a/t/t9106-git-svn-commit-diff-clobber.sh b/t/t9106-git-svn-commit-diff-clobber.sh
index 79b7968..bb42339 100755
--- a/t/t9106-git-svn-commit-diff-clobber.sh
+++ b/t/t9106-git-svn-commit-diff-clobber.sh
@@ -8,14 +8,14 @@ test_expect_success 'initialize repo' "
mkdir import &&
cd import &&
echo initial > file &&
- svn import -m 'initial' . $svnrepo &&
+ svn import -m 'initial' . '$svnrepo' &&
cd .. &&
echo initial > file &&
git update-index --add file &&
git commit -a -m 'initial'
"
test_expect_success 'commit change from svn side' "
- svn co $svnrepo t.svn &&
+ svn co '$svnrepo' t.svn &&
cd t.svn &&
echo second line from svn >> file &&
poke file &&
@@ -27,7 +27,7 @@ test_expect_success 'commit change from svn side' "
test_expect_failure 'commit conflicting change from git' "
echo second line from git >> file &&
git commit -a -m 'second line from git' &&
- git-svn commit-diff -r1 HEAD~1 HEAD $svnrepo
+ git-svn commit-diff -r1 HEAD~1 HEAD '$svnrepo'
" || true
test_expect_success 'commit complementing change from git' "
@@ -36,14 +36,14 @@ test_expect_success 'commit complementing change from git' "
git commit -a -m 'second line from svn' &&
echo third line from git >> file &&
git commit -a -m 'third line from git' &&
- git-svn commit-diff -r2 HEAD~1 HEAD $svnrepo
+ git-svn commit-diff -r2 HEAD~1 HEAD '$svnrepo'
"
test_expect_failure 'dcommit fails to commit because of conflict' "
- git-svn init $svnrepo &&
+ git-svn init '$svnrepo' &&
git-svn fetch &&
git reset --hard refs/remotes/git-svn &&
- svn co $svnrepo t.svn &&
+ svn co '$svnrepo' t.svn &&
cd t.svn &&
echo fourth line from svn >> file &&
poke file &&
@@ -67,7 +67,7 @@ test_expect_success 'dcommit does the svn equivalent of an index merge' "
"
test_expect_success 'commit another change from svn side' "
- svn co $svnrepo t.svn &&
+ svn co '$svnrepo' t.svn &&
cd t.svn &&
echo third line from svn >> file &&
poke file &&
diff --git a/t/t9107-git-svn-migrate.sh b/t/t9107-git-svn-migrate.sh
index 67fdf70..90bf786 100755
--- a/t/t9107-git-svn-migrate.sh
+++ b/t/t9107-git-svn-migrate.sh
@@ -4,7 +4,7 @@ test_description='git-svn metadata migrations from previous versions'
. ./lib-git-svn.sh
test_expect_success 'setup old-looking metadata' "
- cp $GIT_DIR/config $GIT_DIR/config-old-git-svn &&
+ cp '$GIT_DIR/config' '$GIT_DIR/config-old-git-svn' &&
mkdir import &&
cd import &&
for i in trunk branches/a branches/b \
@@ -12,13 +12,13 @@ test_expect_success 'setup old-looking metadata' "
mkdir -p \$i && \
echo hello >> \$i/README || exit 1
done && \
- svn import -m test . $svnrepo
+ svn import -m test . '$svnrepo'
cd .. &&
- git-svn init $svnrepo &&
+ git-svn init '$svnrepo' &&
git-svn fetch &&
- mv $GIT_DIR/svn/* $GIT_DIR/ &&
- mv $GIT_DIR/svn/.metadata $GIT_DIR/ &&
- rmdir $GIT_DIR/svn &&
+ mv '$GIT_DIR'/svn/* '$GIT_DIR/' &&
+ mv '$GIT_DIR/svn/.metadata' '$GIT_DIR/' &&
+ rmdir '$GIT_DIR/svn' &&
git update-ref refs/heads/git-svn-HEAD refs/remotes/git-svn &&
git update-ref refs/heads/svn-HEAD refs/remotes/git-svn &&
git update-ref -d refs/remotes/git-svn refs/remotes/git-svn
@@ -28,20 +28,20 @@ head=`git rev-parse --verify refs/heads/git-svn-HEAD^0`
test_expect_success 'git-svn-HEAD is a real HEAD' "test -n '$head'"
test_expect_success 'initialize old-style (v0) git-svn layout' "
- mkdir -p $GIT_DIR/git-svn/info $GIT_DIR/svn/info &&
- echo $svnrepo > $GIT_DIR/git-svn/info/url &&
- echo $svnrepo > $GIT_DIR/svn/info/url &&
+ mkdir -p '$GIT_DIR/git-svn/info' '$GIT_DIR/svn/info' &&
+ echo '$svnrepo' > '$GIT_DIR/git-svn/info/url' &&
+ echo '$svnrepo' > '$GIT_DIR/svn/info/url' &&
git-svn migrate &&
- ! test -d $GIT_DIR/git-svn &&
+ ! test -d '$GIT_DIR/git-svn' &&
git rev-parse --verify refs/remotes/git-svn^0 &&
git rev-parse --verify refs/remotes/svn^0 &&
- test \`git config --get svn-remote.svn.url\` = '$svnrepo' &&
+ test \"\`git config --get svn-remote.svn.url\`\" = \"$svnrepo\" &&
test \`git config --get svn-remote.svn.fetch\` = \
':refs/remotes/git-svn'
"
test_expect_success 'initialize a multi-repository repo' "
- git-svn init $svnrepo -T trunk -t tags -b branches &&
+ git-svn init '$svnrepo' -T trunk -t tags -b branches &&
git config --get-all svn-remote.svn.fetch > fetch.out &&
grep '^trunk:refs/remotes/trunk$' fetch.out &&
test -n \"\`git config --get svn-remote.svn.branches \
@@ -76,14 +76,14 @@ test_expect_success 'multi-fetch works on partial urls + paths' "
test_expect_success 'migrate --minimize on old inited layout' "
git config --unset-all svn-remote.svn.fetch &&
git config --unset-all svn-remote.svn.url &&
- rm -rf $GIT_DIR/svn &&
+ rm -rf '$GIT_DIR/svn' &&
for i in \`cat fetch.out\`; do
path=\`expr \$i : '\\([^:]*\\):.*$'\`
ref=\`expr \$i : '[^:]*:refs/remotes/\\(.*\\)$'\`
if test -z \"\$ref\"; then continue; fi
if test -n \"\$path\"; then path=\"/\$path\"; fi
- ( mkdir -p $GIT_DIR/svn/\$ref/info/ &&
- echo $svnrepo\$path > $GIT_DIR/svn/\$ref/info/url ) || exit 1;
+ ( mkdir -p '$GIT_DIR'/svn/\$ref/info/ &&
+ echo '$svnrepo'\$path > '$GIT_DIR'/svn/\$ref/info/url ) || exit 1;
done &&
git-svn migrate --minimize &&
test -z \"\`git config -l |grep -v '^svn-remote\.git-svn\.'\`\" &&
@@ -99,13 +99,13 @@ test_expect_success 'migrate --minimize on old inited layout' "
test_expect_success ".rev_db auto-converted to .rev_db.UUID" "
git-svn fetch -i trunk &&
- expect=$GIT_DIR/svn/trunk/.rev_db.* &&
+ expect=\"\`find \"\$GIT_DIR\"/svn/trunk/ -name '.rev_db.*'\`\" &&
test -n \"\$expect\" &&
- mv \$expect $GIT_DIR/svn/trunk/.rev_db &&
+ mv \"\$expect\" \"\$GIT_DIR\"/svn/trunk/.rev_db &&
git-svn fetch -i trunk &&
- test -L $GIT_DIR/svn/trunk/.rev_db &&
- test -f \$expect &&
- cmp \$expect $GIT_DIR/svn/trunk/.rev_db
+ test -L \"\$GIT_DIR\"/svn/trunk/.rev_db &&
+ test -f \"\$expect\" &&
+ cmp \"\$expect\" \"\$GIT_DIR\"/svn/trunk/.rev_db
"
test_done
diff --git a/t/t9108-git-svn-glob.sh b/t/t9108-git-svn-glob.sh
index db4344c..c6dc0ef 100755
--- a/t/t9108-git-svn-glob.sh
+++ b/t/t9108-git-svn-glob.sh
@@ -14,8 +14,8 @@ test_expect_success 'test refspec globbing' "
mkdir -p trunk/src/a trunk/src/b trunk/doc &&
echo 'hello world' > trunk/src/a/readme &&
echo 'goodbye world' > trunk/src/b/readme &&
- svn import -m 'initial' trunk $svnrepo/trunk &&
- svn co $svnrepo tmp &&
+ svn import -m 'initial' trunk '$svnrepo/trunk' &&
+ svn co '$svnrepo' tmp &&
cd tmp &&
mkdir branches tags &&
svn add branches tags &&
@@ -38,7 +38,7 @@ test_expect_success 'test refspec globbing' "
poke tags/end/src/b/readme &&
svn commit -m 'nothing to see here'
cd .. &&
- git config --add svn-remote.svn.url $svnrepo &&
+ git config --add svn-remote.svn.url '$svnrepo' &&
git config --add svn-remote.svn.fetch \
'trunk/src/a:refs/remotes/trunk' &&
git config --add svn-remote.svn.branches \
@@ -60,7 +60,7 @@ echo nothing to see here >> expect.two
cat expect.end >> expect.two
test_expect_success 'test left-hand-side only globbing' "
- git config --add svn-remote.two.url $svnrepo &&
+ git config --add svn-remote.two.url '$svnrepo' &&
git config --add svn-remote.two.fetch trunk:refs/remotes/two/trunk &&
git config --add svn-remote.two.branches \
'branches/*:refs/remotes/two/branches/*' &&
diff --git a/t/t9110-git-svn-use-svm-props.sh b/t/t9110-git-svn-use-svm-props.sh
index 6235af4..d4ab01f 100755
--- a/t/t9110-git-svn-use-svm-props.sh
+++ b/t/t9110-git-svn-use-svm-props.sh
@@ -8,11 +8,11 @@ test_description='git-svn useSvmProps test'
. ./lib-git-svn.sh
test_expect_success 'load svm repo' "
- svnadmin load -q $rawsvnrepo < ../t9110/svm.dump &&
- git-svn init --minimize-url -R arr -i bar $svnrepo/mirror/arr &&
- git-svn init --minimize-url -R argh -i dir $svnrepo/mirror/argh &&
+ svnadmin load -q '$rawsvnrepo' < ../t9110/svm.dump &&
+ git-svn init --minimize-url -R arr -i bar '$svnrepo/mirror/arr' &&
+ git-svn init --minimize-url -R argh -i dir '$svnrepo/mirror/argh' &&
git-svn init --minimize-url -R argh -i e \
- $svnrepo/mirror/argh/a/b/c/d/e &&
+ '$svnrepo/mirror/argh/a/b/c/d/e' &&
git config svn.useSvmProps true &&
git-svn fetch --all
"
diff --git a/t/t9111-git-svn-use-svnsync-props.sh b/t/t9111-git-svn-use-svnsync-props.sh
index ec7dedd..936f023 100755
--- a/t/t9111-git-svn-use-svnsync-props.sh
+++ b/t/t9111-git-svn-use-svnsync-props.sh
@@ -8,10 +8,10 @@ test_description='git-svn useSvnsyncProps test'
. ./lib-git-svn.sh
test_expect_success 'load svnsync repo' "
- svnadmin load -q $rawsvnrepo < ../t9111/svnsync.dump &&
- git-svn init --minimize-url -R arr -i bar $svnrepo/bar &&
- git-svn init --minimize-url -R argh -i dir $svnrepo/dir &&
- git-svn init --minimize-url -R argh -i e $svnrepo/dir/a/b/c/d/e &&
+ svnadmin load -q '$rawsvnrepo' < ../t9111/svnsync.dump &&
+ git-svn init --minimize-url -R arr -i bar '$svnrepo/bar' &&
+ git-svn init --minimize-url -R argh -i dir '$svnrepo/dir' &&
+ git-svn init --minimize-url -R argh -i e '$svnrepo/dir/a/b/c/d/e' &&
git config svn.useSvnsyncProps true &&
git-svn fetch --all
"
diff --git a/t/t9112-git-svn-md5less-file.sh b/t/t9112-git-svn-md5less-file.sh
index 08313bb..b095583 100755
--- a/t/t9112-git-svn-md5less-file.sh
+++ b/t/t9112-git-svn-md5less-file.sh
@@ -38,8 +38,8 @@ PROPS-END
EOF
-test_expect_success 'load svn dumpfile' "svnadmin load $rawsvnrepo < dumpfile.svn"
+test_expect_success 'load svn dumpfile' "svnadmin load '$rawsvnrepo' < dumpfile.svn"
-test_expect_success 'initialize git-svn' "git-svn init $svnrepo"
+test_expect_success 'initialize git-svn' "git-svn init '$svnrepo'"
test_expect_success 'fetch revisions from svn' 'git-svn fetch'
test_done
diff --git a/t/t9113-git-svn-dcommit-new-file.sh b/t/t9113-git-svn-dcommit-new-file.sh
index 9ef0db9..0088c75 100755
--- a/t/t9113-git-svn-dcommit-new-file.sh
+++ b/t/t9113-git-svn-dcommit-new-file.sh
@@ -15,14 +15,14 @@ test_description='git-svn dcommit new files over svn:// test'
start_svnserve () {
svnserve --listen-port $SVNSERVE_PORT \
- --root $rawsvnrepo \
+ --root '$rawsvnrepo' \
--listen-once \
--listen-host 127.0.0.1 &
}
test_expect_success 'start tracking an empty repo' "
- svn mkdir -m 'empty dir' $svnrepo/empty-dir &&
- echo anon-access = write >> $rawsvnrepo/conf/svnserve.conf &&
+ svn mkdir -m 'empty dir' '$svnrepo/empty-dir' &&
+ echo anon-access = write >> '$rawsvnrepo/conf/svnserve.conf' &&
start_svnserve &&
git svn init svn://127.0.0.1:$SVNSERVE_PORT &&
git svn fetch
diff --git a/t/t9114-git-svn-dcommit-merge.sh b/t/t9114-git-svn-dcommit-merge.sh
index d6ca955..64ec7fd 100755
--- a/t/t9114-git-svn-dcommit-merge.sh
+++ b/t/t9114-git-svn-dcommit-merge.sh
@@ -35,7 +35,7 @@ EOF
}
test_expect_success 'setup svn repository' "
- svn co $svnrepo mysvnwork &&
+ svn co '$svnrepo' mysvnwork &&
mkdir -p mysvnwork/trunk &&
cd mysvnwork &&
big_text_block >> trunk/README &&
@@ -45,7 +45,7 @@ test_expect_success 'setup svn repository' "
"
test_expect_success 'setup git mirror and merge' "
- git svn init $svnrepo -t tags -T trunk -b branches &&
+ git svn init '$svnrepo' -t tags -T trunk -b branches &&
git svn fetch &&
git checkout --track -b svn remotes/trunk &&
git checkout -b merge &&
diff --git a/t/t9115-git-svn-dcommit-funky-renames.sh b/t/t9115-git-svn-dcommit-funky-renames.sh
index 182299c..653578d 100755
--- a/t/t9115-git-svn-dcommit-funky-renames.sh
+++ b/t/t9115-git-svn-dcommit-funky-renames.sh
@@ -8,12 +8,12 @@ test_description='git-svn dcommit can commit renames of files with ugly names'
. ./lib-git-svn.sh
test_expect_success 'load repository with strange names' "
- svnadmin load -q $rawsvnrepo < ../t9115/funky-names.dump &&
+ svnadmin load -q '$rawsvnrepo' < ../t9115/funky-names.dump &&
start_httpd
"
test_expect_success 'init and fetch repository' "
- git svn init $svnrepo &&
+ git svn init '$svnrepo' &&
git svn fetch &&
git reset --hard git-svn
"
diff --git a/t/t9116-git-svn-log.sh b/t/t9116-git-svn-log.sh
index 0d4e6b3..70c0c5f 100755
--- a/t/t9116-git-svn-log.sh
+++ b/t/t9116-git-svn-log.sh
@@ -14,9 +14,9 @@ test_expect_success 'setup repository and import' "
mkdir -p \$i && \
echo hello >> \$i/README || exit 1
done && \
- svn import -m test . $svnrepo
+ svn import -m test . '$svnrepo'
cd .. &&
- git-svn init $svnrepo -T trunk -b branches -t tags &&
+ git-svn init '$svnrepo' -T trunk -b branches -t tags &&
git-svn fetch &&
git reset --hard trunk &&
echo bye >> README &&
diff --git a/t/test-lib.sh b/t/test-lib.sh
index cc1253c..a68415f 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -229,7 +229,7 @@ test_create_repo () {
repo="$1"
mkdir "$repo"
cd "$repo" || error "Cannot setup test environment"
- "$GIT_EXEC_PATH/git" init --template=$GIT_EXEC_PATH/templates/blt/ >/dev/null 2>&1 ||
+ "$GIT_EXEC_PATH/git" init --template="$GIT_EXEC_PATH/templates/blt/" >/dev/null 2>&1 ||
error "cannot run git init -- have you built things yet?"
mv .git/hooks .git/hooks-disabled
cd "$owd"
--
1.5.3.1
^ permalink raw reply related [relevance 11%]
* [PATCH] Fixing path quoting issues
@ 2007-10-10 21:13 11% Jonathan del Strother
0 siblings, 0 replies; 200+ results
From: Jonathan del Strother @ 2007-10-10 21:13 UTC (permalink / raw)
To: git, gitster; +Cc: Jonathan del Strother
git-rebase and a number of tests didn't properly quote paths, leading to problems when run from a path with a space in.
Signed-off-by: Jonathan del Strother <jon.delStrother@bestbefore.tv>
---
git-rebase.sh | 26 +++++-----
t/t1020-subdirectory.sh | 22 ++++----
t/t3050-subprojects-fetch.sh | 2 +-
t/t3404-rebase-interactive.sh | 2 +-
t/t5500-fetch-pack.sh | 2 +-
t/t5700-clone-reference.sh | 2 +-
t/t7003-filter-branch.sh | 2 +-
t/t7501-commit.sh | 74 +++++++++++++++---------------
t/t9100-git-svn-basic.sh | 18 ++++----
t/t9101-git-svn-props.sh | 6 +-
t/t9102-git-svn-deep-rmdir.sh | 6 +-
t/t9104-git-svn-follow-parent.sh | 50 ++++++++++----------
t/t9105-git-svn-commit-diff.sh | 10 ++--
t/t9106-git-svn-commit-diff-clobber.sh | 14 +++---
t/t9107-git-svn-migrate.sh | 40 ++++++++--------
t/t9108-git-svn-glob.sh | 8 ++--
t/t9110-git-svn-use-svm-props.sh | 8 ++--
t/t9111-git-svn-use-svnsync-props.sh | 8 ++--
t/t9112-git-svn-md5less-file.sh | 4 +-
t/t9113-git-svn-dcommit-new-file.sh | 6 +-
t/t9114-git-svn-dcommit-merge.sh | 4 +-
t/t9115-git-svn-dcommit-funky-renames.sh | 4 +-
t/t9116-git-svn-log.sh | 4 +-
t/test-lib.sh | 2 +-
24 files changed, 162 insertions(+), 162 deletions(-)
diff --git a/git-rebase.sh b/git-rebase.sh
index 1583402..b48397e 100755
--- a/git-rebase.sh
+++ b/git-rebase.sh
@@ -59,7 +59,7 @@ continue_merge () {
die "$RESOLVEMSG"
fi
- cmt=`cat $dotest/current`
+ cmt=`cat "$dotest/current"`
if ! git diff-index --quiet HEAD
then
if ! git-commit -C "$cmt"
@@ -84,14 +84,14 @@ continue_merge () {
}
call_merge () {
- cmt="$(cat $dotest/cmt.$1)"
+ cmt="$(cat "$dotest/cmt.$1")"
echo "$cmt" > "$dotest/current"
hd=$(git rev-parse --verify HEAD)
cmt_name=$(git symbolic-ref HEAD)
- msgnum=$(cat $dotest/msgnum)
- end=$(cat $dotest/end)
+ msgnum=$(cat "$dotest/msgnum")
+ end=$(cat "$dotest/end")
eval GITHEAD_$cmt='"${cmt_name##refs/heads/}~$(($end - $msgnum))"'
- eval GITHEAD_$hd='"$(cat $dotest/onto_name)"'
+ eval GITHEAD_$hd='"$(cat \"$dotest/onto_name\")"'
export GITHEAD_$cmt GITHEAD_$hd
git-merge-$strategy "$cmt^" -- "$hd" "$cmt"
rv=$?
@@ -140,10 +140,10 @@ do
}
if test -d "$dotest"
then
- prev_head="`cat $dotest/prev_head`"
- end="`cat $dotest/end`"
- msgnum="`cat $dotest/msgnum`"
- onto="`cat $dotest/onto`"
+ prev_head="`cat \"$dotest/prev_head\"`"
+ end="`cat \"$dotest/end\"`"
+ msgnum="`cat \"$dotest/msgnum\"`"
+ onto="`cat \"$dotest/onto\"`"
continue_merge
while test "$msgnum" -le "$end"
do
@@ -160,11 +160,11 @@ do
if test -d "$dotest"
then
git rerere clear
- prev_head="`cat $dotest/prev_head`"
- end="`cat $dotest/end`"
- msgnum="`cat $dotest/msgnum`"
+ prev_head="`cat \"$dotest/prev_head\"`"
+ end="`cat \"$dotest/end\"`"
+ msgnum="`cat \"$dotest/msgnum\"`"
msgnum=$(($msgnum + 1))
- onto="`cat $dotest/onto`"
+ onto="`cat \"$dotest/onto\"`"
while test "$msgnum" -le "$end"
do
call_merge "$msgnum"
diff --git a/t/t1020-subdirectory.sh b/t/t1020-subdirectory.sh
index b9cef34..5ed7fa4 100755
--- a/t/t1020-subdirectory.sh
+++ b/t/t1020-subdirectory.sh
@@ -21,7 +21,7 @@ LF='
'
test_expect_success 'update-index and ls-files' '
- cd $HERE &&
+ cd "$HERE" &&
git update-index --add one &&
case "`git ls-files`" in
one) echo ok one ;;
@@ -41,7 +41,7 @@ test_expect_success 'update-index and ls-files' '
'
test_expect_success 'cat-file' '
- cd $HERE &&
+ cd "$HERE" &&
two=`git ls-files -s dir/two` &&
two=`expr "$two" : "[0-7]* \\([0-9a-f]*\\)"` &&
echo "$two" &&
@@ -54,7 +54,7 @@ test_expect_success 'cat-file' '
rm -f actual dir/actual
test_expect_success 'diff-files' '
- cd $HERE &&
+ cd "$HERE" &&
echo a >>one &&
echo d >>dir/two &&
case "`git diff-files --name-only`" in
@@ -74,7 +74,7 @@ test_expect_success 'diff-files' '
'
test_expect_success 'write-tree' '
- cd $HERE &&
+ cd "$HERE" &&
top=`git write-tree` &&
echo $top &&
cd dir &&
@@ -84,7 +84,7 @@ test_expect_success 'write-tree' '
'
test_expect_success 'checkout-index' '
- cd $HERE &&
+ cd "$HERE" &&
git checkout-index -f -u one &&
cmp one original.one &&
cd dir &&
@@ -93,7 +93,7 @@ test_expect_success 'checkout-index' '
'
test_expect_success 'read-tree' '
- cd $HERE &&
+ cd "$HERE" &&
rm -f one dir/two &&
tree=`git write-tree` &&
git read-tree --reset -u "$tree" &&
@@ -107,27 +107,27 @@ test_expect_success 'read-tree' '
'
test_expect_success 'no file/rev ambiguity check inside .git' '
- cd $HERE &&
+ cd "$HERE" &&
git commit -a -m 1 &&
- cd $HERE/.git &&
+ cd "$HERE/.git" &&
git show -s HEAD
'
test_expect_success 'no file/rev ambiguity check inside a bare repo' '
- cd $HERE &&
+ cd "$HERE" &&
git clone -s --bare .git foo.git &&
cd foo.git && GIT_DIR=. git show -s HEAD
'
# This still does not work as it should...
: test_expect_success 'no file/rev ambiguity check inside a bare repo' '
- cd $HERE &&
+ cd "$HERE" &&
git clone -s --bare .git foo.git &&
cd foo.git && git show -s HEAD
'
test_expect_success 'detection should not be fooled by a symlink' '
- cd $HERE &&
+ cd "$HERE" &&
rm -fr foo.git &&
git clone -s .git another &&
ln -s another yetanother &&
diff --git a/t/t3050-subprojects-fetch.sh b/t/t3050-subprojects-fetch.sh
index 34f26a8..4b74cc6 100755
--- a/t/t3050-subprojects-fetch.sh
+++ b/t/t3050-subprojects-fetch.sh
@@ -20,7 +20,7 @@ test_expect_success setup '
'
test_expect_success clone '
- git clone file://`pwd`/.git cloned &&
+ git clone "file://`pwd`/.git" cloned &&
(git rev-parse HEAD; git ls-files -s) >expected &&
(
cd cloned &&
diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh
index 1113904..f321787 100755
--- a/t/t3404-rebase-interactive.sh
+++ b/t/t3404-rebase-interactive.sh
@@ -92,7 +92,7 @@ done
EOF
chmod a+x fake-editor.sh
-VISUAL="$(pwd)/fake-editor.sh"
+VISUAL="'$(pwd)/fake-editor.sh'"
export VISUAL
test_expect_success 'no changes are a nop' '
diff --git a/t/t5500-fetch-pack.sh b/t/t5500-fetch-pack.sh
index 7b6798d..5489ffe 100755
--- a/t/t5500-fetch-pack.sh
+++ b/t/t5500-fetch-pack.sh
@@ -129,7 +129,7 @@ pull_to_client 2nd "B" $((64*3))
pull_to_client 3rd "A" $((1*3)) # old fails
-test_expect_success "clone shallow" "git-clone --depth 2 file://`pwd`/. shallow"
+test_expect_success "clone shallow" "git-clone --depth 2 \"file://`pwd`/.\" shallow"
(cd shallow; git count-objects -v) > count.shallow
diff --git a/t/t5700-clone-reference.sh b/t/t5700-clone-reference.sh
index 4e93aaa..8bb34f9 100755
--- a/t/t5700-clone-reference.sh
+++ b/t/t5700-clone-reference.sh
@@ -51,7 +51,7 @@ diff expected current'
cd "$base_dir"
test_expect_success 'cloning with reference (no -l -s)' \
-'git clone --reference B file://`pwd`/A D'
+'git clone --reference B "file://`pwd`/A" D'
cd "$base_dir"
diff --git a/t/t7003-filter-branch.sh b/t/t7003-filter-branch.sh
index e935b20..1ab5392 100755
--- a/t/t7003-filter-branch.sh
+++ b/t/t7003-filter-branch.sh
@@ -107,7 +107,7 @@ test_expect_success 'use index-filter to move into a subdirectory' '
"git ls-files -s | sed \"s-\\t-&newsubdir/-\" |
GIT_INDEX_FILE=\$GIT_INDEX_FILE.new \
git update-index --index-info &&
- mv \$GIT_INDEX_FILE.new \$GIT_INDEX_FILE" directorymoved &&
+ mv \"\$GIT_INDEX_FILE.new\" \"\$GIT_INDEX_FILE\"" directorymoved &&
test -z "$(git diff HEAD directorymoved:newsubdir)"'
test_expect_success 'stops when msg filter fails' '
diff --git a/t/t7501-commit.sh b/t/t7501-commit.sh
index b151b51..f3d0ab9 100644
--- a/t/t7501-commit.sh
+++ b/t/t7501-commit.sh
@@ -69,7 +69,7 @@ test_expect_success \
cat >editor <<\EOF
#!/bin/sh
-sed -i -e "s/a file/an amend commit/g" $1
+sed -i -e "s/a file/an amend commit/g" "$1"
EOF
chmod 755 editor
@@ -80,40 +80,40 @@ test_expect_success \
test_expect_failure \
"passing -m and -F" \
"echo 'enough with the bongos' >file && \
- git-commit -F msg -m amending ."
+ git-commit -F msg -m amending ."
test_expect_success \
- "using message from other commit" \
- "git-commit -C HEAD^ ."
+ "using message from other commit" \
+ "git-commit -C HEAD^ ."
cat >editor <<\EOF
#!/bin/sh
-sed -i -e "s/amend/older/g" $1
+sed -i -e "s/amend/older/g" "$1"
EOF
chmod 755 editor
test_expect_success \
- "editing message from other commit" \
- "echo 'hula hula' >file && \
- VISUAL=./editor git-commit -c HEAD^ -a"
+ "editing message from other commit" \
+ "echo 'hula hula' >file && \
+ VISUAL=./editor git-commit -c HEAD^ -a"
test_expect_success \
- "message from stdin" \
- "echo 'silly new contents' >file && \
- echo commit message from stdin | git-commit -F - -a"
+ "message from stdin" \
+ "echo 'silly new contents' >file && \
+ echo commit message from stdin | git-commit -F - -a"
test_expect_success \
- "overriding author from command line" \
- "echo 'gak' >file && \
- git-commit -m 'author' --author 'Rubber Duck <rduck@convoy.org>' -a"
+ "overriding author from command line" \
+ "echo 'gak' >file && \
+ git-commit -m 'author' --author 'Rubber Duck <rduck@convoy.org>' -a"
test_expect_success \
- "interactive add" \
- "echo 7 | git-commit --interactive | grep 'What now'"
+ "interactive add" \
+ "echo 7 | git-commit --interactive | grep 'What now'"
test_expect_success \
- "showing committed revisions" \
- "git-rev-list HEAD >current"
+ "showing committed revisions" \
+ "git-rev-list HEAD >current"
# We could just check the head sha1, but checking each commit makes it
# easier to isolate bugs.
@@ -128,38 +128,38 @@ d381ac431806e53f3dd7ac2f1ae0534f36d738b9
EOF
test_expect_success \
- 'validate git-rev-list output.' \
- 'diff current expected'
+ 'validate git-rev-list output.' \
+ 'diff current expected'
test_expect_success 'partial commit that involves removal (1)' '
- git rm --cached file &&
- mv file elif &&
- git add elif &&
- git commit -m "Partial: add elif" elif &&
- git diff-tree --name-status HEAD^ HEAD >current &&
- echo "A elif" >expected &&
- diff expected current
+ git rm --cached file &&
+ mv file elif &&
+ git add elif &&
+ git commit -m "Partial: add elif" elif &&
+ git diff-tree --name-status HEAD^ HEAD >current &&
+ echo "A elif" >expected &&
+ diff -b expected current
'
test_expect_success 'partial commit that involves removal (2)' '
- git commit -m "Partial: remove file" file &&
- git diff-tree --name-status HEAD^ HEAD >current &&
- echo "D file" >expected &&
- diff expected current
+ git commit -m "Partial: remove file" file &&
+ git diff-tree --name-status HEAD^ HEAD >current &&
+ echo "D file" >expected &&
+ diff -b expected current
'
test_expect_success 'partial commit that involves removal (3)' '
- git rm --cached elif &&
- echo elif >elif &&
- git commit -m "Partial: modify elif" elif &&
- git diff-tree --name-status HEAD^ HEAD >current &&
- echo "M elif" >expected &&
- diff expected current
+ git rm --cached elif &&
+ echo elif >elif &&
+ git commit -m "Partial: modify elif" elif &&
+ git diff-tree --name-status HEAD^ HEAD >current &&
+ echo "M elif" >expected &&
+ diff -b expected current
'
diff --git a/t/t9100-git-svn-basic.sh b/t/t9100-git-svn-basic.sh
index 614cf50..c3585da 100755
--- a/t/t9100-git-svn-basic.sh
+++ b/t/t9100-git-svn-basic.sh
@@ -31,16 +31,16 @@ test_expect_success \
echo 'zzz' > bar/zzz &&
echo '#!/bin/sh' > exec.sh &&
chmod +x exec.sh &&
- svn import -m 'import for git-svn' . $svnrepo >/dev/null &&
+ svn import -m 'import for git-svn' . '$svnrepo' >/dev/null &&
cd .. &&
rm -rf import &&
- git-svn init $svnrepo"
+ git-svn init '$svnrepo'"
test_expect_success \
'import an SVN revision into git' \
'git-svn fetch'
-test_expect_success "checkout from svn" "svn co $svnrepo '$SVN_TREE'"
+test_expect_success "checkout from svn" "svn co '$svnrepo' '$SVN_TREE'"
name='try a deep --rmdir with a commit'
test_expect_success "$name" "
@@ -169,7 +169,7 @@ test_expect_success "$name" "
svn up '$SVN_TREE' &&
test -f '$SVN_TREE'/exec-2.sh &&
test ! -L '$SVN_TREE'/exec-2.sh &&
- git diff help $SVN_TREE/exec-2.sh"
+ git diff help '$SVN_TREE/exec-2.sh'"
if test "$have_utf8" = t
then
@@ -190,7 +190,7 @@ name='test fetch functionality (svn => git) with alternate GIT_SVN_ID'
GIT_SVN_ID=alt
export GIT_SVN_ID
test_expect_success "$name" \
- "git-svn init $svnrepo && git-svn fetch &&
+ "git-svn init '$svnrepo' && git-svn fetch &&
git rev-list --pretty=raw remotes/git-svn | grep ^tree | uniq > a &&
git rev-list --pretty=raw remotes/alt | grep ^tree | uniq > b &&
git diff a b"
@@ -220,16 +220,16 @@ test_expect_failure 'exit if remote refs are ambigious' "
"
test_expect_failure 'exit if init-ing a would clobber a URL' "
- svnadmin create ${PWD}/svnrepo2 &&
- svn mkdir -m 'mkdir bar' ${svnrepo}2/bar &&
+ svnadmin create '${PWD}/svnrepo2' &&
+ svn mkdir -m 'mkdir bar' '${svnrepo}2/bar' &&
git config --unset svn-remote.svn.fetch \
'^bar:refs/remotes/git-svn$' &&
- git-svn init ${svnrepo}2/bar
+ git-svn init '${svnrepo}2/bar'
"
test_expect_success \
'init allows us to connect to another directory in the same repo' "
- git-svn init --minimize-url -i bar $svnrepo/bar &&
+ git-svn init --minimize-url -i bar '$svnrepo/bar' &&
git config --get svn-remote.svn.fetch \
'^bar:refs/remotes/bar$' &&
git config --get svn-remote.svn.fetch \
diff --git a/t/t9101-git-svn-props.sh b/t/t9101-git-svn-props.sh
index 5aac644..a1c85e0 100755
--- a/t/t9101-git-svn-props.sh
+++ b/t/t9101-git-svn-props.sh
@@ -52,7 +52,7 @@ EOF
cd ..
rm -rf import
-test_expect_success 'checkout working copy from svn' "svn co $svnrepo test_wc"
+test_expect_success 'checkout working copy from svn' "svn co '$svnrepo' test_wc"
test_expect_success 'setup some commits to svn' \
'cd test_wc &&
echo Greetings >> kw.c &&
@@ -66,7 +66,7 @@ test_expect_success 'setup some commits to svn' \
svn commit -m "Propset Id" &&
cd ..'
-test_expect_success 'initialize git-svn' "git-svn init $svnrepo"
+test_expect_success 'initialize git-svn' "git-svn init '$svnrepo'"
test_expect_success 'fetch revisions from svn' 'git-svn fetch'
name='test svn:keywords ignoring'
@@ -92,7 +92,7 @@ test_expect_success "propset CR on crlf files" \
test_expect_success 'fetch and pull latest from svn and checkout a new wc' \
"git-svn fetch &&
git pull . remotes/git-svn &&
- svn co $svnrepo new_wc"
+ svn co '$svnrepo' new_wc"
for i in crlf ne_crlf lf ne_lf cr ne_cr empty_cr empty_lf empty empty_crlf
do
diff --git a/t/t9102-git-svn-deep-rmdir.sh b/t/t9102-git-svn-deep-rmdir.sh
index 4e08083..99c8840 100755
--- a/t/t9102-git-svn-deep-rmdir.sh
+++ b/t/t9102-git-svn-deep-rmdir.sh
@@ -9,12 +9,12 @@ test_expect_success 'initialize repo' "
mkdir -p deeply/nested/directory/number/2 &&
echo foo > deeply/nested/directory/number/1/file &&
echo foo > deeply/nested/directory/number/2/another &&
- svn import -m 'import for git-svn' . $svnrepo &&
+ svn import -m 'import for git-svn' . '$svnrepo' &&
cd ..
"
test_expect_success 'mirror via git-svn' "
- git-svn init $svnrepo &&
+ git-svn init '$svnrepo' &&
git-svn fetch &&
git checkout -f -b test-rmdir remotes/git-svn
"
@@ -23,7 +23,7 @@ test_expect_success 'Try a commit on rmdir' "
git rm -f deeply/nested/directory/number/2/another &&
git commit -a -m 'remove another' &&
git-svn set-tree --rmdir HEAD &&
- svn ls -R $svnrepo | grep ^deeply/nested/directory/number/1
+ svn ls -R '$svnrepo' | grep ^deeply/nested/directory/number/1
"
diff --git a/t/t9104-git-svn-follow-parent.sh b/t/t9104-git-svn-follow-parent.sh
index 7ba7630..aa2bfe2 100755
--- a/t/t9104-git-svn-follow-parent.sh
+++ b/t/t9104-git-svn-follow-parent.sh
@@ -11,9 +11,9 @@ test_expect_success 'initialize repo' "
cd import &&
mkdir -p trunk &&
echo hello > trunk/readme &&
- svn import -m 'initial' . $svnrepo &&
+ svn import -m 'initial' . '$svnrepo' &&
cd .. &&
- svn co $svnrepo wc &&
+ svn co '$svnrepo' wc &&
cd wc &&
echo world >> trunk/readme &&
poke trunk/readme &&
@@ -27,7 +27,7 @@ test_expect_success 'initialize repo' "
"
test_expect_success 'init and fetch a moved directory' "
- git-svn init --minimize-url -i thunk $svnrepo/thunk &&
+ git-svn init --minimize-url -i thunk '$svnrepo/thunk' &&
git-svn fetch -i thunk &&
test \"\`git rev-parse --verify refs/remotes/thunk@2\`\" \
= \"\`git rev-parse --verify refs/remotes/thunk~1\`\" &&
@@ -38,7 +38,7 @@ test_expect_success 'init and fetch a moved directory' "
"
test_expect_success 'init and fetch from one svn-remote' "
- git config svn-remote.svn.url $svnrepo &&
+ git config svn-remote.svn.url '$svnrepo' &&
git config --add svn-remote.svn.fetch \
trunk:refs/remotes/svn/trunk &&
git config --add svn-remote.svn.fetch \
@@ -52,9 +52,9 @@ test_expect_success 'init and fetch from one svn-remote' "
test_expect_success 'follow deleted parent' "
(svn cp -m 'resurrecting trunk as junk' \
- $svnrepo/trunk@2 $svnrepo/junk ||
+ '$svnrepo/trunk@2' '$svnrepo'/junk ||
svn cp -m 'resurrecting trunk as junk' \
- -r2 $svnrepo/trunk $svnrepo/junk) &&
+ -r2 '$svnrepo/trunk' '$svnrepo/junk') &&
git config --add svn-remote.svn.fetch \
junk:refs/remotes/svn/junk &&
git-svn fetch -i svn/thunk &&
@@ -67,10 +67,10 @@ test_expect_success 'follow deleted parent' "
test_expect_success 'follow larger parent' "
mkdir -p import/trunk/thunk/bump/thud &&
echo hi > import/trunk/thunk/bump/thud/file &&
- svn import -m 'import a larger parent' import $svnrepo/larger-parent &&
- svn cp -m 'hi' $svnrepo/larger-parent $svnrepo/another-larger &&
+ svn import -m 'import a larger parent' import '$svnrepo/larger-parent' &&
+ svn cp -m 'hi' '$svnrepo/larger-parent' '$svnrepo/another-larger' &&
git-svn init --minimize-url -i larger \
- $svnrepo/another-larger/trunk/thunk/bump/thud &&
+ '$svnrepo/another-larger/trunk/thunk/bump/thud' &&
git-svn fetch -i larger &&
git rev-parse --verify refs/remotes/larger &&
git rev-parse --verify \
@@ -83,23 +83,23 @@ test_expect_success 'follow larger parent' "
"
test_expect_success 'follow higher-level parent' "
- svn mkdir -m 'follow higher-level parent' $svnrepo/blob &&
- svn co $svnrepo/blob blob &&
+ svn mkdir -m 'follow higher-level parent' '$svnrepo/blob' &&
+ svn co '$svnrepo/blob' blob &&
cd blob &&
echo hi > hi &&
svn add hi &&
svn commit -m 'hihi' &&
cd ..
- svn mkdir -m 'new glob at top level' $svnrepo/glob &&
- svn mv -m 'move blob down a level' $svnrepo/blob $svnrepo/glob/blob &&
- git-svn init --minimize-url -i blob $svnrepo/glob/blob &&
+ svn mkdir -m 'new glob at top level' '$svnrepo/glob' &&
+ svn mv -m 'move blob down a level' '$svnrepo/blob' '$svnrepo/glob/blob' &&
+ git-svn init --minimize-url -i blob '$svnrepo/glob/blob' &&
git-svn fetch -i blob
"
test_expect_success 'follow deleted directory' "
- svn mv -m 'bye!' $svnrepo/glob/blob/hi $svnrepo/glob/blob/bye &&
- svn rm -m 'remove glob' $svnrepo/glob &&
- git-svn init --minimize-url -i glob $svnrepo/glob &&
+ svn mv -m 'bye!' '$svnrepo/glob/blob/hi' '$svnrepo/glob/blob/bye' &&
+ svn rm -m 'remove glob' '$svnrepo/glob' &&
+ git-svn init --minimize-url -i glob '$svnrepo/glob' &&
git-svn fetch -i glob &&
test \"\`git cat-file blob refs/remotes/glob:blob/bye\`\" = hi &&
test \"\`git ls-tree refs/remotes/glob | wc -l \`\" -eq 1
@@ -118,9 +118,9 @@ test_expect_success 'follow-parent avoids deleting relevant info' "
echo 'bad delete test 2' > \
import/trunk/subversion/bindings/swig/perl/another-larger &&
cd import &&
- svn import -m 'r9270 test' . $svnrepo/r9270 &&
+ svn import -m 'r9270 test' . '$svnrepo/r9270' &&
cd .. &&
- svn co $svnrepo/r9270/trunk/subversion/bindings/swig/perl r9270 &&
+ svn co '$svnrepo/r9270/trunk/subversion/bindings/swig/perl' r9270 &&
cd r9270 &&
svn mkdir native &&
svn mv t native/t &&
@@ -130,7 +130,7 @@ test_expect_success 'follow-parent avoids deleting relevant info' "
svn commit -m 'reorg test' &&
cd .. &&
git-svn init --minimize-url -i r9270-t \
- $svnrepo/r9270/trunk/subversion/bindings/swig/perl/native/t &&
+ '$svnrepo/r9270/trunk/subversion/bindings/swig/perl/native/t' &&
git-svn fetch -i r9270-t &&
test \`git rev-list r9270-t | wc -l\` -eq 2 &&
test \"\`git ls-tree --name-only r9270-t~1\`\" = \
@@ -138,9 +138,9 @@ test_expect_success 'follow-parent avoids deleting relevant info' "
"
test_expect_success "track initial change if it was only made to parent" "
- svn cp -m 'wheee!' $svnrepo/r9270/trunk $svnrepo/r9270/drunk &&
+ svn cp -m 'wheee!' '$svnrepo/r9270/trunk' '$svnrepo/r9270/drunk' &&
git-svn init --minimize-url -i r9270-d \
- $svnrepo/r9270/drunk/subversion/bindings/swig/perl/native/t &&
+ '$svnrepo/r9270/drunk/subversion/bindings/swig/perl/native/t' &&
git-svn fetch -i r9270-d &&
test \`git rev-list r9270-d | wc -l\` -eq 3 &&
test \"\`git ls-tree --name-only r9270-t\`\" = \
@@ -150,7 +150,7 @@ test_expect_success "track initial change if it was only made to parent" "
"
test_expect_success "track multi-parent paths" "
- svn cp -m 'resurrect /glob' $svnrepo/r9270 $svnrepo/glob &&
+ svn cp -m 'resurrect /glob' '$svnrepo/r9270' '$svnrepo/glob' &&
git-svn multi-fetch &&
test \`git cat-file commit refs/remotes/glob | \
grep '^parent ' | wc -l\` -eq 2
@@ -161,8 +161,8 @@ test_expect_success "multi-fetch continues to work" "
"
test_expect_success "multi-fetch works off a 'clean' repository" "
- rm -r $GIT_DIR/svn $GIT_DIR/refs/remotes $GIT_DIR/logs &&
- mkdir $GIT_DIR/svn &&
+ rm -r '$GIT_DIR/svn' '$GIT_DIR/refs/remotes' '$GIT_DIR/logs' &&
+ mkdir '$GIT_DIR/svn' &&
git-svn multi-fetch
"
diff --git a/t/t9105-git-svn-commit-diff.sh b/t/t9105-git-svn-commit-diff.sh
index 318e172..2e1eb75 100755
--- a/t/t9105-git-svn-commit-diff.sh
+++ b/t/t9105-git-svn-commit-diff.sh
@@ -8,7 +8,7 @@ test_expect_success 'initialize repo' "
mkdir import &&
cd import &&
echo hello > readme &&
- svn import -m 'initial' . $svnrepo &&
+ svn import -m 'initial' . '$svnrepo' &&
cd .. &&
echo hello > readme &&
git update-index --add readme &&
@@ -27,16 +27,16 @@ prev=`git rev-parse --verify HEAD^1`
test_expect_success 'test the commit-diff command' "
test -n '$prev' && test -n '$head' &&
git-svn commit-diff -r1 '$prev' '$head' '$svnrepo' &&
- svn co $svnrepo wc &&
+ svn co '$svnrepo' wc &&
cmp readme wc/readme
"
test_expect_success 'commit-diff to a sub-directory (with git-svn config)' "
- svn import -m 'sub-directory' import $svnrepo/subdir &&
- git-svn init --minimize-url $svnrepo/subdir &&
+ svn import -m 'sub-directory' import '$svnrepo/subdir' &&
+ git-svn init --minimize-url '$svnrepo/subdir' &&
git-svn fetch &&
git-svn commit-diff -r3 '$prev' '$head' &&
- svn cat $svnrepo/subdir/readme > readme.2 &&
+ svn cat '$svnrepo/subdir/readme' > readme.2 &&
cmp readme readme.2
"
diff --git a/t/t9106-git-svn-commit-diff-clobber.sh b/t/t9106-git-svn-commit-diff-clobber.sh
index 79b7968..bb42339 100755
--- a/t/t9106-git-svn-commit-diff-clobber.sh
+++ b/t/t9106-git-svn-commit-diff-clobber.sh
@@ -8,14 +8,14 @@ test_expect_success 'initialize repo' "
mkdir import &&
cd import &&
echo initial > file &&
- svn import -m 'initial' . $svnrepo &&
+ svn import -m 'initial' . '$svnrepo' &&
cd .. &&
echo initial > file &&
git update-index --add file &&
git commit -a -m 'initial'
"
test_expect_success 'commit change from svn side' "
- svn co $svnrepo t.svn &&
+ svn co '$svnrepo' t.svn &&
cd t.svn &&
echo second line from svn >> file &&
poke file &&
@@ -27,7 +27,7 @@ test_expect_success 'commit change from svn side' "
test_expect_failure 'commit conflicting change from git' "
echo second line from git >> file &&
git commit -a -m 'second line from git' &&
- git-svn commit-diff -r1 HEAD~1 HEAD $svnrepo
+ git-svn commit-diff -r1 HEAD~1 HEAD '$svnrepo'
" || true
test_expect_success 'commit complementing change from git' "
@@ -36,14 +36,14 @@ test_expect_success 'commit complementing change from git' "
git commit -a -m 'second line from svn' &&
echo third line from git >> file &&
git commit -a -m 'third line from git' &&
- git-svn commit-diff -r2 HEAD~1 HEAD $svnrepo
+ git-svn commit-diff -r2 HEAD~1 HEAD '$svnrepo'
"
test_expect_failure 'dcommit fails to commit because of conflict' "
- git-svn init $svnrepo &&
+ git-svn init '$svnrepo' &&
git-svn fetch &&
git reset --hard refs/remotes/git-svn &&
- svn co $svnrepo t.svn &&
+ svn co '$svnrepo' t.svn &&
cd t.svn &&
echo fourth line from svn >> file &&
poke file &&
@@ -67,7 +67,7 @@ test_expect_success 'dcommit does the svn equivalent of an index merge' "
"
test_expect_success 'commit another change from svn side' "
- svn co $svnrepo t.svn &&
+ svn co '$svnrepo' t.svn &&
cd t.svn &&
echo third line from svn >> file &&
poke file &&
diff --git a/t/t9107-git-svn-migrate.sh b/t/t9107-git-svn-migrate.sh
index 67fdf70..90bf786 100755
--- a/t/t9107-git-svn-migrate.sh
+++ b/t/t9107-git-svn-migrate.sh
@@ -4,7 +4,7 @@ test_description='git-svn metadata migrations from previous versions'
. ./lib-git-svn.sh
test_expect_success 'setup old-looking metadata' "
- cp $GIT_DIR/config $GIT_DIR/config-old-git-svn &&
+ cp '$GIT_DIR/config' '$GIT_DIR/config-old-git-svn' &&
mkdir import &&
cd import &&
for i in trunk branches/a branches/b \
@@ -12,13 +12,13 @@ test_expect_success 'setup old-looking metadata' "
mkdir -p \$i && \
echo hello >> \$i/README || exit 1
done && \
- svn import -m test . $svnrepo
+ svn import -m test . '$svnrepo'
cd .. &&
- git-svn init $svnrepo &&
+ git-svn init '$svnrepo' &&
git-svn fetch &&
- mv $GIT_DIR/svn/* $GIT_DIR/ &&
- mv $GIT_DIR/svn/.metadata $GIT_DIR/ &&
- rmdir $GIT_DIR/svn &&
+ mv '$GIT_DIR'/svn/* '$GIT_DIR/' &&
+ mv '$GIT_DIR/svn/.metadata' '$GIT_DIR/' &&
+ rmdir '$GIT_DIR/svn' &&
git update-ref refs/heads/git-svn-HEAD refs/remotes/git-svn &&
git update-ref refs/heads/svn-HEAD refs/remotes/git-svn &&
git update-ref -d refs/remotes/git-svn refs/remotes/git-svn
@@ -28,20 +28,20 @@ head=`git rev-parse --verify refs/heads/git-svn-HEAD^0`
test_expect_success 'git-svn-HEAD is a real HEAD' "test -n '$head'"
test_expect_success 'initialize old-style (v0) git-svn layout' "
- mkdir -p $GIT_DIR/git-svn/info $GIT_DIR/svn/info &&
- echo $svnrepo > $GIT_DIR/git-svn/info/url &&
- echo $svnrepo > $GIT_DIR/svn/info/url &&
+ mkdir -p '$GIT_DIR/git-svn/info' '$GIT_DIR/svn/info' &&
+ echo '$svnrepo' > '$GIT_DIR/git-svn/info/url' &&
+ echo '$svnrepo' > '$GIT_DIR/svn/info/url' &&
git-svn migrate &&
- ! test -d $GIT_DIR/git-svn &&
+ ! test -d '$GIT_DIR/git-svn' &&
git rev-parse --verify refs/remotes/git-svn^0 &&
git rev-parse --verify refs/remotes/svn^0 &&
- test \`git config --get svn-remote.svn.url\` = '$svnrepo' &&
+ test \"\`git config --get svn-remote.svn.url\`\" = \"$svnrepo\" &&
test \`git config --get svn-remote.svn.fetch\` = \
':refs/remotes/git-svn'
"
test_expect_success 'initialize a multi-repository repo' "
- git-svn init $svnrepo -T trunk -t tags -b branches &&
+ git-svn init '$svnrepo' -T trunk -t tags -b branches &&
git config --get-all svn-remote.svn.fetch > fetch.out &&
grep '^trunk:refs/remotes/trunk$' fetch.out &&
test -n \"\`git config --get svn-remote.svn.branches \
@@ -76,14 +76,14 @@ test_expect_success 'multi-fetch works on partial urls + paths' "
test_expect_success 'migrate --minimize on old inited layout' "
git config --unset-all svn-remote.svn.fetch &&
git config --unset-all svn-remote.svn.url &&
- rm -rf $GIT_DIR/svn &&
+ rm -rf '$GIT_DIR/svn' &&
for i in \`cat fetch.out\`; do
path=\`expr \$i : '\\([^:]*\\):.*$'\`
ref=\`expr \$i : '[^:]*:refs/remotes/\\(.*\\)$'\`
if test -z \"\$ref\"; then continue; fi
if test -n \"\$path\"; then path=\"/\$path\"; fi
- ( mkdir -p $GIT_DIR/svn/\$ref/info/ &&
- echo $svnrepo\$path > $GIT_DIR/svn/\$ref/info/url ) || exit 1;
+ ( mkdir -p '$GIT_DIR'/svn/\$ref/info/ &&
+ echo '$svnrepo'\$path > '$GIT_DIR'/svn/\$ref/info/url ) || exit 1;
done &&
git-svn migrate --minimize &&
test -z \"\`git config -l |grep -v '^svn-remote\.git-svn\.'\`\" &&
@@ -99,13 +99,13 @@ test_expect_success 'migrate --minimize on old inited layout' "
test_expect_success ".rev_db auto-converted to .rev_db.UUID" "
git-svn fetch -i trunk &&
- expect=$GIT_DIR/svn/trunk/.rev_db.* &&
+ expect=\"\`find \"\$GIT_DIR\"/svn/trunk/ -name '.rev_db.*'\`\" &&
test -n \"\$expect\" &&
- mv \$expect $GIT_DIR/svn/trunk/.rev_db &&
+ mv \"\$expect\" \"\$GIT_DIR\"/svn/trunk/.rev_db &&
git-svn fetch -i trunk &&
- test -L $GIT_DIR/svn/trunk/.rev_db &&
- test -f \$expect &&
- cmp \$expect $GIT_DIR/svn/trunk/.rev_db
+ test -L \"\$GIT_DIR\"/svn/trunk/.rev_db &&
+ test -f \"\$expect\" &&
+ cmp \"\$expect\" \"\$GIT_DIR\"/svn/trunk/.rev_db
"
test_done
diff --git a/t/t9108-git-svn-glob.sh b/t/t9108-git-svn-glob.sh
index db4344c..c6dc0ef 100755
--- a/t/t9108-git-svn-glob.sh
+++ b/t/t9108-git-svn-glob.sh
@@ -14,8 +14,8 @@ test_expect_success 'test refspec globbing' "
mkdir -p trunk/src/a trunk/src/b trunk/doc &&
echo 'hello world' > trunk/src/a/readme &&
echo 'goodbye world' > trunk/src/b/readme &&
- svn import -m 'initial' trunk $svnrepo/trunk &&
- svn co $svnrepo tmp &&
+ svn import -m 'initial' trunk '$svnrepo/trunk' &&
+ svn co '$svnrepo' tmp &&
cd tmp &&
mkdir branches tags &&
svn add branches tags &&
@@ -38,7 +38,7 @@ test_expect_success 'test refspec globbing' "
poke tags/end/src/b/readme &&
svn commit -m 'nothing to see here'
cd .. &&
- git config --add svn-remote.svn.url $svnrepo &&
+ git config --add svn-remote.svn.url '$svnrepo' &&
git config --add svn-remote.svn.fetch \
'trunk/src/a:refs/remotes/trunk' &&
git config --add svn-remote.svn.branches \
@@ -60,7 +60,7 @@ echo nothing to see here >> expect.two
cat expect.end >> expect.two
test_expect_success 'test left-hand-side only globbing' "
- git config --add svn-remote.two.url $svnrepo &&
+ git config --add svn-remote.two.url '$svnrepo' &&
git config --add svn-remote.two.fetch trunk:refs/remotes/two/trunk &&
git config --add svn-remote.two.branches \
'branches/*:refs/remotes/two/branches/*' &&
diff --git a/t/t9110-git-svn-use-svm-props.sh b/t/t9110-git-svn-use-svm-props.sh
index 6235af4..d4ab01f 100755
--- a/t/t9110-git-svn-use-svm-props.sh
+++ b/t/t9110-git-svn-use-svm-props.sh
@@ -8,11 +8,11 @@ test_description='git-svn useSvmProps test'
. ./lib-git-svn.sh
test_expect_success 'load svm repo' "
- svnadmin load -q $rawsvnrepo < ../t9110/svm.dump &&
- git-svn init --minimize-url -R arr -i bar $svnrepo/mirror/arr &&
- git-svn init --minimize-url -R argh -i dir $svnrepo/mirror/argh &&
+ svnadmin load -q '$rawsvnrepo' < ../t9110/svm.dump &&
+ git-svn init --minimize-url -R arr -i bar '$svnrepo/mirror/arr' &&
+ git-svn init --minimize-url -R argh -i dir '$svnrepo/mirror/argh' &&
git-svn init --minimize-url -R argh -i e \
- $svnrepo/mirror/argh/a/b/c/d/e &&
+ '$svnrepo/mirror/argh/a/b/c/d/e' &&
git config svn.useSvmProps true &&
git-svn fetch --all
"
diff --git a/t/t9111-git-svn-use-svnsync-props.sh b/t/t9111-git-svn-use-svnsync-props.sh
index ec7dedd..936f023 100755
--- a/t/t9111-git-svn-use-svnsync-props.sh
+++ b/t/t9111-git-svn-use-svnsync-props.sh
@@ -8,10 +8,10 @@ test_description='git-svn useSvnsyncProps test'
. ./lib-git-svn.sh
test_expect_success 'load svnsync repo' "
- svnadmin load -q $rawsvnrepo < ../t9111/svnsync.dump &&
- git-svn init --minimize-url -R arr -i bar $svnrepo/bar &&
- git-svn init --minimize-url -R argh -i dir $svnrepo/dir &&
- git-svn init --minimize-url -R argh -i e $svnrepo/dir/a/b/c/d/e &&
+ svnadmin load -q '$rawsvnrepo' < ../t9111/svnsync.dump &&
+ git-svn init --minimize-url -R arr -i bar '$svnrepo/bar' &&
+ git-svn init --minimize-url -R argh -i dir '$svnrepo/dir' &&
+ git-svn init --minimize-url -R argh -i e '$svnrepo/dir/a/b/c/d/e' &&
git config svn.useSvnsyncProps true &&
git-svn fetch --all
"
diff --git a/t/t9112-git-svn-md5less-file.sh b/t/t9112-git-svn-md5less-file.sh
index 08313bb..b095583 100755
--- a/t/t9112-git-svn-md5less-file.sh
+++ b/t/t9112-git-svn-md5less-file.sh
@@ -38,8 +38,8 @@ PROPS-END
EOF
-test_expect_success 'load svn dumpfile' "svnadmin load $rawsvnrepo < dumpfile.svn"
+test_expect_success 'load svn dumpfile' "svnadmin load '$rawsvnrepo' < dumpfile.svn"
-test_expect_success 'initialize git-svn' "git-svn init $svnrepo"
+test_expect_success 'initialize git-svn' "git-svn init '$svnrepo'"
test_expect_success 'fetch revisions from svn' 'git-svn fetch'
test_done
diff --git a/t/t9113-git-svn-dcommit-new-file.sh b/t/t9113-git-svn-dcommit-new-file.sh
index 9ef0db9..0088c75 100755
--- a/t/t9113-git-svn-dcommit-new-file.sh
+++ b/t/t9113-git-svn-dcommit-new-file.sh
@@ -15,14 +15,14 @@ test_description='git-svn dcommit new files over svn:// test'
start_svnserve () {
svnserve --listen-port $SVNSERVE_PORT \
- --root $rawsvnrepo \
+ --root '$rawsvnrepo' \
--listen-once \
--listen-host 127.0.0.1 &
}
test_expect_success 'start tracking an empty repo' "
- svn mkdir -m 'empty dir' $svnrepo/empty-dir &&
- echo anon-access = write >> $rawsvnrepo/conf/svnserve.conf &&
+ svn mkdir -m 'empty dir' '$svnrepo/empty-dir' &&
+ echo anon-access = write >> '$rawsvnrepo/conf/svnserve.conf' &&
start_svnserve &&
git svn init svn://127.0.0.1:$SVNSERVE_PORT &&
git svn fetch
diff --git a/t/t9114-git-svn-dcommit-merge.sh b/t/t9114-git-svn-dcommit-merge.sh
index d6ca955..64ec7fd 100755
--- a/t/t9114-git-svn-dcommit-merge.sh
+++ b/t/t9114-git-svn-dcommit-merge.sh
@@ -35,7 +35,7 @@ EOF
}
test_expect_success 'setup svn repository' "
- svn co $svnrepo mysvnwork &&
+ svn co '$svnrepo' mysvnwork &&
mkdir -p mysvnwork/trunk &&
cd mysvnwork &&
big_text_block >> trunk/README &&
@@ -45,7 +45,7 @@ test_expect_success 'setup svn repository' "
"
test_expect_success 'setup git mirror and merge' "
- git svn init $svnrepo -t tags -T trunk -b branches &&
+ git svn init '$svnrepo' -t tags -T trunk -b branches &&
git svn fetch &&
git checkout --track -b svn remotes/trunk &&
git checkout -b merge &&
diff --git a/t/t9115-git-svn-dcommit-funky-renames.sh b/t/t9115-git-svn-dcommit-funky-renames.sh
index 182299c..653578d 100755
--- a/t/t9115-git-svn-dcommit-funky-renames.sh
+++ b/t/t9115-git-svn-dcommit-funky-renames.sh
@@ -8,12 +8,12 @@ test_description='git-svn dcommit can commit renames of files with ugly names'
. ./lib-git-svn.sh
test_expect_success 'load repository with strange names' "
- svnadmin load -q $rawsvnrepo < ../t9115/funky-names.dump &&
+ svnadmin load -q '$rawsvnrepo' < ../t9115/funky-names.dump &&
start_httpd
"
test_expect_success 'init and fetch repository' "
- git svn init $svnrepo &&
+ git svn init '$svnrepo' &&
git svn fetch &&
git reset --hard git-svn
"
diff --git a/t/t9116-git-svn-log.sh b/t/t9116-git-svn-log.sh
index 0d4e6b3..70c0c5f 100755
--- a/t/t9116-git-svn-log.sh
+++ b/t/t9116-git-svn-log.sh
@@ -14,9 +14,9 @@ test_expect_success 'setup repository and import' "
mkdir -p \$i && \
echo hello >> \$i/README || exit 1
done && \
- svn import -m test . $svnrepo
+ svn import -m test . '$svnrepo'
cd .. &&
- git-svn init $svnrepo -T trunk -b branches -t tags &&
+ git-svn init '$svnrepo' -T trunk -b branches -t tags &&
git-svn fetch &&
git reset --hard trunk &&
echo bye >> README &&
diff --git a/t/test-lib.sh b/t/test-lib.sh
index cc1253c..a68415f 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -229,7 +229,7 @@ test_create_repo () {
repo="$1"
mkdir "$repo"
cd "$repo" || error "Cannot setup test environment"
- "$GIT_EXEC_PATH/git" init --template=$GIT_EXEC_PATH/templates/blt/ >/dev/null 2>&1 ||
+ "$GIT_EXEC_PATH/git" init --template="$GIT_EXEC_PATH/templates/blt/" >/dev/null 2>&1 ||
error "cannot run git init -- have you built things yet?"
mv .git/hooks .git/hooks-disabled
cd "$owd"
--
1.5.3.1
^ permalink raw reply related [relevance 11%]
* Git User's Survey 2007 summary - comparison with previous survey
@ 2007-10-12 22:07 1% Jakub Narebski
0 siblings, 0 replies; 200+ results
From: Jakub Narebski @ 2007-10-12 22:07 UTC (permalink / raw)
To: git
It's been more than a year since last Git User's Survey. It would be
interesting to find what changed since then. Therefore the idea to
have another survey.
This is partial comparison of Git User's Survey 2007,
(ending at state from 28 September 2007) with previous
survey.
The current survey can be found here:
http://www.survey.net.nz/survey.php?94e135ff41e871a1ea5bcda3ee1856d9
http://tinyurl.com/26774s
The data for current, 2007 survey can be found here:
The data for previous, 2006 survey was taken from following wiki page
http://git.or.cz/gitwiki/GitSurvey2006
---
There were 683 individual responses in 2007 survey.
There were around 117 responses in 2006 survey.
There are 62 questions in 2007 survey, and 31 questions (half of
the number) in 2006 survey.
About you
~~~~~~~~~
01. What country are you in?
Answer | Old | Count
------------------------------------------------
Algeria | | 1
Argentina | | 3
Australia | 3 | 25
Austria | 2 | 9
Belarus | 1 |
Belgium | | 5
Brazil | 2 | 20
Bulgaria | | 1
Canada | 3 | 44
Chile | 1 | 2
China | 2 | 4
Colombia | | 2
Czech Republic | 2 | 10
Denmark | 4 | 7
Ecuador | | 1
Estonia | 1 | 1
Europe | 1 | 1
Finland | 5 | 23
France | 6 | 36
Germany | 14 | 64
Greece | | 3
Hungary | | 2
India | 1 | 13
Ireland | | 2
Israel | | 6
Italy | 3 | 14
Japan | | 4
Jersey | | 1
Latvia | | 1
Lithuania | 1 |
Malaysia | | 1
Mexico | | 1
Netherlands | 3 | 15
New Zealand | | 5
Norway | 1 | 14
Philippines | 1 | 3
Poland | 3 | 6
Portugal | | 2
Puerto Rico | | 1
Romania | | 1
Russian Federation | 2 | 6
Samoa | | 1
Serbia | | 1
Singapore | | 2
Slovak Republic | | 1
Slovenia | | 2
South Africa | 1 | 4
Spain | 2 | 11
Sri Lanka | | 1
Sweden | 6 | 14
Switzerland | 1 | 15
UAE | 1 |
UK / US | | 1
United Kingdom | 8 | 40
United States of America | 35 | 218
Venezuela | | 1
Vietnam | 1 | 1
------------------------------------------------
Base | | 673 / 683
Total (sum) | 117 | 673
England, Scotland and British Isles counts as United Kingdom here.
Table is sorted in alphabetical order.
As before most Git users are in the USA.
There are quite a bit of new countries, only two vanished. Note that
current survey has much more responses, so it is expected.
02. What is your preferred non-programming language?
This is multiple answers question, although most people
gave only one preferred language.
Answer | Old | Count
------------------------------------------------
Afrikaans | | 1
Belarusian | 1 |
Bulgarian | | 1
Castellano | | 2
Catalan | | 1
Chinese | 1 | 2
Czech | 2 | 10
Danish | 5 | 6
Dutch | 4 | 12
English | 71 | 416
Estonian | 1 |
Finnish | 4 | 16
French | 5 | 33
Galician | | 1
German | 12 | 58
Greek | | 2
Hebrew | | 1
HibernoEnglish | | 1
Hungarian | | 3
Italian | 3 | 9
Japanese | 1 | 1
LSF (French sign language) | | 1
Norwegian | | 4
Polish | 3 | 5
Portuguese | | 10
Romanian | | 1
Russian | 4 | 13
Serbian | | 1
Slovenian | | 2
Spanish | 4 | 13
Swedish | 5 | 13
Swiss | | 1
Ukrainian | | 1
Vietnamese | 1 | 1
invalid (computer language) | ? | 37
not understood | ? | 4
------------------------------------------------
Base | | 662 / 683
Total (sum) | 127 | 683
Most of git users prefer English language, at least for dealing with
computers, the same as before.
In previous survey summary the invalid responses were not enumerated.
The question itself is not well formulated, as one can see from the
number of answers with computer language, and "not understood"
answers. I am not native English speaker, but there were suggestions
to use "natural language" instead of "non-programming language". The
question is formulated the same as in previous survey.
03. How old are you?
04. Which programming languages you are proficient with?
Those are new questions, which were not present in previous survey.
Getting started with GIT
~~~~~~~~~~~~~~~~~~~~~~~~
05. How did you hear about GIT?
This question is present in both current (2007) and previous (2006)
survey. But because it uses free-form answer, and tabularization
(dividing data in categories and generating histogram / counting
occurences) is quite different it is not easy to compare results.
In Git User's Survey 2006 (prevuius survey) the dominant source was
LKML (Linux Kernel Mailing List) with 74 / 115 responses, with LWN
leading the rest with 11 / 115 count.
Although LKML still dominates the table for current survey, it is not
by such a wide margin (109/658 = 17% as compared to 74/115 = 64% in
previous one). Many people heard about git because Linux kernel uses
it; Linus Torvalds presentation (talk) at Google (Google Video and
YouTube) got also high count, bit higher than LWN.
But there was no "I wrote it" response in current survey, though...
06. Did you find GIT easy to learn?
Answer | Old | Count
------------------------------------------------
very easy | 6 | 38
easy | 21 | 136
reasonably | 64 | 318
hard | 23 | 131
very hard | 3 | 33
------------------------------------------------
Base | | 656 / 683
Total (sum) | 117 | 656
Nice gaussian curve both for current survey, and previous year survey
data. Most users find GIT reasonably easy to use.
07. What helped you most in learning to use it?
TO DO. This again is a free-form question, present in both surveys.
For current (2007) survey data is not even tabularized yet, although
(some) of responses got listed (without a count). I don't think
comparison with previous result is any interesting, but previous year
data can provide at least some hint on how to divide answers into
categories.
08. What did you find hardest?
TO DO. Yet another free-form question, present in both surveys.
Tabularized for 2006 survey, listed without count for 2007 survey, as
for previous question.
09. When did you start using git? From which version?
TO DO. Again free-form question. Note that in previous survey this
question consisted only of the first part, and read "When did you
start using git?", so it is date that got tabularized, not git version
(mostly). Analysis of current survey data is unfinished, and only
answers in which there was given git version explicitely got
tabularized. For comparison we would need analysis of answers giving
date; and even then I don't think it would be especially useful,
unless very coarse-grained (which year for example).
Other SCMs
~~~~~~~~~~
10. What other SCMs did/do you use?
11. Why did you choose GIT?
12. Why did you choose other SCMs?
13. What would you require from GIT to enable you to change,
if you use other SCM for your project?
14. Did you import your repository from foreign SCM? What SCM?
15. What tool did you use for import?
16. Do your GIT repository interact with other SCM? Which SCM?
17. What tool did/do you use to interact?
This whole section is new, and was not present in previous survey.
How you use GIT
~~~~~~~~~~~~~~~
18. Do you use GIT for work, unpaid projects, or both?
This question had slightly different wording in 2006 survey:
"How you use GIT? Do you use GIT for ...".
Answer / Purpose | Old | Count
------------------------------------------------
work | 14 | 56
unpaid projects | 50 | 212
both | 53 | 377
------------------------------------------------
Base | | 645 / 683
Total (sum) | 117 | 645
In the previous survey unpaid projects (only unpaid) were slightly
less than half of answers (43 %), while current survey shows that
[only] around a third of git users use it only for unpaid projects.
So we see more git used for work.
19. How do you obtain GIT?
Answer | Old | Count
------------------------------------------------
binary package | 31 | 283
source tarball | 33 | 210
pull from main repository | 53 | 153
------------------------------------------------
Base | | 646 / 683
Total (sum) | 117 | 646
As one can see a year ago pull from main repository dominated, while
now binary package dominates, and pull is least used. At least among
people who answered Git User's Survey; the difference might be caused
by the fact that previous survey was distributed mainly among readers
of git mailing list, who run latest 'master' or even 'next' version,
and often contribute to git (see also question 30, "Does git.git
repository include code produced by you?").
On the other hand the difference might be caused by the fact that more
distributions have got git, or that git is more mature and there is no
need to run development version and/or the fact that x.y.z is now
development version following 'master' and not 'maint', and includes
new features.
20. What hardware platforms do you use GIT on?
This is free-form question, tabularized for both current and previous
survey, but tabularized (slightly) differently. It is not suprising,
as extracting architecture and dividing into categories was doneby two
different people: Paolo Ciarrocchi (if I remember correctly) for 2006
survey, and Jakub Narebski (me) for 2007.
Moreover I guess that the _comparison_ is not very interesting; the
current data is.
Hardware platfrom tables should relly be generated by someone better
versed in computer architecture.
21. What OS (please include the version) do you use GIT on?
This question is also free-form. For 2006 survey there is generic
count, and two tables: for Linux (distribution or kernel), and for
other operating systems. The table for 2007 survey is slightly less
generic than the 2006 count, but there are no OS version tables.
There is much more data, and more data without version number.
Perhaps we should have provided examples of answers to this
question...
Answer | Old | Count
---------------------------------------------
AIX | 1 | 1
FreeBSD | 4 | 16
OpenBSD | - | 3
NetBSD | 1 | -
HP-UX | 1 | 1
IRIX | 1 | -
Linux | 167? | 582
MS Windows (Cygwin) | 14 | 22
MS Windows (other) | | 36
MacOS X / Darwin | 11 | 94
Solaris | 3 | 11
SunOS | - | 5
---------------------------------------------
Note that one person can use git on more than one operating system.
The number for Linux from 2006 survey is taken as total for Linux
table. "MS Windows (other)" means msys (native) version, or
unspecified whether Cygwin or MinGW/MSys. If I remember correctly
there were no native Windows version (which is currently under
development) during previous survey.
Most is Linux, as before. MacOS X is quite a percentage in current
survey, and dominates among non-Linux OS, coming before MS Windows.
22. What projects do you track (or download) using GIT
(or git web interface)?
This question was not present in previous survey.
23. How many people do you collaborate with using GIT?
TO DO. This is free-form question; analysis for current survey is not
done yet. The answer is not always simple number, but even those
answers which are limited to simple number (or contain simple number)
are not done yet.
I have posted question if first post in the thread about what ranges
(what categories) should be used here. I haven't received any answer
yet.
Previous survey have table in two parts: first histogram of simple
number of people, second with names of communities (Cairo, Linux
kernel, U-Boot,...).
24. How big are the repositories that you work on?
TO DO. To be done *both* for 2007 (current) survey, and for 2006 one.
25. How many different projects do you manage using GIT?
This question was not present in previous survey.
Previous survey has empty question in this place, between those
questions.
26. Which porcelains do you use?
27. Which git GUI do you use?
28. Which (main) git web interface do you use for your projects?
The list of porcelains is different for previous and current
survey. Git GUIs were moved to the next question in the 2007 survey,
and web interfaces to second next.
Note that there is some ambiguity concerning git-gui: it was put in
current survey in the GUI question only, while some people consider it
[also] porcelain (and put is as 'other' in porcelain).
Multiple answers (one can use more than one porcelain).
Answer (multiple choice) | Old | Count
----------------------------------------------
core-git | 62 | 558
cogito | 22 | 56
Patch management interface: : 13 : 57
..............................................
StGIT | 11 | 41
Guilt (formerly gq) | n/a | 13
pg (deprecated) | 2 | 3
----------------------------------------------
One has to take into account the fact that neither Cogito nor pg
(Patchy GIT) were deprecated during previous survey. Cogito got
deprecated because all of its functionality got moved in some way to
core git, while Petr 'Pasky' Baudis, main Cogito developer, didn't
have time for catching up to new git features.
Guilt is so new that it just simply was not yet created during
previous survey.
29. How do you publish/propagate your changes?
This question was not present in previous survey.
30. Does git.git repository include code produced by you?
(Previous survey had bad English here: "Is the git.git repository
including codes produced by you?")
Answer | Old | Count
------------------------------------------------
Yes | 73 | 99
No | 34 | 512
------------------------------------------------
Base | | 611 / 683
Total (sum) | 107 | 611
Complete reversion: from most survey participants having their
code in git.git (around 70%) a year ago to around a small amount
(around 16%) currently (!).
This might be cause by the fact that (I think) previous survey was
known mostly to people reading git mailing list, who often send their
own patches to this list. Therefore there it would be nice to have
"How did you heard about this survey?" question. (It would also help
finding where it is worth to send notice if/when we would want to make
another survey.)
Note also the following little fact:
$ git shortlog -s --all --before="01-08-2006" | wc -l
119 (and around 117 individual responses in 2006 survey)
$ git shortlog -s --all --before="01-10-2007" | wc -l
215 (and 683 individual responses in 2007 survey)
So it is simply not possible to have the same percentage of git
developers among git users (or rather git survey participants): 70%
out of 683 users is more than 465, which is more than git.git has
developers.
Internationalization
~~~~~~~~~~~~~~~~~~~~
31. Is translating GIT required for wider adoption?
32. What do you need translated?
33. For what language do you need translation for?
This whole section is new, and was not present in previous survey.
What you think of GIT
~~~~~~~~~~~~~~~~~~~~~
34. Overall, how happy are you with GIT?
Answer | Old | Count
------------------------------------------------
unhappy | 1 | 13
not so happy | 19 | 36
happy | 53 | 179
very happy | 41 | 302
completely ecstatic | 1 | 112
------------------------------------------------
Base | | 642 / 683
Total (sum) | 115 | 642
During the year the balance shifted slightly in the positive
direction: from mostly happy to very happy, to mostly very happy
leaning to happy. And we have much more percentage of completely
ecstatic.
Good work!
35. How does GIT compare to other SCM tools you have used?
Answer | Old | Count
------------------------------------------------
Better | 80 | 505
Equal (comparable) | 20 | 96
Worse | 8 | 30
------------------------------------------------
Base | | 631 / 683
Total (sum) | 108 | 631
Here not much changed. The shape of this histogram is almost the same,
with slight shift towards "better than other SCMs used".
Note that 2006 survey has "Equal (or uncomparable)" instead of
"Equal (comparable)" as it is now.
36. What do you like about using GIT?
TO DO. Yet another free-form question. Tabularized for 2006 survey,
most encountered answers listed without count for 2007 survey.
37. What would you most like to see improved about GIT?
(features, bugs, plug-ins, documentation, ...)
TO DO. As above: tabularized somewhat for previous survey, with the
list of ideas (divided broadly into categories) below the table; with
some ideas dropped. For current survey there is only list of most
commonly encountered, and most interesting ideas.
Some of the 2006 ideas got implemented, or are being implemented, like
better documentation (Git User's Manual, documenting options), shallow
clones, win32 native binaries (via MinGS, in development), subproject
support (plumbing and beginnings of porcelain), libification and
builtinification (GSoC projects), increased verbosity when needed and
making error messages more helpful, graphical merges (git-mergetool:
interface to file-level graphical mergers like Meld, KDiff3 etc.), per
user configuration (~/.gitconfig rather that ~/.gitrc, and there is
even system wide configuration). Some of ideas are repeated (like
"The Git Book" idea, although "Git User's Manual" fills it somewhat),
some ideas provided too hard (e.g. lazy clone aka remote alternates)
or without someone to implement them. Some got abandoned, some will
probably never get implemented.
Even some suggestions in 2007 survey are actually implemented already,
for example git development Changelog (present in the form of
RelNotes), shallow clone support, submodules support. This means that
new features are not very well announced (which was also one of
comments in current survey).
38. If you want to see GIT more widely used, what do you think
we could do to make this happen?
TO DO. List of suggestions for 2006 survey; for current 2007 survey
only two most striking.
Changes in GIT (since year ago, or since you started using it)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
39. Did you participate in previous Git User's Survey?
40. What improvements you wanted got implemented?
41. What improvements you wanted didn't get implemented?
42. How do you compare current version with version from year ago?
43. Which of the new features do you use?
This whole section is of course new (Git User's Survey 2006 was first
git survey ever; git is not very much older than that), and was not
present in previous survey.
Documentation
~~~~~~~~~~~~~
44. Do you use the GIT wiki?
45. Do you find GIT wiki useful?
Previous survey has two questions in one here: "Do you use the GIT
wiki? If yes, do you find it useful?". This made it hard to
distinguish if "no" means "no I don't use GIT wiki" or "no it is not
useful".
This was one of the improvements over previous version of survey.
46. Do you contribute to GIT wiki?
This question was not present in previous survey.
47. Do you find GIT's on-line help (homepage, documentation) useful?
In 2007 survey there is additional "somewhat useful" answer, which was
not present in the 2006 survey.
Answer | Old | Count
--------------------------------------------
Yes | 88 | 377
No | 20 | 28
Somewhat | - | 172
------------------------------------------
Base | | 577 / 683
Total (sum) | 108 | 577
The results are similar: most users find online help useful.
47b. What is your favourite user documentation for any software
projects or products you have used?
This question is present in 2006 survey, and was removed in current
one. The idea behind question was I guess to have the results in hand
if git ever was to change documentation format. Most likely current
format of documentation (AsciiDoc), or at least idea behind it
(it should be possible to read sources, editing sources without
specialized editor support should be easy even for people who don't
know the format) is here to stay.
48. Do you find help distributed with GIT useful
(manpages, manual, tutorial, HOWTO, release notes)?
49. Did/Do you contribute to GIT documentation?
Those questions were not present in previous survey.
50. What could be improved on the GIT homepage?
TO DO. List of suggestions for 2006 survey, nothing yet for 2007
survey.
51. What topics would you like to have on GIT wiki?
52. What could be improved in GIT documentation?
Those questions were not present in previous survey.
Getting help, staying in touch
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
53. Have you tried to get GIT help from other people?
Answer | Old | Count
------------------------------------------------
Yes | 68 | 357
No | 45 | 261
------------------------------------------------
Base | | 618 / 683
Total (sum) | 113 | 618
Around 60% of people tried to get GIT help from other people,
for both current (2007) and previous (2006) survey.
54. If yes, did you get these problems resolved quickly
and to your liking?
Answer | Old | Count
--------------------------------------------
Yes | 68 | 326
No | 45 | 53
------------------------------------------
Base | | 379 / 683
Total (sum) | 113 | 379
The precentage was a bit worse during earlier survey (around 60%) than
for corrent one (around 86%).
This might be caused by the fact that git is now more userfriendly,
and has more features, and problems are easier to resolve.
55. Would commerical (paid) support from a support vendor
be of interest to you/your organization?
This question was not present in previous survey. It was requested
during an RFC for this year (2007) survey.
56. Do you read the mailing list?
Answer | Old | Count
------------------------------------------------
Yes | 67 | 204
No | 50 | 406
------------------------------------------------
Base | | 610 / 683
Total (sum) | 117 | 610
Note that 2006 version had "subscribe" instead of "read" in this
question. Even despite that the number of people reading git mailing
list decreased from more than half (around 57%) to around third
(around 33%). This might be caused by the fact that notice / info
about Git User's Survey 2006 was distributed mainly among git mailing
list and among mailing lists for projects which use git (see also
commets to questions 19 and 30).
The fact that only one third of git users are reading mailing list
(which is nevertheless quite large percentage) means that features
_have_ to be documented somewhere besides mailing list archive and
logs (commit messages).
57. If yes, do you find the mailing list useful?
58. Do you find traffic levels on GIT mailing list OK?
Previous survey has two questions in one here: "If yes, do you find it
useful, and traffic levels OK?". They were split in current survey.
59. Do you use the IRC channel (#git on irc.freenode.net)?
Answer | Old | Count
------------------------------------------------
Yes | 23 | 182
No | 93 | 376
------------------------------------------------
Base | | 558 / 683
Total (sum) | 116 | 558
More people use #git channel now (33% as compared to 20% before).
Nevertheless relatively few people use this form of comminication and
getting help.
60. If yes, do you find IRC channel useful?
This question was not present in previous survey. It nicely follows in
the series of questions about git wiki and git mailing list (do you
use? is it useful?).
61. Did you have problems getting GIT help on mailing list
or on IRC channel? What were it? What could be improved?
This question was not present in previous survey.
Open forum
~~~~~~~~~~
62. What other comments or suggestions do you have
that are not covered by the questions above?
TO DO. There is list of responses for 2006 survey; the 141 responses
in current (2007) survey are not yet analysed.
--
Jakub Narebski
(currently away from net)
^ permalink raw reply [relevance 1%]
* Git User's Survey 2007 unfinished summary continued
@ 2007-10-12 22:08 2% ` Jakub Narebski
0 siblings, 0 replies; 200+ results
From: Jakub Narebski @ 2007-10-12 22:08 UTC (permalink / raw)
To: git
This is continuation of partial summary of Git User's Survey 2007,
ending at state from 28 September 2007.
(response ident "46f95167c967b").
The survey can be found here:
http://www.survey.net.nz/survey.php?94e135ff41e871a1ea5bcda3ee1856d9
http://tinyurl.com/26774s
The data this summary is base on can be found here:
----
There were 683 individual responses
Other SCMs
~~~~~~~~~~
13. What would you require from GIT to enable you to change,
if you use other SCM for your project?
TO DO
474 / 683 non-empty responses
List of answers, without count (which for this question is, I think,
less important), divided into broad categories, is shown below
Generic
* being more user-friendly, easier to use
more friendly output from commands
better and clearer error messages
stable command semantics
* reduced number of (visible) commands
clear separation of plumbing and porcelain
* consistent set of commands
consistency if command flags
* easier to learn (easier learning curve)
* more stability
* support UTF-16
* A clearer UI. Read the monotone list archive. 70% of the mails are
UI related. The result is an clear and easy to use intuitive UI
that does what you expect in most cases.
Performance
* better performance on massive trees (FreeBSD)
* good speed on NTFS (MS WIndows)
Documentation
* a good documentation
user/installation documentation
troubleshooting guide
'Git For Dummies', 'The Git Book'
* documented workflows (including centralized repo workflow, or at
least documenting how and why replace it with better workflow)
* development model tutorials
more example usage
best practices
case studies
* guide for designing a branch policy for a shared repository
* screencasts
* documentation in one's native language
* good in-depth administative documentation
* maybe git-tutor program
Specific features
* partial-tree checkouts (partial checkout)
checking out arbitrary subdirectories
* granular permissions (ACL) within the tree
e.g. restricting translators to the po/ subdirectory
* shallow clone from a given commit: git clone --depth <commit>
* automatic (re)packing
* lightweight working copies
* better and well documented submodule support
* multi-project support / multiple sandboxes support
* git-bind/unbind (like in bzr)
* git-sync
* cvs-compatible syntax as an option
* tracking empty directories
* more friendliness with corporate firewalls
* ability to preserve permissions/modes/EA of files and directories
access control features / visibility access control
disabling some users from accessing certain parts of the repository
* being able to merge directories (instead of branches)
* FastCGI gitweb
* some embedded keyword capabilities similar to those provided by CVS
and Subversion
* ignore files during merge
* R/W git server (allow push), with NIS, LDAP support
* pull/rebase into dirty tree
* clearcase dynamic view-like support (externally?)
* better http(s) push via WebDAV: hooks
working and easy to setup push over https
* plain simple FTP upload (push) and download (clone, fetch)
* better working through corporate firewalls
Portability
* native MS Windows support, easy installer package
even better support for all platforms
easier setup on Solaris and AIX
* pre-prepared _static_ binaries for FreeBSD, MacOS X, MS Windows
* less dependencies
* support for more platforms
* a portable version of git, one binary + library (gitbox)
* Windows version(s) mentioned on homepage
GUI
* better (G)UI
TortoiseGit for MS Windows, or other Windows front-end
good, advanced GTK+ 2.x tool to visualize git
* history graph conected to file tree in GUIs
* easier management of remotes using GUI
* better diff viewing tools (side-by-side, like KDiff3)
Other SCMs
* seamless import
BitKeeper / ClearCase import/sync
tool to import TeamWare history into Git
better SCM interop
* SCM rosetta / "Git for <SCM> users" documentation
* import/export tools supporting incremental import and export
* 100% subversion interoperability
* git update (stash, fetch, rebase, unstash) a la CVS
* git-svnserve
* svn:externals support
Tools
* improved administrative tools
* reasonable plugins for IDE (e.g. Visual Studio, KDevelop, NetBeans)
full Eclipse / NetBeans / IntelliJ support
* good integration with apps like Trac and Bugzilla
work with continuous integration tools (cruise control etc...)
* Git+Launchpad
* libification (for tools support)
Other
* SourceForge / Gna! / Google Projects support
(free) hosting with git facilities
FOSS hosting sites supporting git
* commercial support / corporate backing
contractual service
* number of users, to convince my co-workers that they're not
a silly minority
popularity
* projects switching to git
* user education
* marketing, advocacy videos
* convincing coworkers / other members / boss
willingness of the other developers to learn to use it
* training/certification
* a stop to the constant bashing of other SCMs - this doesn't get you
any friends drop the arrogant attitude, work with the rest of the
community and try to make something people can understand in an
hour
* http://wiki.FreeBSD.org/VersionControl
* At work it'd require some kind of miracle. Huge Perforce repository
of highly interrelated stuff in which people can make sweeping
changes in a single changelist. Lots of tools that access Perforce.
Slow as hell.
Getting help, staying in touch
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
61. Did you have problems getting GIT help on mailing list
or on IRC channel? What were it? What could be improved?
TO TABULARIZE
99 / 683 non-empty responses
Problems and suggestion for mailing list:
* I answered my own question and no one even commented it. User and
development discussion should be separated. Just release
announcements in the user list.
You need another mailing list for users. The current mailing list
is very developer centric.
The mailing list feels like it's more for developers rather than
users and it's a little intimidating to ask newbie questions there.
Maybe separate git-users and git-dev lists would make sense.
Git mailing list needs a users and developers list. Mixing up the
two is intimidating with all the traffic and the number of patches
and advanced topics that shoot around.
Having separate git-users and git-devel lists would be nice. I
might read both but I hate to ask a newbie question on a list where
50% of the submissions contain patches.
(Other users find mailing list very responsive. Splitting the list
into either git-devel and git-users, or git and git-announce has
its advantages and disadvantages. You can always filter out patch
submission and comments on patches thanks to the "[PATCH .*]"
prefix convention present on mailing list.)
* A question or two with no response at all. In hindsight my query
was way too long-winded but it's still frustrating to be ignored.
I answered my own question and no one even commented it.
(See above)
* The git mailing list is too high traffic to remain on. Maybe split
it into a few lower traffic versions?
Biggest problem is that smaller problems are getting lost in the
growing size of the mailing list.
The sheer amount of traffic makes the mailing list hard to deal
with sometimes. Getting your email tools set up correctly can help
(i.e. auto tag+archive in GMail), but ultimately you still have to
wade around in hundreds of emails you don't care about in order to
find the ones you do care about.
(Most people find traffic levels on git mailing list OK, see
question 58.)
* Will not go through corporate firewall.
(I think it was about mailing list, but perhaps it was about IRC)
I no longer subscribe to the GIT mailing list as ML subscription is
forbidden at my new job, and I have no time at home to read it all.
(You can read git mailing list through many archives / web
interfaces, including MARC and GMane ones, and throught NNTP
(aka. Usenet, aka news) interface on GMane. You don't need to be
subscribed to git mailing list to post.)
* People responded quickly to mailing list queries usually helpfully.
However there was occasionally a touch of annoying 'groupthink' to
the responses; sometimes new users are just confused and really
would be better served by just changing their working habits, but
other times there appeared to be a bit of tunnel-vision on the part
of the longtime git users.
* Trolls could be thrown out ;-) Seriously we had only a few there,
but they are mighty annoying.
* Mostly no. But little help on applying email-patches in win32 using
GMail. I'll get there though :)
(Late addition of smtpserver (with ability to select port number),
smtpuser, smtppass and smtpssl configuration variables / options to
git-send-email should help with _sending_ patches using GMail. As
to applying email-patches, git-am understand both mbox and maildir
formats, not that it help much with win32 mail programs; but you
can always try to save email in raw format from GMail WWW
interface)
Problems and suggestions for IRC:
* The IRC channel has too few people who know answers to questions;
if you're there at the wrong time of day when none of them happen
to be around it's useless. But if you're there at the right time
it's pretty good.
* IRC channel seems to respond to newbie git users quite well, but
mid-level experience often gets no response.
* Traffic on the IRC channel is a bit high. It may need to be split
into a few different high-level topics in the near future.
(IRC channel or git mailing list? I don't remember IRC channel
having high traffic...)
* It's hard to improve IRC. It's such a poor medium for understanding
the communication going on.
(On the other hand it is responsive. I think pastebins helps to
sidestep limitations of the medium. Nevertheless the main medium of
communication is git mailing list, not #git channel.)
* IRC is blocked from work :-( I may try it by tunneling out.
(Any suggestions here?)
Generic problems and suggestions:
* Sometimes you get no answer (on git mailing list or #git channel)
but that happens
* People seem to think the problem isn't with git, and yet I find git
extremely buggy and non-intuitive. Your "Git in 5 minutes" doesn't
even include +x a hook or mention of hooks; neither does linus
speech. If you don't +x a hook, try to figure out what is going
on. I dare you. Git fails silently a bunch, maybe half of the time
by design. Which shouldn't be acceptable.
Try addressing an ssh address in url format: it isn't consistent
and it will fail in half the apps. Same thing with git-ls-remote:
it might have an --upload-pack that works, but this isn't across
the board! From my own debugging none of the shell scripts have an
--upload-pack option that work.
(Not here. This is question about getting help from people, not
about documentation or what you find hardest in GIT.)
* After the last thread the GIT FAQ is almost begging for a 'Please
don't ask about C++' section.
(Truly, Git FAQ (which resides on Git wiki, but perhaps we should
consider extracting it and adding to distribution tarballs) needs
maintenance, updating and adding new frequently asked
questions. Currently there is no FAQ maintainer.)
The other side: getting help success stories:
* Quite the contrary. When Source Mage GNU/Linux switched to using
GIT our developers spent a considerable amount of time asking
questions and discussing features and bugs on #git. The feedback
that we got was fabulous: the GIT developers were helpful
interested in our needs and productive when it came to fixing
bugs. One bug we discovered was even handled by Linus Torvalds
himself and in just a matter of hours! In our eyes the GIT
development community gained rightful reputation as one of the most
friendly and helpful communities there is.
* No, the mailing list has been very responsive. I have never asked a
question on IRC but I sometimes answer newbie questions.
* Mailing list is very interesting especially as I'm working on
egit. IRC is more immediately helpful.
* I'd like to say that I consider #git to be the most useful IRC
channel I've ever been to when it came to getting answers to my
questions. Thanks guys!
The IRC channel is wonderful. The people there do a good job with
questions.
* No problems. In fact the mailing list/IRC could substitute the
documentation but I guess that
(1) does not work in offline mode
(2) _is_ going to get on peoples nerves after a while
(recurring questions)
Open forum
~~~~~~~~~~
62. What other comments or suggestions do you have, that are not
covered by the questions above?
TO DO
141 / 683 non-empty responses
There are many "keep up the great work!" (and equivalent) as answers
to this questions, and a few "worst SCM I've used". Those are excluded
from the lists below.
Suggestions for git:
* One of the biggest complaints I hear is that mercurial's UI is much
more 'intuitive' and user friendly. Perhaps looking at it's
operation and comparing/contrasting would be good.
(Note that changing names of commands for example might be
impossible because of historical reasons and large usebase.
On the other hand perhaps this is just a steep learning curve,
unavoidable for a power tool)
* Mercurial has an excellent tutorial which had my team up and
running in less than a hour after a week struggling to make git do
anything useful.
(I hope that late work on "Git User's Manual" helps here)
* Handling of Unicode (UTF-16 encoded) files is a big pain with git.
Even SVN can do a diff of them.
(The idea that blob is just a bag of bytes will not change; but we
have input/output filters, and soon before-diff filters, connected
with gitattributes)
* I like how in Subversion the commands work relative to the current
directory. With Git I always seem to be dealing with longer paths
and/or have to change to the root.
(Running git from within directory deep within repository structure
should 'just work'. If not, then it is an error... unless in
situation like referring to tree-ish, where path is almost always
relative to project root).
* Keep up the UI simplification and make sure the docs start off with
usage somewhat similar to CVS/SVN. I think many users are scared by
Git because they see the more powerful commands thrown around too
early and get scared.
Git is just too complicated for a typical project. I understand
it's probably great for the Linux kernel but for a smaller project
like mine (Mesa) it's overkill and a frustration. (...) With git
everything seems hard. (...) I've _wasted_ hours trying to figure
out git. That alone is a huge issue. I guess I could go into
specific details about my problems with git but I've already spent
enough time on this survey.
Figure out why people find git hard to learn and eliminate those
barriers to entry. Make git more task-oriented rather than
data-model-oriented the way it is now.
It's a great idea and a powerful tool but it's got a long way to go
before it reaches wider adoption because it's so damn hard to use.
(...) I'm evaluating Mercurial despite its being based on Python
because it feels cleaner and simpler to use. I would prefer to use
Git.
(I think the 1.4 and 1.5 series is a good step in simplifying git
for simple tasks and ordinary user. Core git porcelain improved
much, and now there is no need to use plumbing for every-day tasks)
* No one-pager cheat sheet with the 6 most basic commands on it so
people can go use git.
(This got corrected. There is git cheat sheet on the Internet;
there is link on GitWiki to it)
* Having a git library where other apps can integrate git, along with
bindings for Python would be great.
Make it easier to use by graphical clients like KGit.
(The libification projects from Google Summer of Code would help
there, I think)
* I think that moving away from shell scripts to builtins is a
necessary step but I don't really like it. It would help if you
kept them around, perhaps in contrib/, so that others can learn how
to use the plumbing (I learned a lot about git from reading these
shell scripts).
(Doing it: shell scripts which are moved to builtin are retired to
contrib/examples/ directory).
* Building git is a pain. (SHA1 sources being a problem). Can't git
use autoconf? Also I've heard people have issues with git's
portability (for example some BSD variant). Shell scrips weren't
portable to non bash IIRC and often relied on GNU extensions in
some programs. Native Windows port is also important.
Probably the toughest challenge for Git IMO is that Mercurial,
Darcs and Bazaar are good and similar. Lack of Windows support
makes some people rule out Git altogether even though it may be
better overall.
I'd like to just stress support for windows and central
repositories. (...) In fact most of my friends really wanted to use
git but they wanted a solid native port.
I think key to the adoption of git is that it is made to run on
Windows as well as the other major OSes.
(Git tries to use autoconf in a way that is totally optional, to do
detection and write options for Makefile; you are welcome to
contribute to configure.ac. People work on making git more
portable, for example trying to make it work with dash, defining
in the meantime minimal POSIX-like shell compatibility required.
Native MinGW Windows port is in the development)
* I think that it is very nice that git is in the native OS
repositories for Fedora. The Debian version needs updating.
(git Makefile has rpm target, and git.spec target; perhaps this is
the cause)
* git-blame is manageable (with gc and reduced history etc) but that
slowness still seems to be a negative point for many of my peers. I
wouldn't mind better performance there either. Maybe some kind of
optional indexing for those who want fast blame?
(I recall there were some ideas about how to make git-blame faster
on git mailing list. Making it interactive for graphical blame
tools reduced latency; there is I think a bit place for easy
improvement for reblaming. Maybe packv4 would help with blame
performance... What is I think unchangeable is the fact that
snapshot driven / whole history driven SCMs _always_ would be
slower at least a bit than single-file based SCMs. This tradeoff
is not possible to avoid. But don't forget that git has other
tools for examining history, like path (subsystem) limiting,
searching commit messages, pickaxe search and graphical history
browsing tools like gitk or qgit)
* Get a mascot perhaps O'Reilly animal for O'Reilly GitBook
(Git User's Manual) like the svnbook.
(What animal could Git use for O'Reilly? Herd of horses, or a
pony?)
* I'm wondering what the overall goal is - git's origin as a neutral
ground was fine but it hasn't seemed to take off as a viable
alternative for general use. Do you care about that? Is it ok
that git is it's own little niche?
(Junio, Linus?)
Suggestions about git mailing list:
* Git adoption will be limited by the actions and attitudes of those
on the mailing list. 'If you can't say anything nice...'
(We are nice, I think... to a point)
* The ML had way too much traffic. I think there should be at least a
git-patches@ where people submit there patches and git@ remains for
user/dev discussions.
(Most users find level of traffic on git mailing list O.K. It is
not that hard to separate patch submission and their discussion
from the rest of traffic thanks to [PATCH] prefix convention used.)
Suggestions and comments about this survey:
* Various questions need 'other' options such as the programming
language question. Various questions that already have 'other' as a
possible choice need a text box to fill in the specifics.
(I am not sure if it is possible mixing radiobutton/checkbox with
text field with currently used free survey service, survey.net.nz)
* The text fields (and text areas) of this survey are way too small!
(I am not sure if changing this is possible with currently used
free survey service, survey.net.nz)
* You should do a survey of feature requests.
(See questions 13, 38, 41 and especially 37)
* Shorten survey length. This survey is too damn long. Make the
survey shorter!
Cut down the number of questions on this survey by a factor of 4.
(I think removing the questions which asks very similar question
but in different context be a good start. But that aside: which
questions should be dropped, which concatenated (and which split);
which are useful and which are not?)
* Questions not asked: what can be improved on GitWiki, workflows
used and tools used, kind of repository hosting used for project,
programming experience level and version control experience, using
git for non-programming repositories like ikiwiki or documents,
perceived git stability and number of bugs.
(The surveys is very long as it is now. Those questions are nice,
but it would make survey too long I think.)
* The survey asks about new features that are not in a stable version
of git yet. git-stash comes to mind. This is silly. Not everybody
will track your development branch. I certainly don't. I don't for
other SCMs I use either.
(I tried to put only features which are in released, i.e. numbered,
version. git-stash is in 1.5.3, see Documentation/RelNotes-1.5.3.txt)
* Regarding Q19 (How do you obtain GIT?). I actually use all three
forms on different systems.
Mac: pull from MacPorts
Ubuntu: from git.git
remote systems: tar balls.
(Should it be made multiple choice question, then?)
Some other comments:
* I've been so busy with other projects. I didn't realize so many
interfaces exist. Thanks to this survey I'll spend some time
checking out the wiki for the other interfaces.
I didn't even know about any of the new git features listed in
question 43.
I need to get an up to date version as there are things mentioned
in this survey that I don't know about.
* At the 'Solutions Linux 2007' exhibition in Paris I have been
looking for a service provider that could propose some training
sessions for Git. I couldn't find one. Maybe in 2008...
--
Jakub Narebski
(away from Internet)
^ permalink raw reply [relevance 2%]
* [PATCH 2/3] Quoting paths in tests
@ 2007-10-15 13:13 7% ` Jonathan del Strother
0 siblings, 0 replies; 200+ results
From: Jonathan del Strother @ 2007-10-15 13:13 UTC (permalink / raw)
To: git; +Cc: Jonathan del Strother
From: Jonathan del Strother <jon.delStrother@bestbefore.tv>
Add quoting to various test paths so they can be run from a path with a space in
Signed-off-by: Jonathan del Strother <jon.delStrother@bestbefore.tv>
---
t/lib-git-svn.sh | 2 +-
t/t1020-subdirectory.sh | 22 ++++++------
t/t3050-subprojects-fetch.sh | 2 +-
t/t3404-rebase-interactive.sh | 2 +-
t/t5500-fetch-pack.sh | 2 +-
t/t5700-clone-reference.sh | 2 +-
t/t7003-filter-branch.sh | 2 +-
t/t7501-commit.sh | 4 +-
t/t9100-git-svn-basic.sh | 18 +++++-----
t/t9101-git-svn-props.sh | 6 ++--
t/t9102-git-svn-deep-rmdir.sh | 6 ++--
t/t9104-git-svn-follow-parent.sh | 50 +++++++++++++++---------------
t/t9105-git-svn-commit-diff.sh | 10 +++---
t/t9106-git-svn-commit-diff-clobber.sh | 14 ++++----
t/t9107-git-svn-migrate.sh | 40 ++++++++++++------------
t/t9108-git-svn-glob.sh | 8 ++--
t/t9110-git-svn-use-svm-props.sh | 8 ++--
t/t9111-git-svn-use-svnsync-props.sh | 8 ++--
t/t9112-git-svn-md5less-file.sh | 4 +-
t/t9113-git-svn-dcommit-new-file.sh | 6 ++--
t/t9114-git-svn-dcommit-merge.sh | 4 +-
t/t9115-git-svn-dcommit-funky-renames.sh | 4 +-
t/t9116-git-svn-log.sh | 4 +-
t/t9500-gitweb-standalone-no-errors.sh | 4 +-
t/test-lib.sh | 2 +-
25 files changed, 117 insertions(+), 117 deletions(-)
diff --git a/t/lib-git-svn.sh b/t/lib-git-svn.sh
index 8d4a447..cde3053 100644
--- a/t/lib-git-svn.sh
+++ b/t/lib-git-svn.sh
@@ -25,7 +25,7 @@ perl -w -e "
use SVN::Core;
use SVN::Repos;
\$SVN::Core::VERSION gt '1.1.0' or exit(42);
-system(qw/svnadmin create --fs-type fsfs/, '$svnrepo') == 0 or exit(41);
+system(qw/svnadmin create --fs-type fsfs/, \"$svnrepo\") == 0 or exit(41);
" >&3 2>&4
x=$?
if test $x -ne 0
diff --git a/t/t1020-subdirectory.sh b/t/t1020-subdirectory.sh
index b9cef34..5ed7fa4 100755
--- a/t/t1020-subdirectory.sh
+++ b/t/t1020-subdirectory.sh
@@ -21,7 +21,7 @@ LF='
'
test_expect_success 'update-index and ls-files' '
- cd $HERE &&
+ cd "$HERE" &&
git update-index --add one &&
case "`git ls-files`" in
one) echo ok one ;;
@@ -41,7 +41,7 @@ test_expect_success 'update-index and ls-files' '
'
test_expect_success 'cat-file' '
- cd $HERE &&
+ cd "$HERE" &&
two=`git ls-files -s dir/two` &&
two=`expr "$two" : "[0-7]* \\([0-9a-f]*\\)"` &&
echo "$two" &&
@@ -54,7 +54,7 @@ test_expect_success 'cat-file' '
rm -f actual dir/actual
test_expect_success 'diff-files' '
- cd $HERE &&
+ cd "$HERE" &&
echo a >>one &&
echo d >>dir/two &&
case "`git diff-files --name-only`" in
@@ -74,7 +74,7 @@ test_expect_success 'diff-files' '
'
test_expect_success 'write-tree' '
- cd $HERE &&
+ cd "$HERE" &&
top=`git write-tree` &&
echo $top &&
cd dir &&
@@ -84,7 +84,7 @@ test_expect_success 'write-tree' '
'
test_expect_success 'checkout-index' '
- cd $HERE &&
+ cd "$HERE" &&
git checkout-index -f -u one &&
cmp one original.one &&
cd dir &&
@@ -93,7 +93,7 @@ test_expect_success 'checkout-index' '
'
test_expect_success 'read-tree' '
- cd $HERE &&
+ cd "$HERE" &&
rm -f one dir/two &&
tree=`git write-tree` &&
git read-tree --reset -u "$tree" &&
@@ -107,27 +107,27 @@ test_expect_success 'read-tree' '
'
test_expect_success 'no file/rev ambiguity check inside .git' '
- cd $HERE &&
+ cd "$HERE" &&
git commit -a -m 1 &&
- cd $HERE/.git &&
+ cd "$HERE/.git" &&
git show -s HEAD
'
test_expect_success 'no file/rev ambiguity check inside a bare repo' '
- cd $HERE &&
+ cd "$HERE" &&
git clone -s --bare .git foo.git &&
cd foo.git && GIT_DIR=. git show -s HEAD
'
# This still does not work as it should...
: test_expect_success 'no file/rev ambiguity check inside a bare repo' '
- cd $HERE &&
+ cd "$HERE" &&
git clone -s --bare .git foo.git &&
cd foo.git && git show -s HEAD
'
test_expect_success 'detection should not be fooled by a symlink' '
- cd $HERE &&
+ cd "$HERE" &&
rm -fr foo.git &&
git clone -s .git another &&
ln -s another yetanother &&
diff --git a/t/t3050-subprojects-fetch.sh b/t/t3050-subprojects-fetch.sh
index 34f26a8..4b74cc6 100755
--- a/t/t3050-subprojects-fetch.sh
+++ b/t/t3050-subprojects-fetch.sh
@@ -20,7 +20,7 @@ test_expect_success setup '
'
test_expect_success clone '
- git clone file://`pwd`/.git cloned &&
+ git clone "file://`pwd`/.git" cloned &&
(git rev-parse HEAD; git ls-files -s) >expected &&
(
cd cloned &&
diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh
index 1113904..aa86042 100755
--- a/t/t3404-rebase-interactive.sh
+++ b/t/t3404-rebase-interactive.sh
@@ -92,7 +92,7 @@ done
EOF
chmod a+x fake-editor.sh
-VISUAL="$(pwd)/fake-editor.sh"
+VISUAL="\"$(pwd)/fake-editor.sh\""
export VISUAL
test_expect_success 'no changes are a nop' '
diff --git a/t/t5500-fetch-pack.sh b/t/t5500-fetch-pack.sh
index 7b6798d..5489ffe 100755
--- a/t/t5500-fetch-pack.sh
+++ b/t/t5500-fetch-pack.sh
@@ -129,7 +129,7 @@ pull_to_client 2nd "B" $((64*3))
pull_to_client 3rd "A" $((1*3)) # old fails
-test_expect_success "clone shallow" "git-clone --depth 2 file://`pwd`/. shallow"
+test_expect_success "clone shallow" "git-clone --depth 2 \"file://`pwd`/.\" shallow"
(cd shallow; git count-objects -v) > count.shallow
diff --git a/t/t5700-clone-reference.sh b/t/t5700-clone-reference.sh
index 4e93aaa..8bb34f9 100755
--- a/t/t5700-clone-reference.sh
+++ b/t/t5700-clone-reference.sh
@@ -51,7 +51,7 @@ diff expected current'
cd "$base_dir"
test_expect_success 'cloning with reference (no -l -s)' \
-'git clone --reference B file://`pwd`/A D'
+'git clone --reference B "file://`pwd`/A" D'
cd "$base_dir"
diff --git a/t/t7003-filter-branch.sh b/t/t7003-filter-branch.sh
index e935b20..1ab5392 100755
--- a/t/t7003-filter-branch.sh
+++ b/t/t7003-filter-branch.sh
@@ -107,7 +107,7 @@ test_expect_success 'use index-filter to move into a subdirectory' '
"git ls-files -s | sed \"s-\\t-&newsubdir/-\" |
GIT_INDEX_FILE=\$GIT_INDEX_FILE.new \
git update-index --index-info &&
- mv \$GIT_INDEX_FILE.new \$GIT_INDEX_FILE" directorymoved &&
+ mv \"\$GIT_INDEX_FILE.new\" \"\$GIT_INDEX_FILE\"" directorymoved &&
test -z "$(git diff HEAD directorymoved:newsubdir)"'
test_expect_success 'stops when msg filter fails' '
diff --git a/t/t7501-commit.sh b/t/t7501-commit.sh
index b151b51..e97e756 100644
--- a/t/t7501-commit.sh
+++ b/t/t7501-commit.sh
@@ -69,7 +69,7 @@ test_expect_success \
cat >editor <<\EOF
#!/bin/sh
-sed -i -e "s/a file/an amend commit/g" $1
+sed -i -e "s/a file/an amend commit/g" "$1"
EOF
chmod 755 editor
@@ -88,7 +88,7 @@ test_expect_success \
cat >editor <<\EOF
#!/bin/sh
-sed -i -e "s/amend/older/g" $1
+sed -i -e "s/amend/older/g" "$1"
EOF
chmod 755 editor
diff --git a/t/t9100-git-svn-basic.sh b/t/t9100-git-svn-basic.sh
index 614cf50..c3585da 100755
--- a/t/t9100-git-svn-basic.sh
+++ b/t/t9100-git-svn-basic.sh
@@ -31,16 +31,16 @@ test_expect_success \
echo 'zzz' > bar/zzz &&
echo '#!/bin/sh' > exec.sh &&
chmod +x exec.sh &&
- svn import -m 'import for git-svn' . $svnrepo >/dev/null &&
+ svn import -m 'import for git-svn' . '$svnrepo' >/dev/null &&
cd .. &&
rm -rf import &&
- git-svn init $svnrepo"
+ git-svn init '$svnrepo'"
test_expect_success \
'import an SVN revision into git' \
'git-svn fetch'
-test_expect_success "checkout from svn" "svn co $svnrepo '$SVN_TREE'"
+test_expect_success "checkout from svn" "svn co '$svnrepo' '$SVN_TREE'"
name='try a deep --rmdir with a commit'
test_expect_success "$name" "
@@ -169,7 +169,7 @@ test_expect_success "$name" "
svn up '$SVN_TREE' &&
test -f '$SVN_TREE'/exec-2.sh &&
test ! -L '$SVN_TREE'/exec-2.sh &&
- git diff help $SVN_TREE/exec-2.sh"
+ git diff help '$SVN_TREE/exec-2.sh'"
if test "$have_utf8" = t
then
@@ -190,7 +190,7 @@ name='test fetch functionality (svn => git) with alternate GIT_SVN_ID'
GIT_SVN_ID=alt
export GIT_SVN_ID
test_expect_success "$name" \
- "git-svn init $svnrepo && git-svn fetch &&
+ "git-svn init '$svnrepo' && git-svn fetch &&
git rev-list --pretty=raw remotes/git-svn | grep ^tree | uniq > a &&
git rev-list --pretty=raw remotes/alt | grep ^tree | uniq > b &&
git diff a b"
@@ -220,16 +220,16 @@ test_expect_failure 'exit if remote refs are ambigious' "
"
test_expect_failure 'exit if init-ing a would clobber a URL' "
- svnadmin create ${PWD}/svnrepo2 &&
- svn mkdir -m 'mkdir bar' ${svnrepo}2/bar &&
+ svnadmin create '${PWD}/svnrepo2' &&
+ svn mkdir -m 'mkdir bar' '${svnrepo}2/bar' &&
git config --unset svn-remote.svn.fetch \
'^bar:refs/remotes/git-svn$' &&
- git-svn init ${svnrepo}2/bar
+ git-svn init '${svnrepo}2/bar'
"
test_expect_success \
'init allows us to connect to another directory in the same repo' "
- git-svn init --minimize-url -i bar $svnrepo/bar &&
+ git-svn init --minimize-url -i bar '$svnrepo/bar' &&
git config --get svn-remote.svn.fetch \
'^bar:refs/remotes/bar$' &&
git config --get svn-remote.svn.fetch \
diff --git a/t/t9101-git-svn-props.sh b/t/t9101-git-svn-props.sh
index 5aac644..a1c85e0 100755
--- a/t/t9101-git-svn-props.sh
+++ b/t/t9101-git-svn-props.sh
@@ -52,7 +52,7 @@ EOF
cd ..
rm -rf import
-test_expect_success 'checkout working copy from svn' "svn co $svnrepo test_wc"
+test_expect_success 'checkout working copy from svn' "svn co '$svnrepo' test_wc"
test_expect_success 'setup some commits to svn' \
'cd test_wc &&
echo Greetings >> kw.c &&
@@ -66,7 +66,7 @@ test_expect_success 'setup some commits to svn' \
svn commit -m "Propset Id" &&
cd ..'
-test_expect_success 'initialize git-svn' "git-svn init $svnrepo"
+test_expect_success 'initialize git-svn' "git-svn init '$svnrepo'"
test_expect_success 'fetch revisions from svn' 'git-svn fetch'
name='test svn:keywords ignoring'
@@ -92,7 +92,7 @@ test_expect_success "propset CR on crlf files" \
test_expect_success 'fetch and pull latest from svn and checkout a new wc' \
"git-svn fetch &&
git pull . remotes/git-svn &&
- svn co $svnrepo new_wc"
+ svn co '$svnrepo' new_wc"
for i in crlf ne_crlf lf ne_lf cr ne_cr empty_cr empty_lf empty empty_crlf
do
diff --git a/t/t9102-git-svn-deep-rmdir.sh b/t/t9102-git-svn-deep-rmdir.sh
index 4e08083..99c8840 100755
--- a/t/t9102-git-svn-deep-rmdir.sh
+++ b/t/t9102-git-svn-deep-rmdir.sh
@@ -9,12 +9,12 @@ test_expect_success 'initialize repo' "
mkdir -p deeply/nested/directory/number/2 &&
echo foo > deeply/nested/directory/number/1/file &&
echo foo > deeply/nested/directory/number/2/another &&
- svn import -m 'import for git-svn' . $svnrepo &&
+ svn import -m 'import for git-svn' . '$svnrepo' &&
cd ..
"
test_expect_success 'mirror via git-svn' "
- git-svn init $svnrepo &&
+ git-svn init '$svnrepo' &&
git-svn fetch &&
git checkout -f -b test-rmdir remotes/git-svn
"
@@ -23,7 +23,7 @@ test_expect_success 'Try a commit on rmdir' "
git rm -f deeply/nested/directory/number/2/another &&
git commit -a -m 'remove another' &&
git-svn set-tree --rmdir HEAD &&
- svn ls -R $svnrepo | grep ^deeply/nested/directory/number/1
+ svn ls -R '$svnrepo' | grep ^deeply/nested/directory/number/1
"
diff --git a/t/t9104-git-svn-follow-parent.sh b/t/t9104-git-svn-follow-parent.sh
index 7ba7630..aa2bfe2 100755
--- a/t/t9104-git-svn-follow-parent.sh
+++ b/t/t9104-git-svn-follow-parent.sh
@@ -11,9 +11,9 @@ test_expect_success 'initialize repo' "
cd import &&
mkdir -p trunk &&
echo hello > trunk/readme &&
- svn import -m 'initial' . $svnrepo &&
+ svn import -m 'initial' . '$svnrepo' &&
cd .. &&
- svn co $svnrepo wc &&
+ svn co '$svnrepo' wc &&
cd wc &&
echo world >> trunk/readme &&
poke trunk/readme &&
@@ -27,7 +27,7 @@ test_expect_success 'initialize repo' "
"
test_expect_success 'init and fetch a moved directory' "
- git-svn init --minimize-url -i thunk $svnrepo/thunk &&
+ git-svn init --minimize-url -i thunk '$svnrepo/thunk' &&
git-svn fetch -i thunk &&
test \"\`git rev-parse --verify refs/remotes/thunk@2\`\" \
= \"\`git rev-parse --verify refs/remotes/thunk~1\`\" &&
@@ -38,7 +38,7 @@ test_expect_success 'init and fetch a moved directory' "
"
test_expect_success 'init and fetch from one svn-remote' "
- git config svn-remote.svn.url $svnrepo &&
+ git config svn-remote.svn.url '$svnrepo' &&
git config --add svn-remote.svn.fetch \
trunk:refs/remotes/svn/trunk &&
git config --add svn-remote.svn.fetch \
@@ -52,9 +52,9 @@ test_expect_success 'init and fetch from one svn-remote' "
test_expect_success 'follow deleted parent' "
(svn cp -m 'resurrecting trunk as junk' \
- $svnrepo/trunk@2 $svnrepo/junk ||
+ '$svnrepo/trunk@2' '$svnrepo'/junk ||
svn cp -m 'resurrecting trunk as junk' \
- -r2 $svnrepo/trunk $svnrepo/junk) &&
+ -r2 '$svnrepo/trunk' '$svnrepo/junk') &&
git config --add svn-remote.svn.fetch \
junk:refs/remotes/svn/junk &&
git-svn fetch -i svn/thunk &&
@@ -67,10 +67,10 @@ test_expect_success 'follow deleted parent' "
test_expect_success 'follow larger parent' "
mkdir -p import/trunk/thunk/bump/thud &&
echo hi > import/trunk/thunk/bump/thud/file &&
- svn import -m 'import a larger parent' import $svnrepo/larger-parent &&
- svn cp -m 'hi' $svnrepo/larger-parent $svnrepo/another-larger &&
+ svn import -m 'import a larger parent' import '$svnrepo/larger-parent' &&
+ svn cp -m 'hi' '$svnrepo/larger-parent' '$svnrepo/another-larger' &&
git-svn init --minimize-url -i larger \
- $svnrepo/another-larger/trunk/thunk/bump/thud &&
+ '$svnrepo/another-larger/trunk/thunk/bump/thud' &&
git-svn fetch -i larger &&
git rev-parse --verify refs/remotes/larger &&
git rev-parse --verify \
@@ -83,23 +83,23 @@ test_expect_success 'follow larger parent' "
"
test_expect_success 'follow higher-level parent' "
- svn mkdir -m 'follow higher-level parent' $svnrepo/blob &&
- svn co $svnrepo/blob blob &&
+ svn mkdir -m 'follow higher-level parent' '$svnrepo/blob' &&
+ svn co '$svnrepo/blob' blob &&
cd blob &&
echo hi > hi &&
svn add hi &&
svn commit -m 'hihi' &&
cd ..
- svn mkdir -m 'new glob at top level' $svnrepo/glob &&
- svn mv -m 'move blob down a level' $svnrepo/blob $svnrepo/glob/blob &&
- git-svn init --minimize-url -i blob $svnrepo/glob/blob &&
+ svn mkdir -m 'new glob at top level' '$svnrepo/glob' &&
+ svn mv -m 'move blob down a level' '$svnrepo/blob' '$svnrepo/glob/blob' &&
+ git-svn init --minimize-url -i blob '$svnrepo/glob/blob' &&
git-svn fetch -i blob
"
test_expect_success 'follow deleted directory' "
- svn mv -m 'bye!' $svnrepo/glob/blob/hi $svnrepo/glob/blob/bye &&
- svn rm -m 'remove glob' $svnrepo/glob &&
- git-svn init --minimize-url -i glob $svnrepo/glob &&
+ svn mv -m 'bye!' '$svnrepo/glob/blob/hi' '$svnrepo/glob/blob/bye' &&
+ svn rm -m 'remove glob' '$svnrepo/glob' &&
+ git-svn init --minimize-url -i glob '$svnrepo/glob' &&
git-svn fetch -i glob &&
test \"\`git cat-file blob refs/remotes/glob:blob/bye\`\" = hi &&
test \"\`git ls-tree refs/remotes/glob | wc -l \`\" -eq 1
@@ -118,9 +118,9 @@ test_expect_success 'follow-parent avoids deleting relevant info' "
echo 'bad delete test 2' > \
import/trunk/subversion/bindings/swig/perl/another-larger &&
cd import &&
- svn import -m 'r9270 test' . $svnrepo/r9270 &&
+ svn import -m 'r9270 test' . '$svnrepo/r9270' &&
cd .. &&
- svn co $svnrepo/r9270/trunk/subversion/bindings/swig/perl r9270 &&
+ svn co '$svnrepo/r9270/trunk/subversion/bindings/swig/perl' r9270 &&
cd r9270 &&
svn mkdir native &&
svn mv t native/t &&
@@ -130,7 +130,7 @@ test_expect_success 'follow-parent avoids deleting relevant info' "
svn commit -m 'reorg test' &&
cd .. &&
git-svn init --minimize-url -i r9270-t \
- $svnrepo/r9270/trunk/subversion/bindings/swig/perl/native/t &&
+ '$svnrepo/r9270/trunk/subversion/bindings/swig/perl/native/t' &&
git-svn fetch -i r9270-t &&
test \`git rev-list r9270-t | wc -l\` -eq 2 &&
test \"\`git ls-tree --name-only r9270-t~1\`\" = \
@@ -138,9 +138,9 @@ test_expect_success 'follow-parent avoids deleting relevant info' "
"
test_expect_success "track initial change if it was only made to parent" "
- svn cp -m 'wheee!' $svnrepo/r9270/trunk $svnrepo/r9270/drunk &&
+ svn cp -m 'wheee!' '$svnrepo/r9270/trunk' '$svnrepo/r9270/drunk' &&
git-svn init --minimize-url -i r9270-d \
- $svnrepo/r9270/drunk/subversion/bindings/swig/perl/native/t &&
+ '$svnrepo/r9270/drunk/subversion/bindings/swig/perl/native/t' &&
git-svn fetch -i r9270-d &&
test \`git rev-list r9270-d | wc -l\` -eq 3 &&
test \"\`git ls-tree --name-only r9270-t\`\" = \
@@ -150,7 +150,7 @@ test_expect_success "track initial change if it was only made to parent" "
"
test_expect_success "track multi-parent paths" "
- svn cp -m 'resurrect /glob' $svnrepo/r9270 $svnrepo/glob &&
+ svn cp -m 'resurrect /glob' '$svnrepo/r9270' '$svnrepo/glob' &&
git-svn multi-fetch &&
test \`git cat-file commit refs/remotes/glob | \
grep '^parent ' | wc -l\` -eq 2
@@ -161,8 +161,8 @@ test_expect_success "multi-fetch continues to work" "
"
test_expect_success "multi-fetch works off a 'clean' repository" "
- rm -r $GIT_DIR/svn $GIT_DIR/refs/remotes $GIT_DIR/logs &&
- mkdir $GIT_DIR/svn &&
+ rm -r '$GIT_DIR/svn' '$GIT_DIR/refs/remotes' '$GIT_DIR/logs' &&
+ mkdir '$GIT_DIR/svn' &&
git-svn multi-fetch
"
diff --git a/t/t9105-git-svn-commit-diff.sh b/t/t9105-git-svn-commit-diff.sh
index 318e172..2e1eb75 100755
--- a/t/t9105-git-svn-commit-diff.sh
+++ b/t/t9105-git-svn-commit-diff.sh
@@ -8,7 +8,7 @@ test_expect_success 'initialize repo' "
mkdir import &&
cd import &&
echo hello > readme &&
- svn import -m 'initial' . $svnrepo &&
+ svn import -m 'initial' . '$svnrepo' &&
cd .. &&
echo hello > readme &&
git update-index --add readme &&
@@ -27,16 +27,16 @@ prev=`git rev-parse --verify HEAD^1`
test_expect_success 'test the commit-diff command' "
test -n '$prev' && test -n '$head' &&
git-svn commit-diff -r1 '$prev' '$head' '$svnrepo' &&
- svn co $svnrepo wc &&
+ svn co '$svnrepo' wc &&
cmp readme wc/readme
"
test_expect_success 'commit-diff to a sub-directory (with git-svn config)' "
- svn import -m 'sub-directory' import $svnrepo/subdir &&
- git-svn init --minimize-url $svnrepo/subdir &&
+ svn import -m 'sub-directory' import '$svnrepo/subdir' &&
+ git-svn init --minimize-url '$svnrepo/subdir' &&
git-svn fetch &&
git-svn commit-diff -r3 '$prev' '$head' &&
- svn cat $svnrepo/subdir/readme > readme.2 &&
+ svn cat '$svnrepo/subdir/readme' > readme.2 &&
cmp readme readme.2
"
diff --git a/t/t9106-git-svn-commit-diff-clobber.sh b/t/t9106-git-svn-commit-diff-clobber.sh
index 79b7968..bb42339 100755
--- a/t/t9106-git-svn-commit-diff-clobber.sh
+++ b/t/t9106-git-svn-commit-diff-clobber.sh
@@ -8,14 +8,14 @@ test_expect_success 'initialize repo' "
mkdir import &&
cd import &&
echo initial > file &&
- svn import -m 'initial' . $svnrepo &&
+ svn import -m 'initial' . '$svnrepo' &&
cd .. &&
echo initial > file &&
git update-index --add file &&
git commit -a -m 'initial'
"
test_expect_success 'commit change from svn side' "
- svn co $svnrepo t.svn &&
+ svn co '$svnrepo' t.svn &&
cd t.svn &&
echo second line from svn >> file &&
poke file &&
@@ -27,7 +27,7 @@ test_expect_success 'commit change from svn side' "
test_expect_failure 'commit conflicting change from git' "
echo second line from git >> file &&
git commit -a -m 'second line from git' &&
- git-svn commit-diff -r1 HEAD~1 HEAD $svnrepo
+ git-svn commit-diff -r1 HEAD~1 HEAD '$svnrepo'
" || true
test_expect_success 'commit complementing change from git' "
@@ -36,14 +36,14 @@ test_expect_success 'commit complementing change from git' "
git commit -a -m 'second line from svn' &&
echo third line from git >> file &&
git commit -a -m 'third line from git' &&
- git-svn commit-diff -r2 HEAD~1 HEAD $svnrepo
+ git-svn commit-diff -r2 HEAD~1 HEAD '$svnrepo'
"
test_expect_failure 'dcommit fails to commit because of conflict' "
- git-svn init $svnrepo &&
+ git-svn init '$svnrepo' &&
git-svn fetch &&
git reset --hard refs/remotes/git-svn &&
- svn co $svnrepo t.svn &&
+ svn co '$svnrepo' t.svn &&
cd t.svn &&
echo fourth line from svn >> file &&
poke file &&
@@ -67,7 +67,7 @@ test_expect_success 'dcommit does the svn equivalent of an index merge' "
"
test_expect_success 'commit another change from svn side' "
- svn co $svnrepo t.svn &&
+ svn co '$svnrepo' t.svn &&
cd t.svn &&
echo third line from svn >> file &&
poke file &&
diff --git a/t/t9107-git-svn-migrate.sh b/t/t9107-git-svn-migrate.sh
index 67fdf70..90bf786 100755
--- a/t/t9107-git-svn-migrate.sh
+++ b/t/t9107-git-svn-migrate.sh
@@ -4,7 +4,7 @@ test_description='git-svn metadata migrations from previous versions'
. ./lib-git-svn.sh
test_expect_success 'setup old-looking metadata' "
- cp $GIT_DIR/config $GIT_DIR/config-old-git-svn &&
+ cp '$GIT_DIR/config' '$GIT_DIR/config-old-git-svn' &&
mkdir import &&
cd import &&
for i in trunk branches/a branches/b \
@@ -12,13 +12,13 @@ test_expect_success 'setup old-looking metadata' "
mkdir -p \$i && \
echo hello >> \$i/README || exit 1
done && \
- svn import -m test . $svnrepo
+ svn import -m test . '$svnrepo'
cd .. &&
- git-svn init $svnrepo &&
+ git-svn init '$svnrepo' &&
git-svn fetch &&
- mv $GIT_DIR/svn/* $GIT_DIR/ &&
- mv $GIT_DIR/svn/.metadata $GIT_DIR/ &&
- rmdir $GIT_DIR/svn &&
+ mv '$GIT_DIR'/svn/* '$GIT_DIR/' &&
+ mv '$GIT_DIR/svn/.metadata' '$GIT_DIR/' &&
+ rmdir '$GIT_DIR/svn' &&
git update-ref refs/heads/git-svn-HEAD refs/remotes/git-svn &&
git update-ref refs/heads/svn-HEAD refs/remotes/git-svn &&
git update-ref -d refs/remotes/git-svn refs/remotes/git-svn
@@ -28,20 +28,20 @@ head=`git rev-parse --verify refs/heads/git-svn-HEAD^0`
test_expect_success 'git-svn-HEAD is a real HEAD' "test -n '$head'"
test_expect_success 'initialize old-style (v0) git-svn layout' "
- mkdir -p $GIT_DIR/git-svn/info $GIT_DIR/svn/info &&
- echo $svnrepo > $GIT_DIR/git-svn/info/url &&
- echo $svnrepo > $GIT_DIR/svn/info/url &&
+ mkdir -p '$GIT_DIR/git-svn/info' '$GIT_DIR/svn/info' &&
+ echo '$svnrepo' > '$GIT_DIR/git-svn/info/url' &&
+ echo '$svnrepo' > '$GIT_DIR/svn/info/url' &&
git-svn migrate &&
- ! test -d $GIT_DIR/git-svn &&
+ ! test -d '$GIT_DIR/git-svn' &&
git rev-parse --verify refs/remotes/git-svn^0 &&
git rev-parse --verify refs/remotes/svn^0 &&
- test \`git config --get svn-remote.svn.url\` = '$svnrepo' &&
+ test \"\`git config --get svn-remote.svn.url\`\" = \"$svnrepo\" &&
test \`git config --get svn-remote.svn.fetch\` = \
':refs/remotes/git-svn'
"
test_expect_success 'initialize a multi-repository repo' "
- git-svn init $svnrepo -T trunk -t tags -b branches &&
+ git-svn init '$svnrepo' -T trunk -t tags -b branches &&
git config --get-all svn-remote.svn.fetch > fetch.out &&
grep '^trunk:refs/remotes/trunk$' fetch.out &&
test -n \"\`git config --get svn-remote.svn.branches \
@@ -76,14 +76,14 @@ test_expect_success 'multi-fetch works on partial urls + paths' "
test_expect_success 'migrate --minimize on old inited layout' "
git config --unset-all svn-remote.svn.fetch &&
git config --unset-all svn-remote.svn.url &&
- rm -rf $GIT_DIR/svn &&
+ rm -rf '$GIT_DIR/svn' &&
for i in \`cat fetch.out\`; do
path=\`expr \$i : '\\([^:]*\\):.*$'\`
ref=\`expr \$i : '[^:]*:refs/remotes/\\(.*\\)$'\`
if test -z \"\$ref\"; then continue; fi
if test -n \"\$path\"; then path=\"/\$path\"; fi
- ( mkdir -p $GIT_DIR/svn/\$ref/info/ &&
- echo $svnrepo\$path > $GIT_DIR/svn/\$ref/info/url ) || exit 1;
+ ( mkdir -p '$GIT_DIR'/svn/\$ref/info/ &&
+ echo '$svnrepo'\$path > '$GIT_DIR'/svn/\$ref/info/url ) || exit 1;
done &&
git-svn migrate --minimize &&
test -z \"\`git config -l |grep -v '^svn-remote\.git-svn\.'\`\" &&
@@ -99,13 +99,13 @@ test_expect_success 'migrate --minimize on old inited layout' "
test_expect_success ".rev_db auto-converted to .rev_db.UUID" "
git-svn fetch -i trunk &&
- expect=$GIT_DIR/svn/trunk/.rev_db.* &&
+ expect=\"\`find \"\$GIT_DIR\"/svn/trunk/ -name '.rev_db.*'\`\" &&
test -n \"\$expect\" &&
- mv \$expect $GIT_DIR/svn/trunk/.rev_db &&
+ mv \"\$expect\" \"\$GIT_DIR\"/svn/trunk/.rev_db &&
git-svn fetch -i trunk &&
- test -L $GIT_DIR/svn/trunk/.rev_db &&
- test -f \$expect &&
- cmp \$expect $GIT_DIR/svn/trunk/.rev_db
+ test -L \"\$GIT_DIR\"/svn/trunk/.rev_db &&
+ test -f \"\$expect\" &&
+ cmp \"\$expect\" \"\$GIT_DIR\"/svn/trunk/.rev_db
"
test_done
diff --git a/t/t9108-git-svn-glob.sh b/t/t9108-git-svn-glob.sh
index db4344c..c6dc0ef 100755
--- a/t/t9108-git-svn-glob.sh
+++ b/t/t9108-git-svn-glob.sh
@@ -14,8 +14,8 @@ test_expect_success 'test refspec globbing' "
mkdir -p trunk/src/a trunk/src/b trunk/doc &&
echo 'hello world' > trunk/src/a/readme &&
echo 'goodbye world' > trunk/src/b/readme &&
- svn import -m 'initial' trunk $svnrepo/trunk &&
- svn co $svnrepo tmp &&
+ svn import -m 'initial' trunk '$svnrepo/trunk' &&
+ svn co '$svnrepo' tmp &&
cd tmp &&
mkdir branches tags &&
svn add branches tags &&
@@ -38,7 +38,7 @@ test_expect_success 'test refspec globbing' "
poke tags/end/src/b/readme &&
svn commit -m 'nothing to see here'
cd .. &&
- git config --add svn-remote.svn.url $svnrepo &&
+ git config --add svn-remote.svn.url '$svnrepo' &&
git config --add svn-remote.svn.fetch \
'trunk/src/a:refs/remotes/trunk' &&
git config --add svn-remote.svn.branches \
@@ -60,7 +60,7 @@ echo nothing to see here >> expect.two
cat expect.end >> expect.two
test_expect_success 'test left-hand-side only globbing' "
- git config --add svn-remote.two.url $svnrepo &&
+ git config --add svn-remote.two.url '$svnrepo' &&
git config --add svn-remote.two.fetch trunk:refs/remotes/two/trunk &&
git config --add svn-remote.two.branches \
'branches/*:refs/remotes/two/branches/*' &&
diff --git a/t/t9110-git-svn-use-svm-props.sh b/t/t9110-git-svn-use-svm-props.sh
index 6235af4..d4ab01f 100755
--- a/t/t9110-git-svn-use-svm-props.sh
+++ b/t/t9110-git-svn-use-svm-props.sh
@@ -8,11 +8,11 @@ test_description='git-svn useSvmProps test'
. ./lib-git-svn.sh
test_expect_success 'load svm repo' "
- svnadmin load -q $rawsvnrepo < ../t9110/svm.dump &&
- git-svn init --minimize-url -R arr -i bar $svnrepo/mirror/arr &&
- git-svn init --minimize-url -R argh -i dir $svnrepo/mirror/argh &&
+ svnadmin load -q '$rawsvnrepo' < ../t9110/svm.dump &&
+ git-svn init --minimize-url -R arr -i bar '$svnrepo/mirror/arr' &&
+ git-svn init --minimize-url -R argh -i dir '$svnrepo/mirror/argh' &&
git-svn init --minimize-url -R argh -i e \
- $svnrepo/mirror/argh/a/b/c/d/e &&
+ '$svnrepo/mirror/argh/a/b/c/d/e' &&
git config svn.useSvmProps true &&
git-svn fetch --all
"
diff --git a/t/t9111-git-svn-use-svnsync-props.sh b/t/t9111-git-svn-use-svnsync-props.sh
index ec7dedd..936f023 100755
--- a/t/t9111-git-svn-use-svnsync-props.sh
+++ b/t/t9111-git-svn-use-svnsync-props.sh
@@ -8,10 +8,10 @@ test_description='git-svn useSvnsyncProps test'
. ./lib-git-svn.sh
test_expect_success 'load svnsync repo' "
- svnadmin load -q $rawsvnrepo < ../t9111/svnsync.dump &&
- git-svn init --minimize-url -R arr -i bar $svnrepo/bar &&
- git-svn init --minimize-url -R argh -i dir $svnrepo/dir &&
- git-svn init --minimize-url -R argh -i e $svnrepo/dir/a/b/c/d/e &&
+ svnadmin load -q '$rawsvnrepo' < ../t9111/svnsync.dump &&
+ git-svn init --minimize-url -R arr -i bar '$svnrepo/bar' &&
+ git-svn init --minimize-url -R argh -i dir '$svnrepo/dir' &&
+ git-svn init --minimize-url -R argh -i e '$svnrepo/dir/a/b/c/d/e' &&
git config svn.useSvnsyncProps true &&
git-svn fetch --all
"
diff --git a/t/t9112-git-svn-md5less-file.sh b/t/t9112-git-svn-md5less-file.sh
index 08313bb..b095583 100755
--- a/t/t9112-git-svn-md5less-file.sh
+++ b/t/t9112-git-svn-md5less-file.sh
@@ -38,8 +38,8 @@ PROPS-END
EOF
-test_expect_success 'load svn dumpfile' "svnadmin load $rawsvnrepo < dumpfile.svn"
+test_expect_success 'load svn dumpfile' "svnadmin load '$rawsvnrepo' < dumpfile.svn"
-test_expect_success 'initialize git-svn' "git-svn init $svnrepo"
+test_expect_success 'initialize git-svn' "git-svn init '$svnrepo'"
test_expect_success 'fetch revisions from svn' 'git-svn fetch'
test_done
diff --git a/t/t9113-git-svn-dcommit-new-file.sh b/t/t9113-git-svn-dcommit-new-file.sh
index 9ef0db9..0088c75 100755
--- a/t/t9113-git-svn-dcommit-new-file.sh
+++ b/t/t9113-git-svn-dcommit-new-file.sh
@@ -15,14 +15,14 @@ test_description='git-svn dcommit new files over svn:// test'
start_svnserve () {
svnserve --listen-port $SVNSERVE_PORT \
- --root $rawsvnrepo \
+ --root '$rawsvnrepo' \
--listen-once \
--listen-host 127.0.0.1 &
}
test_expect_success 'start tracking an empty repo' "
- svn mkdir -m 'empty dir' $svnrepo/empty-dir &&
- echo anon-access = write >> $rawsvnrepo/conf/svnserve.conf &&
+ svn mkdir -m 'empty dir' '$svnrepo/empty-dir' &&
+ echo anon-access = write >> '$rawsvnrepo/conf/svnserve.conf' &&
start_svnserve &&
git svn init svn://127.0.0.1:$SVNSERVE_PORT &&
git svn fetch
diff --git a/t/t9114-git-svn-dcommit-merge.sh b/t/t9114-git-svn-dcommit-merge.sh
index d6ca955..64ec7fd 100755
--- a/t/t9114-git-svn-dcommit-merge.sh
+++ b/t/t9114-git-svn-dcommit-merge.sh
@@ -35,7 +35,7 @@ EOF
}
test_expect_success 'setup svn repository' "
- svn co $svnrepo mysvnwork &&
+ svn co '$svnrepo' mysvnwork &&
mkdir -p mysvnwork/trunk &&
cd mysvnwork &&
big_text_block >> trunk/README &&
@@ -45,7 +45,7 @@ test_expect_success 'setup svn repository' "
"
test_expect_success 'setup git mirror and merge' "
- git svn init $svnrepo -t tags -T trunk -b branches &&
+ git svn init '$svnrepo' -t tags -T trunk -b branches &&
git svn fetch &&
git checkout --track -b svn remotes/trunk &&
git checkout -b merge &&
diff --git a/t/t9115-git-svn-dcommit-funky-renames.sh b/t/t9115-git-svn-dcommit-funky-renames.sh
index 182299c..653578d 100755
--- a/t/t9115-git-svn-dcommit-funky-renames.sh
+++ b/t/t9115-git-svn-dcommit-funky-renames.sh
@@ -8,12 +8,12 @@ test_description='git-svn dcommit can commit renames of files with ugly names'
. ./lib-git-svn.sh
test_expect_success 'load repository with strange names' "
- svnadmin load -q $rawsvnrepo < ../t9115/funky-names.dump &&
+ svnadmin load -q '$rawsvnrepo' < ../t9115/funky-names.dump &&
start_httpd
"
test_expect_success 'init and fetch repository' "
- git svn init $svnrepo &&
+ git svn init '$svnrepo' &&
git svn fetch &&
git reset --hard git-svn
"
diff --git a/t/t9116-git-svn-log.sh b/t/t9116-git-svn-log.sh
index 0d4e6b3..70c0c5f 100755
--- a/t/t9116-git-svn-log.sh
+++ b/t/t9116-git-svn-log.sh
@@ -14,9 +14,9 @@ test_expect_success 'setup repository and import' "
mkdir -p \$i && \
echo hello >> \$i/README || exit 1
done && \
- svn import -m test . $svnrepo
+ svn import -m test . '$svnrepo'
cd .. &&
- git-svn init $svnrepo -T trunk -b branches -t tags &&
+ git-svn init '$svnrepo' -T trunk -b branches -t tags &&
git-svn fetch &&
git reset --hard trunk &&
echo bye >> README &&
diff --git a/t/t9500-gitweb-standalone-no-errors.sh b/t/t9500-gitweb-standalone-no-errors.sh
index 642b836..b90e78c 100755
--- a/t/t9500-gitweb-standalone-no-errors.sh
+++ b/t/t9500-gitweb-standalone-no-errors.sh
@@ -45,13 +45,13 @@ gitweb_run () {
export QUERY_STRING=""$1""
export PATH_INFO=""$2""
- export GITWEB_CONFIG=$(pwd)/gitweb_config.perl
+ export GITWEB_CONFIG="$(pwd)/gitweb_config.perl"
# some of git commands write to STDERR on error, but this is not
# written to web server logs, so we are not interested in that:
# we are interested only in properly formatted errors/warnings
rm -f gitweb.log &&
- perl -- $(pwd)/../../gitweb/gitweb.perl \
+ perl -- "$(pwd)/../../gitweb/gitweb.perl" \
>/dev/null 2>gitweb.log &&
if grep -q -s "^[[]" gitweb.log >/dev/null; then false; else true; fi
diff --git a/t/test-lib.sh b/t/test-lib.sh
index cc1253c..a68415f 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -229,7 +229,7 @@ test_create_repo () {
repo="$1"
mkdir "$repo"
cd "$repo" || error "Cannot setup test environment"
- "$GIT_EXEC_PATH/git" init --template=$GIT_EXEC_PATH/templates/blt/ >/dev/null 2>&1 ||
+ "$GIT_EXEC_PATH/git" init --template="$GIT_EXEC_PATH/templates/blt/" >/dev/null 2>&1 ||
error "cannot run git init -- have you built things yet?"
mv .git/hooks .git/hooks-disabled
cd "$owd"
--
1.5.3.1
^ permalink raw reply related [relevance 7%]
* RE: Is there any plan to support partial checkout or submoudule improvement?
@ 2007-10-16 9:56 4% ` franky
0 siblings, 0 replies; 200+ results
From: franky @ 2007-10-16 9:56 UTC (permalink / raw)
To: 'Lars Hjemli'; +Cc: git
> Well, there is always
>
> $ git archive --remote=<repo> <revspec> <path> | tar -x
>
> This is effectively a partial checkout of an arbitrary revision from a
> remote repo.
>
> --
That's actually "a single command", but a little complex. And there still
are some problems with this single command
1. each time is full checkout (not incremental), so bad performance for
large bin directory
2. I can't know deployment version easily and I can't use "git-log" to see
the log and to decide which version to back to when necessary.
I just find an ugly resolution:
1. git-clone host:project.git project
Cloned project is as follows (src, bin are subdir instead of submodule)
project
src
bin
.git
2. cd project && rm -rf src
3. when project.git changed, then
git-fetch && git-checkout origin/master bin
Unfortulately, it's annoying when I run git-status which complains "deleted:
src ". And "git-log" will not show the newest log since git-checkout doesn't
update the index file
So, the alternative for the 3rd step is
git-pull && rm src
It's so ugly!
Suggestion 1: how about adding a paths option for git-status just like
git-diff and git-log
Suggestion 2: how about changes the default paths for "git-diff", "git-log"
and so on from the "top dir with .git" to "the current dir"? So when I'm in
bin directory and run "git-log", it will only report log or diff in bin
directory.
franky
^ permalink raw reply [relevance 4%]
* [PATCH 2/2] Quoting paths in tests
@ 2007-10-17 9:31 6% ` Jonathan del Strother
0 siblings, 0 replies; 200+ results
From: Jonathan del Strother @ 2007-10-17 9:31 UTC (permalink / raw)
To: git; +Cc: Jonathan del Strother
From: Jonathan del Strother <jon.delStrother@bestbefore.tv>
Double-quoting all paths so the tests can be run from inside directories with spaces and apostrophes
Signed-off-by: Jonathan del Strother <jon.delStrother@bestbefore.tv>
---
t/lib-git-svn.sh | 2 +-
t/t1020-subdirectory.sh | 22 ++++++------
t/t3050-subprojects-fetch.sh | 2 +-
t/t3404-rebase-interactive.sh | 2 +-
t/t5500-fetch-pack.sh | 2 +-
t/t5700-clone-reference.sh | 2 +-
t/t7003-filter-branch.sh | 2 +-
t/t7501-commit.sh | 4 +-
t/t9100-git-svn-basic.sh | 54 +++++++++++++++---------------
t/t9101-git-svn-props.sh | 6 ++--
t/t9102-git-svn-deep-rmdir.sh | 6 ++--
t/t9104-git-svn-follow-parent.sh | 50 ++++++++++++++--------------
t/t9105-git-svn-commit-diff.sh | 12 +++---
t/t9106-git-svn-commit-diff-clobber.sh | 14 ++++----
t/t9107-git-svn-migrate.sh | 40 +++++++++++-----------
t/t9108-git-svn-glob.sh | 8 ++--
t/t9110-git-svn-use-svm-props.sh | 8 ++--
t/t9111-git-svn-use-svnsync-props.sh | 8 ++--
t/t9112-git-svn-md5less-file.sh | 4 +-
t/t9113-git-svn-dcommit-new-file.sh | 6 ++--
t/t9114-git-svn-dcommit-merge.sh | 4 +-
t/t9115-git-svn-dcommit-funky-renames.sh | 4 +-
t/t9116-git-svn-log.sh | 4 +-
t/t9500-gitweb-standalone-no-errors.sh | 4 +-
t/test-lib.sh | 2 +-
25 files changed, 136 insertions(+), 136 deletions(-)
diff --git a/t/lib-git-svn.sh b/t/lib-git-svn.sh
index 8d4a447..cde3053 100644
--- a/t/lib-git-svn.sh
+++ b/t/lib-git-svn.sh
@@ -25,7 +25,7 @@ perl -w -e "
use SVN::Core;
use SVN::Repos;
\$SVN::Core::VERSION gt '1.1.0' or exit(42);
-system(qw/svnadmin create --fs-type fsfs/, '$svnrepo') == 0 or exit(41);
+system(qw/svnadmin create --fs-type fsfs/, \"$svnrepo\") == 0 or exit(41);
" >&3 2>&4
x=$?
if test $x -ne 0
diff --git a/t/t1020-subdirectory.sh b/t/t1020-subdirectory.sh
index b9cef34..5ed7fa4 100755
--- a/t/t1020-subdirectory.sh
+++ b/t/t1020-subdirectory.sh
@@ -21,7 +21,7 @@ LF='
'
test_expect_success 'update-index and ls-files' '
- cd $HERE &&
+ cd "$HERE" &&
git update-index --add one &&
case "`git ls-files`" in
one) echo ok one ;;
@@ -41,7 +41,7 @@ test_expect_success 'update-index and ls-files' '
'
test_expect_success 'cat-file' '
- cd $HERE &&
+ cd "$HERE" &&
two=`git ls-files -s dir/two` &&
two=`expr "$two" : "[0-7]* \\([0-9a-f]*\\)"` &&
echo "$two" &&
@@ -54,7 +54,7 @@ test_expect_success 'cat-file' '
rm -f actual dir/actual
test_expect_success 'diff-files' '
- cd $HERE &&
+ cd "$HERE" &&
echo a >>one &&
echo d >>dir/two &&
case "`git diff-files --name-only`" in
@@ -74,7 +74,7 @@ test_expect_success 'diff-files' '
'
test_expect_success 'write-tree' '
- cd $HERE &&
+ cd "$HERE" &&
top=`git write-tree` &&
echo $top &&
cd dir &&
@@ -84,7 +84,7 @@ test_expect_success 'write-tree' '
'
test_expect_success 'checkout-index' '
- cd $HERE &&
+ cd "$HERE" &&
git checkout-index -f -u one &&
cmp one original.one &&
cd dir &&
@@ -93,7 +93,7 @@ test_expect_success 'checkout-index' '
'
test_expect_success 'read-tree' '
- cd $HERE &&
+ cd "$HERE" &&
rm -f one dir/two &&
tree=`git write-tree` &&
git read-tree --reset -u "$tree" &&
@@ -107,27 +107,27 @@ test_expect_success 'read-tree' '
'
test_expect_success 'no file/rev ambiguity check inside .git' '
- cd $HERE &&
+ cd "$HERE" &&
git commit -a -m 1 &&
- cd $HERE/.git &&
+ cd "$HERE/.git" &&
git show -s HEAD
'
test_expect_success 'no file/rev ambiguity check inside a bare repo' '
- cd $HERE &&
+ cd "$HERE" &&
git clone -s --bare .git foo.git &&
cd foo.git && GIT_DIR=. git show -s HEAD
'
# This still does not work as it should...
: test_expect_success 'no file/rev ambiguity check inside a bare repo' '
- cd $HERE &&
+ cd "$HERE" &&
git clone -s --bare .git foo.git &&
cd foo.git && git show -s HEAD
'
test_expect_success 'detection should not be fooled by a symlink' '
- cd $HERE &&
+ cd "$HERE" &&
rm -fr foo.git &&
git clone -s .git another &&
ln -s another yetanother &&
diff --git a/t/t3050-subprojects-fetch.sh b/t/t3050-subprojects-fetch.sh
index 34f26a8..4b74cc6 100755
--- a/t/t3050-subprojects-fetch.sh
+++ b/t/t3050-subprojects-fetch.sh
@@ -20,7 +20,7 @@ test_expect_success setup '
'
test_expect_success clone '
- git clone file://`pwd`/.git cloned &&
+ git clone "file://`pwd`/.git" cloned &&
(git rev-parse HEAD; git ls-files -s) >expected &&
(
cd cloned &&
diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh
index 1113904..aa86042 100755
--- a/t/t3404-rebase-interactive.sh
+++ b/t/t3404-rebase-interactive.sh
@@ -92,7 +92,7 @@ done
EOF
chmod a+x fake-editor.sh
-VISUAL="$(pwd)/fake-editor.sh"
+VISUAL="\"$(pwd)/fake-editor.sh\""
export VISUAL
test_expect_success 'no changes are a nop' '
diff --git a/t/t5500-fetch-pack.sh b/t/t5500-fetch-pack.sh
index 7b6798d..5489ffe 100755
--- a/t/t5500-fetch-pack.sh
+++ b/t/t5500-fetch-pack.sh
@@ -129,7 +129,7 @@ pull_to_client 2nd "B" $((64*3))
pull_to_client 3rd "A" $((1*3)) # old fails
-test_expect_success "clone shallow" "git-clone --depth 2 file://`pwd`/. shallow"
+test_expect_success "clone shallow" "git-clone --depth 2 \"file://`pwd`/.\" shallow"
(cd shallow; git count-objects -v) > count.shallow
diff --git a/t/t5700-clone-reference.sh b/t/t5700-clone-reference.sh
index 4e93aaa..8bb34f9 100755
--- a/t/t5700-clone-reference.sh
+++ b/t/t5700-clone-reference.sh
@@ -51,7 +51,7 @@ diff expected current'
cd "$base_dir"
test_expect_success 'cloning with reference (no -l -s)' \
-'git clone --reference B file://`pwd`/A D'
+'git clone --reference B "file://`pwd`/A" D'
cd "$base_dir"
diff --git a/t/t7003-filter-branch.sh b/t/t7003-filter-branch.sh
index e935b20..1ab5392 100755
--- a/t/t7003-filter-branch.sh
+++ b/t/t7003-filter-branch.sh
@@ -107,7 +107,7 @@ test_expect_success 'use index-filter to move into a subdirectory' '
"git ls-files -s | sed \"s-\\t-&newsubdir/-\" |
GIT_INDEX_FILE=\$GIT_INDEX_FILE.new \
git update-index --index-info &&
- mv \$GIT_INDEX_FILE.new \$GIT_INDEX_FILE" directorymoved &&
+ mv \"\$GIT_INDEX_FILE.new\" \"\$GIT_INDEX_FILE\"" directorymoved &&
test -z "$(git diff HEAD directorymoved:newsubdir)"'
test_expect_success 'stops when msg filter fails' '
diff --git a/t/t7501-commit.sh b/t/t7501-commit.sh
index b151b51..e97e756 100644
--- a/t/t7501-commit.sh
+++ b/t/t7501-commit.sh
@@ -69,7 +69,7 @@ test_expect_success \
cat >editor <<\EOF
#!/bin/sh
-sed -i -e "s/a file/an amend commit/g" $1
+sed -i -e "s/a file/an amend commit/g" "$1"
EOF
chmod 755 editor
@@ -88,7 +88,7 @@ test_expect_success \
cat >editor <<\EOF
#!/bin/sh
-sed -i -e "s/amend/older/g" $1
+sed -i -e "s/amend/older/g" "$1"
EOF
chmod 755 editor
diff --git a/t/t9100-git-svn-basic.sh b/t/t9100-git-svn-basic.sh
index 614cf50..1d802a8 100755
--- a/t/t9100-git-svn-basic.sh
+++ b/t/t9100-git-svn-basic.sh
@@ -31,16 +31,16 @@ test_expect_success \
echo 'zzz' > bar/zzz &&
echo '#!/bin/sh' > exec.sh &&
chmod +x exec.sh &&
- svn import -m 'import for git-svn' . $svnrepo >/dev/null &&
+ svn import -m 'import for git-svn' . \"$svnrepo\" >/dev/null &&
cd .. &&
rm -rf import &&
- git-svn init $svnrepo"
+ git-svn init \"$svnrepo\""
test_expect_success \
'import an SVN revision into git' \
'git-svn fetch'
-test_expect_success "checkout from svn" "svn co $svnrepo '$SVN_TREE'"
+test_expect_success "checkout from svn" "svn co \"$svnrepo\" \"$SVN_TREE\""
name='try a deep --rmdir with a commit'
test_expect_success "$name" "
@@ -51,8 +51,8 @@ test_expect_success "$name" "
git commit -m '$name' &&
git-svn set-tree --find-copies-harder --rmdir \
remotes/git-svn..mybranch &&
- svn up '$SVN_TREE' &&
- test -d '$SVN_TREE'/dir && test ! -d '$SVN_TREE'/dir/a"
+ svn up \"$SVN_TREE\" &&
+ test -d \"$SVN_TREE\"/dir && test ! -d \"$SVN_TREE\"/dir/a"
name='detect node change from file to directory #1'
@@ -69,7 +69,7 @@ test_expect_failure "$name" "
name='detect node change from directory to file #1'
test_expect_failure "$name" "
- rm -rf dir '$GIT_DIR'/index &&
+ rm -rf dir \"$GIT_DIR\"/index &&
git checkout -f -b mybranch2 remotes/git-svn &&
mv bar/zzz zzz &&
rm -rf bar &&
@@ -83,7 +83,7 @@ test_expect_failure "$name" "
name='detect node change from file to directory #2'
test_expect_failure "$name" "
- rm -f '$GIT_DIR'/index &&
+ rm -f \"$GIT_DIR\"/index &&
git checkout -f -b mybranch3 remotes/git-svn &&
rm bar/zzz &&
git update-index --remove bar/zzz &&
@@ -97,7 +97,7 @@ test_expect_failure "$name" "
name='detect node change from directory to file #2'
test_expect_failure "$name" "
- rm -f '$GIT_DIR'/index &&
+ rm -f \"$GIT_DIR\"/index &&
git checkout -f -b mybranch4 remotes/git-svn &&
rm -rf dir &&
git update-index --remove -- dir/file &&
@@ -111,15 +111,15 @@ test_expect_failure "$name" "
name='remove executable bit from a file'
test_expect_success "$name" "
- rm -f '$GIT_DIR'/index &&
+ rm -f \"$GIT_DIR\"/index &&
git checkout -f -b mybranch5 remotes/git-svn &&
chmod -x exec.sh &&
git update-index exec.sh &&
git commit -m '$name' &&
git-svn set-tree --find-copies-harder --rmdir \
remotes/git-svn..mybranch5 &&
- svn up '$SVN_TREE' &&
- test ! -x '$SVN_TREE'/exec.sh"
+ svn up \"$SVN_TREE\" &&
+ test ! -x \"$SVN_TREE\"/exec.sh"
name='add executable bit back file'
@@ -129,8 +129,8 @@ test_expect_success "$name" "
git commit -m '$name' &&
git-svn set-tree --find-copies-harder --rmdir \
remotes/git-svn..mybranch5 &&
- svn up '$SVN_TREE' &&
- test -x '$SVN_TREE'/exec.sh"
+ svn up \"$SVN_TREE\" &&
+ test -x \"$SVN_TREE\"/exec.sh"
name='executable file becomes a symlink to bar/zzz (file)'
@@ -141,8 +141,8 @@ test_expect_success "$name" "
git commit -m '$name' &&
git-svn set-tree --find-copies-harder --rmdir \
remotes/git-svn..mybranch5 &&
- svn up '$SVN_TREE' &&
- test -L '$SVN_TREE'/exec.sh"
+ svn up \"$SVN_TREE\" &&
+ test -L \"$SVN_TREE\"/exec.sh"
name='new symlink is added to a file that was also just made executable'
@@ -153,9 +153,9 @@ test_expect_success "$name" "
git commit -m '$name' &&
git-svn set-tree --find-copies-harder --rmdir \
remotes/git-svn..mybranch5 &&
- svn up '$SVN_TREE' &&
- test -x '$SVN_TREE'/bar/zzz &&
- test -L '$SVN_TREE'/exec-2.sh"
+ svn up \"$SVN_TREE\" &&
+ test -x \"$SVN_TREE\"/bar/zzz &&
+ test -L \"$SVN_TREE\"/exec-2.sh"
name='modify a symlink to become a file'
test_expect_success "$name" "
@@ -166,10 +166,10 @@ test_expect_success "$name" "
git commit -m '$name' &&
git-svn set-tree --find-copies-harder --rmdir \
remotes/git-svn..mybranch5 &&
- svn up '$SVN_TREE' &&
- test -f '$SVN_TREE'/exec-2.sh &&
- test ! -L '$SVN_TREE'/exec-2.sh &&
- git diff help $SVN_TREE/exec-2.sh"
+ svn up \"$SVN_TREE\" &&
+ test -f \"$SVN_TREE\"/exec-2.sh &&
+ test ! -L \"$SVN_TREE\"/exec-2.sh &&
+ git diff help \"$SVN_TREE\"/exec-2.sh"
if test "$have_utf8" = t
then
@@ -190,7 +190,7 @@ name='test fetch functionality (svn => git) with alternate GIT_SVN_ID'
GIT_SVN_ID=alt
export GIT_SVN_ID
test_expect_success "$name" \
- "git-svn init $svnrepo && git-svn fetch &&
+ "git-svn init \"$svnrepo\" && git-svn fetch &&
git rev-list --pretty=raw remotes/git-svn | grep ^tree | uniq > a &&
git rev-list --pretty=raw remotes/alt | grep ^tree | uniq > b &&
git diff a b"
@@ -220,16 +220,16 @@ test_expect_failure 'exit if remote refs are ambigious' "
"
test_expect_failure 'exit if init-ing a would clobber a URL' "
- svnadmin create ${PWD}/svnrepo2 &&
- svn mkdir -m 'mkdir bar' ${svnrepo}2/bar &&
+ svnadmin create \"${PWD}/svnrepo2\" &&
+ svn mkdir -m 'mkdir bar' \"${svnrepo}2/bar\" &&
git config --unset svn-remote.svn.fetch \
'^bar:refs/remotes/git-svn$' &&
- git-svn init ${svnrepo}2/bar
+ git-svn init \"${svnrepo}2/bar\"
"
test_expect_success \
'init allows us to connect to another directory in the same repo' "
- git-svn init --minimize-url -i bar $svnrepo/bar &&
+ git-svn init --minimize-url -i bar \"$svnrepo/bar\" &&
git config --get svn-remote.svn.fetch \
'^bar:refs/remotes/bar$' &&
git config --get svn-remote.svn.fetch \
diff --git a/t/t9101-git-svn-props.sh b/t/t9101-git-svn-props.sh
index 5aac644..e741bfe 100755
--- a/t/t9101-git-svn-props.sh
+++ b/t/t9101-git-svn-props.sh
@@ -52,7 +52,7 @@ EOF
cd ..
rm -rf import
-test_expect_success 'checkout working copy from svn' "svn co $svnrepo test_wc"
+test_expect_success 'checkout working copy from svn' "svn co \"$svnrepo\" test_wc"
test_expect_success 'setup some commits to svn' \
'cd test_wc &&
echo Greetings >> kw.c &&
@@ -66,7 +66,7 @@ test_expect_success 'setup some commits to svn' \
svn commit -m "Propset Id" &&
cd ..'
-test_expect_success 'initialize git-svn' "git-svn init $svnrepo"
+test_expect_success 'initialize git-svn' "git-svn init \"$svnrepo\""
test_expect_success 'fetch revisions from svn' 'git-svn fetch'
name='test svn:keywords ignoring'
@@ -92,7 +92,7 @@ test_expect_success "propset CR on crlf files" \
test_expect_success 'fetch and pull latest from svn and checkout a new wc' \
"git-svn fetch &&
git pull . remotes/git-svn &&
- svn co $svnrepo new_wc"
+ svn co \"$svnrepo\" new_wc"
for i in crlf ne_crlf lf ne_lf cr ne_cr empty_cr empty_lf empty empty_crlf
do
diff --git a/t/t9102-git-svn-deep-rmdir.sh b/t/t9102-git-svn-deep-rmdir.sh
index 4e08083..e3af319 100755
--- a/t/t9102-git-svn-deep-rmdir.sh
+++ b/t/t9102-git-svn-deep-rmdir.sh
@@ -9,12 +9,12 @@ test_expect_success 'initialize repo' "
mkdir -p deeply/nested/directory/number/2 &&
echo foo > deeply/nested/directory/number/1/file &&
echo foo > deeply/nested/directory/number/2/another &&
- svn import -m 'import for git-svn' . $svnrepo &&
+ svn import -m 'import for git-svn' . \"$svnrepo\" &&
cd ..
"
test_expect_success 'mirror via git-svn' "
- git-svn init $svnrepo &&
+ git-svn init \"$svnrepo\" &&
git-svn fetch &&
git checkout -f -b test-rmdir remotes/git-svn
"
@@ -23,7 +23,7 @@ test_expect_success 'Try a commit on rmdir' "
git rm -f deeply/nested/directory/number/2/another &&
git commit -a -m 'remove another' &&
git-svn set-tree --rmdir HEAD &&
- svn ls -R $svnrepo | grep ^deeply/nested/directory/number/1
+ svn ls -R \"$svnrepo\" | grep ^deeply/nested/directory/number/1
"
diff --git a/t/t9104-git-svn-follow-parent.sh b/t/t9104-git-svn-follow-parent.sh
index 7ba7630..a422afa 100755
--- a/t/t9104-git-svn-follow-parent.sh
+++ b/t/t9104-git-svn-follow-parent.sh
@@ -11,9 +11,9 @@ test_expect_success 'initialize repo' "
cd import &&
mkdir -p trunk &&
echo hello > trunk/readme &&
- svn import -m 'initial' . $svnrepo &&
+ svn import -m 'initial' . \"$svnrepo\" &&
cd .. &&
- svn co $svnrepo wc &&
+ svn co \"$svnrepo\" wc &&
cd wc &&
echo world >> trunk/readme &&
poke trunk/readme &&
@@ -27,7 +27,7 @@ test_expect_success 'initialize repo' "
"
test_expect_success 'init and fetch a moved directory' "
- git-svn init --minimize-url -i thunk $svnrepo/thunk &&
+ git-svn init --minimize-url -i thunk \"$svnrepo/thunk\" &&
git-svn fetch -i thunk &&
test \"\`git rev-parse --verify refs/remotes/thunk@2\`\" \
= \"\`git rev-parse --verify refs/remotes/thunk~1\`\" &&
@@ -38,7 +38,7 @@ test_expect_success 'init and fetch a moved directory' "
"
test_expect_success 'init and fetch from one svn-remote' "
- git config svn-remote.svn.url $svnrepo &&
+ git config svn-remote.svn.url \"$svnrepo\" &&
git config --add svn-remote.svn.fetch \
trunk:refs/remotes/svn/trunk &&
git config --add svn-remote.svn.fetch \
@@ -52,9 +52,9 @@ test_expect_success 'init and fetch from one svn-remote' "
test_expect_success 'follow deleted parent' "
(svn cp -m 'resurrecting trunk as junk' \
- $svnrepo/trunk@2 $svnrepo/junk ||
+ \"$svnrepo/trunk@2\" \"$svnrepo\"/junk ||
svn cp -m 'resurrecting trunk as junk' \
- -r2 $svnrepo/trunk $svnrepo/junk) &&
+ -r2 \"$svnrepo/trunk\" \"$svnrepo/junk\") &&
git config --add svn-remote.svn.fetch \
junk:refs/remotes/svn/junk &&
git-svn fetch -i svn/thunk &&
@@ -67,10 +67,10 @@ test_expect_success 'follow deleted parent' "
test_expect_success 'follow larger parent' "
mkdir -p import/trunk/thunk/bump/thud &&
echo hi > import/trunk/thunk/bump/thud/file &&
- svn import -m 'import a larger parent' import $svnrepo/larger-parent &&
- svn cp -m 'hi' $svnrepo/larger-parent $svnrepo/another-larger &&
+ svn import -m 'import a larger parent' import \"$svnrepo/larger-parent\" &&
+ svn cp -m 'hi' \"$svnrepo/larger-parent\" \"$svnrepo/another-larger\" &&
git-svn init --minimize-url -i larger \
- $svnrepo/another-larger/trunk/thunk/bump/thud &&
+ \"$svnrepo/another-larger/trunk/thunk/bump/thud\" &&
git-svn fetch -i larger &&
git rev-parse --verify refs/remotes/larger &&
git rev-parse --verify \
@@ -83,23 +83,23 @@ test_expect_success 'follow larger parent' "
"
test_expect_success 'follow higher-level parent' "
- svn mkdir -m 'follow higher-level parent' $svnrepo/blob &&
- svn co $svnrepo/blob blob &&
+ svn mkdir -m 'follow higher-level parent' \"$svnrepo/blob\" &&
+ svn co \"$svnrepo/blob\" blob &&
cd blob &&
echo hi > hi &&
svn add hi &&
svn commit -m 'hihi' &&
cd ..
- svn mkdir -m 'new glob at top level' $svnrepo/glob &&
- svn mv -m 'move blob down a level' $svnrepo/blob $svnrepo/glob/blob &&
- git-svn init --minimize-url -i blob $svnrepo/glob/blob &&
+ svn mkdir -m 'new glob at top level' \"$svnrepo/glob\" &&
+ svn mv -m 'move blob down a level' \"$svnrepo/blob\" \"$svnrepo/glob/blob\" &&
+ git-svn init --minimize-url -i blob \"$svnrepo/glob/blob\" &&
git-svn fetch -i blob
"
test_expect_success 'follow deleted directory' "
- svn mv -m 'bye!' $svnrepo/glob/blob/hi $svnrepo/glob/blob/bye &&
- svn rm -m 'remove glob' $svnrepo/glob &&
- git-svn init --minimize-url -i glob $svnrepo/glob &&
+ svn mv -m 'bye!' \"$svnrepo/glob/blob/hi\" \"$svnrepo/glob/blob/bye\" &&
+ svn rm -m 'remove glob' \"$svnrepo/glob\" &&
+ git-svn init --minimize-url -i glob \"$svnrepo/glob\" &&
git-svn fetch -i glob &&
test \"\`git cat-file blob refs/remotes/glob:blob/bye\`\" = hi &&
test \"\`git ls-tree refs/remotes/glob | wc -l \`\" -eq 1
@@ -118,9 +118,9 @@ test_expect_success 'follow-parent avoids deleting relevant info' "
echo 'bad delete test 2' > \
import/trunk/subversion/bindings/swig/perl/another-larger &&
cd import &&
- svn import -m 'r9270 test' . $svnrepo/r9270 &&
+ svn import -m 'r9270 test' . \"$svnrepo/r9270\" &&
cd .. &&
- svn co $svnrepo/r9270/trunk/subversion/bindings/swig/perl r9270 &&
+ svn co \"$svnrepo/r9270/trunk/subversion/bindings/swig/perl\" r9270 &&
cd r9270 &&
svn mkdir native &&
svn mv t native/t &&
@@ -130,7 +130,7 @@ test_expect_success 'follow-parent avoids deleting relevant info' "
svn commit -m 'reorg test' &&
cd .. &&
git-svn init --minimize-url -i r9270-t \
- $svnrepo/r9270/trunk/subversion/bindings/swig/perl/native/t &&
+ \"$svnrepo/r9270/trunk/subversion/bindings/swig/perl/native/t\" &&
git-svn fetch -i r9270-t &&
test \`git rev-list r9270-t | wc -l\` -eq 2 &&
test \"\`git ls-tree --name-only r9270-t~1\`\" = \
@@ -138,9 +138,9 @@ test_expect_success 'follow-parent avoids deleting relevant info' "
"
test_expect_success "track initial change if it was only made to parent" "
- svn cp -m 'wheee!' $svnrepo/r9270/trunk $svnrepo/r9270/drunk &&
+ svn cp -m 'wheee!' \"$svnrepo/r9270/trunk\" \"$svnrepo/r9270/drunk\" &&
git-svn init --minimize-url -i r9270-d \
- $svnrepo/r9270/drunk/subversion/bindings/swig/perl/native/t &&
+ \"$svnrepo/r9270/drunk/subversion/bindings/swig/perl/native/t\" &&
git-svn fetch -i r9270-d &&
test \`git rev-list r9270-d | wc -l\` -eq 3 &&
test \"\`git ls-tree --name-only r9270-t\`\" = \
@@ -150,7 +150,7 @@ test_expect_success "track initial change if it was only made to parent" "
"
test_expect_success "track multi-parent paths" "
- svn cp -m 'resurrect /glob' $svnrepo/r9270 $svnrepo/glob &&
+ svn cp -m 'resurrect /glob' \"$svnrepo/r9270\" \"$svnrepo/glob\" &&
git-svn multi-fetch &&
test \`git cat-file commit refs/remotes/glob | \
grep '^parent ' | wc -l\` -eq 2
@@ -161,8 +161,8 @@ test_expect_success "multi-fetch continues to work" "
"
test_expect_success "multi-fetch works off a 'clean' repository" "
- rm -r $GIT_DIR/svn $GIT_DIR/refs/remotes $GIT_DIR/logs &&
- mkdir $GIT_DIR/svn &&
+ rm -r \"$GIT_DIR/svn\" \"$GIT_DIR/refs/remotes\" \"$GIT_DIR/logs\" &&
+ mkdir \"$GIT_DIR/svn\" &&
git-svn multi-fetch
"
diff --git a/t/t9105-git-svn-commit-diff.sh b/t/t9105-git-svn-commit-diff.sh
index 318e172..9cc38d3 100755
--- a/t/t9105-git-svn-commit-diff.sh
+++ b/t/t9105-git-svn-commit-diff.sh
@@ -8,7 +8,7 @@ test_expect_success 'initialize repo' "
mkdir import &&
cd import &&
echo hello > readme &&
- svn import -m 'initial' . $svnrepo &&
+ svn import -m 'initial' . \"$svnrepo\" &&
cd .. &&
echo hello > readme &&
git update-index --add readme &&
@@ -26,17 +26,17 @@ prev=`git rev-parse --verify HEAD^1`
test_expect_success 'test the commit-diff command' "
test -n '$prev' && test -n '$head' &&
- git-svn commit-diff -r1 '$prev' '$head' '$svnrepo' &&
- svn co $svnrepo wc &&
+ git-svn commit-diff -r1 '$prev' '$head' \"$svnrepo\" &&
+ svn co \"$svnrepo\" wc &&
cmp readme wc/readme
"
test_expect_success 'commit-diff to a sub-directory (with git-svn config)' "
- svn import -m 'sub-directory' import $svnrepo/subdir &&
- git-svn init --minimize-url $svnrepo/subdir &&
+ svn import -m 'sub-directory' import \"$svnrepo/subdir\" &&
+ git-svn init --minimize-url \"$svnrepo/subdir\" &&
git-svn fetch &&
git-svn commit-diff -r3 '$prev' '$head' &&
- svn cat $svnrepo/subdir/readme > readme.2 &&
+ svn cat \"$svnrepo/subdir/readme\" > readme.2 &&
cmp readme readme.2
"
diff --git a/t/t9106-git-svn-commit-diff-clobber.sh b/t/t9106-git-svn-commit-diff-clobber.sh
index 79b7968..892ca55 100755
--- a/t/t9106-git-svn-commit-diff-clobber.sh
+++ b/t/t9106-git-svn-commit-diff-clobber.sh
@@ -8,14 +8,14 @@ test_expect_success 'initialize repo' "
mkdir import &&
cd import &&
echo initial > file &&
- svn import -m 'initial' . $svnrepo &&
+ svn import -m 'initial' . \"$svnrepo\" &&
cd .. &&
echo initial > file &&
git update-index --add file &&
git commit -a -m 'initial'
"
test_expect_success 'commit change from svn side' "
- svn co $svnrepo t.svn &&
+ svn co \"$svnrepo\" t.svn &&
cd t.svn &&
echo second line from svn >> file &&
poke file &&
@@ -27,7 +27,7 @@ test_expect_success 'commit change from svn side' "
test_expect_failure 'commit conflicting change from git' "
echo second line from git >> file &&
git commit -a -m 'second line from git' &&
- git-svn commit-diff -r1 HEAD~1 HEAD $svnrepo
+ git-svn commit-diff -r1 HEAD~1 HEAD \"$svnrepo\"
" || true
test_expect_success 'commit complementing change from git' "
@@ -36,14 +36,14 @@ test_expect_success 'commit complementing change from git' "
git commit -a -m 'second line from svn' &&
echo third line from git >> file &&
git commit -a -m 'third line from git' &&
- git-svn commit-diff -r2 HEAD~1 HEAD $svnrepo
+ git-svn commit-diff -r2 HEAD~1 HEAD \"$svnrepo\"
"
test_expect_failure 'dcommit fails to commit because of conflict' "
- git-svn init $svnrepo &&
+ git-svn init \"$svnrepo\" &&
git-svn fetch &&
git reset --hard refs/remotes/git-svn &&
- svn co $svnrepo t.svn &&
+ svn co \"$svnrepo\" t.svn &&
cd t.svn &&
echo fourth line from svn >> file &&
poke file &&
@@ -67,7 +67,7 @@ test_expect_success 'dcommit does the svn equivalent of an index merge' "
"
test_expect_success 'commit another change from svn side' "
- svn co $svnrepo t.svn &&
+ svn co \"$svnrepo\" t.svn &&
cd t.svn &&
echo third line from svn >> file &&
poke file &&
diff --git a/t/t9107-git-svn-migrate.sh b/t/t9107-git-svn-migrate.sh
index 67fdf70..59e8f0d 100755
--- a/t/t9107-git-svn-migrate.sh
+++ b/t/t9107-git-svn-migrate.sh
@@ -4,7 +4,7 @@ test_description='git-svn metadata migrations from previous versions'
. ./lib-git-svn.sh
test_expect_success 'setup old-looking metadata' "
- cp $GIT_DIR/config $GIT_DIR/config-old-git-svn &&
+ cp \"$GIT_DIR/config\" \"$GIT_DIR/config-old-git-svn\" &&
mkdir import &&
cd import &&
for i in trunk branches/a branches/b \
@@ -12,13 +12,13 @@ test_expect_success 'setup old-looking metadata' "
mkdir -p \$i && \
echo hello >> \$i/README || exit 1
done && \
- svn import -m test . $svnrepo
+ svn import -m test . \"$svnrepo\"
cd .. &&
- git-svn init $svnrepo &&
+ git-svn init \"$svnrepo\" &&
git-svn fetch &&
- mv $GIT_DIR/svn/* $GIT_DIR/ &&
- mv $GIT_DIR/svn/.metadata $GIT_DIR/ &&
- rmdir $GIT_DIR/svn &&
+ mv \"$GIT_DIR\"/svn/* \"$GIT_DIR/\" &&
+ mv \"$GIT_DIR/svn/.metadata\" \"$GIT_DIR/\" &&
+ rmdir \"$GIT_DIR/svn\" &&
git update-ref refs/heads/git-svn-HEAD refs/remotes/git-svn &&
git update-ref refs/heads/svn-HEAD refs/remotes/git-svn &&
git update-ref -d refs/remotes/git-svn refs/remotes/git-svn
@@ -28,20 +28,20 @@ head=`git rev-parse --verify refs/heads/git-svn-HEAD^0`
test_expect_success 'git-svn-HEAD is a real HEAD' "test -n '$head'"
test_expect_success 'initialize old-style (v0) git-svn layout' "
- mkdir -p $GIT_DIR/git-svn/info $GIT_DIR/svn/info &&
- echo $svnrepo > $GIT_DIR/git-svn/info/url &&
- echo $svnrepo > $GIT_DIR/svn/info/url &&
+ mkdir -p \"$GIT_DIR/git-svn/info\" \"$GIT_DIR/svn/info\" &&
+ echo \"$svnrepo\" > \"$GIT_DIR/git-svn/info/url\" &&
+ echo \"$svnrepo\" > \"$GIT_DIR/svn/info/url\" &&
git-svn migrate &&
- ! test -d $GIT_DIR/git-svn &&
+ ! test -d \"$GIT_DIR/git-svn\" &&
git rev-parse --verify refs/remotes/git-svn^0 &&
git rev-parse --verify refs/remotes/svn^0 &&
- test \`git config --get svn-remote.svn.url\` = '$svnrepo' &&
+ test \"\`git config --get svn-remote.svn.url\`\" = \"$svnrepo\" &&
test \`git config --get svn-remote.svn.fetch\` = \
':refs/remotes/git-svn'
"
test_expect_success 'initialize a multi-repository repo' "
- git-svn init $svnrepo -T trunk -t tags -b branches &&
+ git-svn init \"$svnrepo\" -T trunk -t tags -b branches &&
git config --get-all svn-remote.svn.fetch > fetch.out &&
grep '^trunk:refs/remotes/trunk$' fetch.out &&
test -n \"\`git config --get svn-remote.svn.branches \
@@ -76,14 +76,14 @@ test_expect_success 'multi-fetch works on partial urls + paths' "
test_expect_success 'migrate --minimize on old inited layout' "
git config --unset-all svn-remote.svn.fetch &&
git config --unset-all svn-remote.svn.url &&
- rm -rf $GIT_DIR/svn &&
+ rm -rf \"$GIT_DIR/svn\" &&
for i in \`cat fetch.out\`; do
path=\`expr \$i : '\\([^:]*\\):.*$'\`
ref=\`expr \$i : '[^:]*:refs/remotes/\\(.*\\)$'\`
if test -z \"\$ref\"; then continue; fi
if test -n \"\$path\"; then path=\"/\$path\"; fi
- ( mkdir -p $GIT_DIR/svn/\$ref/info/ &&
- echo $svnrepo\$path > $GIT_DIR/svn/\$ref/info/url ) || exit 1;
+ ( mkdir -p \"$GIT_DIR\"/svn/\$ref/info/ &&
+ echo \"$svnrepo\"\$path > \"$GIT_DIR\"/svn/\$ref/info/url ) || exit 1;
done &&
git-svn migrate --minimize &&
test -z \"\`git config -l |grep -v '^svn-remote\.git-svn\.'\`\" &&
@@ -99,13 +99,13 @@ test_expect_success 'migrate --minimize on old inited layout' "
test_expect_success ".rev_db auto-converted to .rev_db.UUID" "
git-svn fetch -i trunk &&
- expect=$GIT_DIR/svn/trunk/.rev_db.* &&
+ expect=\"\`find \"\$GIT_DIR\"/svn/trunk/ -name '.rev_db.*'\`\" &&
test -n \"\$expect\" &&
- mv \$expect $GIT_DIR/svn/trunk/.rev_db &&
+ mv \"\$expect\" \"\$GIT_DIR\"/svn/trunk/.rev_db &&
git-svn fetch -i trunk &&
- test -L $GIT_DIR/svn/trunk/.rev_db &&
- test -f \$expect &&
- cmp \$expect $GIT_DIR/svn/trunk/.rev_db
+ test -L \"\$GIT_DIR\"/svn/trunk/.rev_db &&
+ test -f \"\$expect\" &&
+ cmp \"\$expect\" \"\$GIT_DIR\"/svn/trunk/.rev_db
"
test_done
diff --git a/t/t9108-git-svn-glob.sh b/t/t9108-git-svn-glob.sh
index db4344c..eb039ef 100755
--- a/t/t9108-git-svn-glob.sh
+++ b/t/t9108-git-svn-glob.sh
@@ -14,8 +14,8 @@ test_expect_success 'test refspec globbing' "
mkdir -p trunk/src/a trunk/src/b trunk/doc &&
echo 'hello world' > trunk/src/a/readme &&
echo 'goodbye world' > trunk/src/b/readme &&
- svn import -m 'initial' trunk $svnrepo/trunk &&
- svn co $svnrepo tmp &&
+ svn import -m 'initial' trunk \"$svnrepo/trunk\" &&
+ svn co \"$svnrepo\" tmp &&
cd tmp &&
mkdir branches tags &&
svn add branches tags &&
@@ -38,7 +38,7 @@ test_expect_success 'test refspec globbing' "
poke tags/end/src/b/readme &&
svn commit -m 'nothing to see here'
cd .. &&
- git config --add svn-remote.svn.url $svnrepo &&
+ git config --add svn-remote.svn.url \"$svnrepo\" &&
git config --add svn-remote.svn.fetch \
'trunk/src/a:refs/remotes/trunk' &&
git config --add svn-remote.svn.branches \
@@ -60,7 +60,7 @@ echo nothing to see here >> expect.two
cat expect.end >> expect.two
test_expect_success 'test left-hand-side only globbing' "
- git config --add svn-remote.two.url $svnrepo &&
+ git config --add svn-remote.two.url \"$svnrepo\" &&
git config --add svn-remote.two.fetch trunk:refs/remotes/two/trunk &&
git config --add svn-remote.two.branches \
'branches/*:refs/remotes/two/branches/*' &&
diff --git a/t/t9110-git-svn-use-svm-props.sh b/t/t9110-git-svn-use-svm-props.sh
index 6235af4..9df60ba 100755
--- a/t/t9110-git-svn-use-svm-props.sh
+++ b/t/t9110-git-svn-use-svm-props.sh
@@ -8,11 +8,11 @@ test_description='git-svn useSvmProps test'
. ./lib-git-svn.sh
test_expect_success 'load svm repo' "
- svnadmin load -q $rawsvnrepo < ../t9110/svm.dump &&
- git-svn init --minimize-url -R arr -i bar $svnrepo/mirror/arr &&
- git-svn init --minimize-url -R argh -i dir $svnrepo/mirror/argh &&
+ svnadmin load -q \"$rawsvnrepo\" < ../t9110/svm.dump &&
+ git-svn init --minimize-url -R arr -i bar \"$svnrepo/mirror/arr\" &&
+ git-svn init --minimize-url -R argh -i dir \"$svnrepo/mirror/argh\" &&
git-svn init --minimize-url -R argh -i e \
- $svnrepo/mirror/argh/a/b/c/d/e &&
+ \"$svnrepo/mirror/argh/a/b/c/d/e\" &&
git config svn.useSvmProps true &&
git-svn fetch --all
"
diff --git a/t/t9111-git-svn-use-svnsync-props.sh b/t/t9111-git-svn-use-svnsync-props.sh
index ec7dedd..e3693eb 100755
--- a/t/t9111-git-svn-use-svnsync-props.sh
+++ b/t/t9111-git-svn-use-svnsync-props.sh
@@ -8,10 +8,10 @@ test_description='git-svn useSvnsyncProps test'
. ./lib-git-svn.sh
test_expect_success 'load svnsync repo' "
- svnadmin load -q $rawsvnrepo < ../t9111/svnsync.dump &&
- git-svn init --minimize-url -R arr -i bar $svnrepo/bar &&
- git-svn init --minimize-url -R argh -i dir $svnrepo/dir &&
- git-svn init --minimize-url -R argh -i e $svnrepo/dir/a/b/c/d/e &&
+ svnadmin load -q \"$rawsvnrepo\" < ../t9111/svnsync.dump &&
+ git-svn init --minimize-url -R arr -i bar \"$svnrepo/bar\" &&
+ git-svn init --minimize-url -R argh -i dir \"$svnrepo/dir\" &&
+ git-svn init --minimize-url -R argh -i e \"$svnrepo/dir/a/b/c/d/e\" &&
git config svn.useSvnsyncProps true &&
git-svn fetch --all
"
diff --git a/t/t9112-git-svn-md5less-file.sh b/t/t9112-git-svn-md5less-file.sh
index 08313bb..124120c 100755
--- a/t/t9112-git-svn-md5less-file.sh
+++ b/t/t9112-git-svn-md5less-file.sh
@@ -38,8 +38,8 @@ PROPS-END
EOF
-test_expect_success 'load svn dumpfile' "svnadmin load $rawsvnrepo < dumpfile.svn"
+test_expect_success 'load svn dumpfile' "svnadmin load \"$rawsvnrepo\" < dumpfile.svn"
-test_expect_success 'initialize git-svn' "git-svn init $svnrepo"
+test_expect_success 'initialize git-svn' "git-svn init \"$svnrepo\""
test_expect_success 'fetch revisions from svn' 'git-svn fetch'
test_done
diff --git a/t/t9113-git-svn-dcommit-new-file.sh b/t/t9113-git-svn-dcommit-new-file.sh
index 9ef0db9..150d7f0 100755
--- a/t/t9113-git-svn-dcommit-new-file.sh
+++ b/t/t9113-git-svn-dcommit-new-file.sh
@@ -15,14 +15,14 @@ test_description='git-svn dcommit new files over svn:// test'
start_svnserve () {
svnserve --listen-port $SVNSERVE_PORT \
- --root $rawsvnrepo \
+ --root "$rawsvnrepo" \
--listen-once \
--listen-host 127.0.0.1 &
}
test_expect_success 'start tracking an empty repo' "
- svn mkdir -m 'empty dir' $svnrepo/empty-dir &&
- echo anon-access = write >> $rawsvnrepo/conf/svnserve.conf &&
+ svn mkdir -m 'empty dir' \"$svnrepo/empty-dir\" &&
+ echo anon-access = write >> \"$rawsvnrepo/conf/svnserve.conf\" &&
start_svnserve &&
git svn init svn://127.0.0.1:$SVNSERVE_PORT &&
git svn fetch
diff --git a/t/t9114-git-svn-dcommit-merge.sh b/t/t9114-git-svn-dcommit-merge.sh
index d6ca955..ffe8859 100755
--- a/t/t9114-git-svn-dcommit-merge.sh
+++ b/t/t9114-git-svn-dcommit-merge.sh
@@ -35,7 +35,7 @@ EOF
}
test_expect_success 'setup svn repository' "
- svn co $svnrepo mysvnwork &&
+ svn co \"$svnrepo\" mysvnwork &&
mkdir -p mysvnwork/trunk &&
cd mysvnwork &&
big_text_block >> trunk/README &&
@@ -45,7 +45,7 @@ test_expect_success 'setup svn repository' "
"
test_expect_success 'setup git mirror and merge' "
- git svn init $svnrepo -t tags -T trunk -b branches &&
+ git svn init \"$svnrepo\" -t tags -T trunk -b branches &&
git svn fetch &&
git checkout --track -b svn remotes/trunk &&
git checkout -b merge &&
diff --git a/t/t9115-git-svn-dcommit-funky-renames.sh b/t/t9115-git-svn-dcommit-funky-renames.sh
index 182299c..0681ffa 100755
--- a/t/t9115-git-svn-dcommit-funky-renames.sh
+++ b/t/t9115-git-svn-dcommit-funky-renames.sh
@@ -8,12 +8,12 @@ test_description='git-svn dcommit can commit renames of files with ugly names'
. ./lib-git-svn.sh
test_expect_success 'load repository with strange names' "
- svnadmin load -q $rawsvnrepo < ../t9115/funky-names.dump &&
+ svnadmin load -q \"$rawsvnrepo\" < ../t9115/funky-names.dump &&
start_httpd
"
test_expect_success 'init and fetch repository' "
- git svn init $svnrepo &&
+ git svn init \"$svnrepo\" &&
git svn fetch &&
git reset --hard git-svn
"
diff --git a/t/t9116-git-svn-log.sh b/t/t9116-git-svn-log.sh
index 0d4e6b3..890b5f1 100755
--- a/t/t9116-git-svn-log.sh
+++ b/t/t9116-git-svn-log.sh
@@ -14,9 +14,9 @@ test_expect_success 'setup repository and import' "
mkdir -p \$i && \
echo hello >> \$i/README || exit 1
done && \
- svn import -m test . $svnrepo
+ svn import -m test . \"$svnrepo\"
cd .. &&
- git-svn init $svnrepo -T trunk -b branches -t tags &&
+ git-svn init \"$svnrepo\" -T trunk -b branches -t tags &&
git-svn fetch &&
git reset --hard trunk &&
echo bye >> README &&
diff --git a/t/t9500-gitweb-standalone-no-errors.sh b/t/t9500-gitweb-standalone-no-errors.sh
index 642b836..b90e78c 100755
--- a/t/t9500-gitweb-standalone-no-errors.sh
+++ b/t/t9500-gitweb-standalone-no-errors.sh
@@ -45,13 +45,13 @@ gitweb_run () {
export QUERY_STRING=""$1""
export PATH_INFO=""$2""
- export GITWEB_CONFIG=$(pwd)/gitweb_config.perl
+ export GITWEB_CONFIG="$(pwd)/gitweb_config.perl"
# some of git commands write to STDERR on error, but this is not
# written to web server logs, so we are not interested in that:
# we are interested only in properly formatted errors/warnings
rm -f gitweb.log &&
- perl -- $(pwd)/../../gitweb/gitweb.perl \
+ perl -- "$(pwd)/../../gitweb/gitweb.perl" \
>/dev/null 2>gitweb.log &&
if grep -q -s "^[[]" gitweb.log >/dev/null; then false; else true; fi
diff --git a/t/test-lib.sh b/t/test-lib.sh
index cc1253c..a68415f 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -229,7 +229,7 @@ test_create_repo () {
repo="$1"
mkdir "$repo"
cd "$repo" || error "Cannot setup test environment"
- "$GIT_EXEC_PATH/git" init --template=$GIT_EXEC_PATH/templates/blt/ >/dev/null 2>&1 ||
+ "$GIT_EXEC_PATH/git" init --template="$GIT_EXEC_PATH/templates/blt/" >/dev/null 2>&1 ||
error "cannot run git init -- have you built things yet?"
mv .git/hooks .git/hooks-disabled
cd "$owd"
--
1.5.3.1
^ permalink raw reply related [relevance 6%]
* stgit restrictions on patch names
@ 2007-10-25 19:48 4% Yann Dirson
2007-10-29 16:14 0% ` Catalin Marinas
0 siblings, 1 reply; 200+ results
From: Yann Dirson @ 2007-10-25 19:48 UTC (permalink / raw)
To: Catalin Marinas, Karl Hasselström; +Cc: GIT list
Looks like stgit is now more picky on patch names than in used to be:
$ stg branch --clone v2.0.6-debian
Checking for changes in the working directory ... done
Cloning current branch to "v2.0.6-debian" ...
No log for 01_springelectrical
stg branch: Invalid patch name: "10_g++4.0_build_failures"
$
=> the result of the cloning operation is a partial clone. Do we want to:
- implement a mechanism for checking beforehand that the operation
will not fail ? Seems awkward to duplicate checks already found
elsewhere.
- wait for proper transactions so we can rollback on error ?
- on clone error, delete the newly-created stack ? I'd vote for this
one, until the previous one gets done.
=> is there any particular reason why we would refuse "+" ?
^ permalink raw reply [relevance 4%]
* Re: stgit restrictions on patch names
2007-10-25 19:48 4% stgit restrictions on patch names Yann Dirson
@ 2007-10-29 16:14 0% ` Catalin Marinas
0 siblings, 0 replies; 200+ results
From: Catalin Marinas @ 2007-10-29 16:14 UTC (permalink / raw)
To: Yann Dirson; +Cc: Karl Hasselström, GIT list
On 25/10/2007, Yann Dirson <ydirson@altern.org> wrote:
> Looks like stgit is now more picky on patch names than in used to be:
It's not that we explicitly disallows "+" but I think I tried to avoid
some wrong patch names but was too lazy to create a better regexp.
As a quick fix, we could re-generate a patch name if it is invalid.
> => the result of the cloning operation is a partial clone. Do we want to:
>
> - implement a mechanism for checking beforehand that the operation
> will not fail ? Seems awkward to duplicate checks already found
> elsewhere.
>
> - wait for proper transactions so we can rollback on error ?
>
> - on clone error, delete the newly-created stack ? I'd vote for this
> one, until the previous one gets done.
I think the last one is the simplest to implement, while the second is
nicer, I've never found the time to investigate it properly.
--
Catalin
^ permalink raw reply [relevance 0%]
* [PATCH] Updated russian translation of git-gui
@ 2007-10-31 21:16 3% Alex Riesen
0 siblings, 0 replies; 200+ results
From: Alex Riesen @ 2007-10-31 21:16 UTC (permalink / raw)
To: git; +Cc: Shawn O. Pearce
Fixed some spelling mistakes.
---
po/ru.po | 516 +++++++++++++++++++++++++++++++++++---------------------------
1 files changed, 292 insertions(+), 224 deletions(-)
diff --git a/po/ru.po b/po/ru.po
index b8e9447..6727a83 100644
--- a/po/ru.po
+++ b/po/ru.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: git-gui\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2007-10-10 04:04-0400\n"
+"POT-Creation-Date: 2007-10-31 21:23+0100\n"
"PO-Revision-Date: 2007-10-22 22:30-0200\n"
"Last-Translator: Alex Riesen <raa.lkml@gmail.com>\n"
"Language-Team: Russian Translation <git@vger.kernel.org>\n"
@@ -15,33 +15,33 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-#: git-gui.sh:41 git-gui.sh:634 git-gui.sh:648 git-gui.sh:661 git-gui.sh:744
-#: git-gui.sh:763
+#: git-gui.sh:41 git-gui.sh:597 git-gui.sh:611 git-gui.sh:624 git-gui.sh:707
+#: git-gui.sh:726
msgid "git-gui: fatal error"
msgstr "git-gui: критическая ошибка"
-#: git-gui.sh:595
+#: git-gui.sh:558
#, tcl-format
msgid "Invalid font specified in %s:"
msgstr "В %s установлен неверный шрифт:"
-#: git-gui.sh:620
+#: git-gui.sh:583
msgid "Main Font"
msgstr "Шрифт интерфейса"
-#: git-gui.sh:621
+#: git-gui.sh:584
msgid "Diff/Console Font"
msgstr "Шрифт консоли и изменений (diff)"
-#: git-gui.sh:635
+#: git-gui.sh:598
msgid "Cannot find git in PATH."
msgstr "git не найден в PATH."
-#: git-gui.sh:662
+#: git-gui.sh:625
msgid "Cannot parse Git version string:"
msgstr "Невозможно распознать строку версии Git: "
-#: git-gui.sh:680
+#: git-gui.sh:643
#, tcl-format
msgid ""
"Git version cannot be determined.\n"
@@ -59,79 +59,79 @@ msgstr ""
"\n"
"Принять '%s' как версию 1.5.0?\n"
-#: git-gui.sh:853
+#: git-gui.sh:881
msgid "Git directory not found:"
msgstr "Каталог Git не найден:"
-#: git-gui.sh:860
+#: git-gui.sh:888
msgid "Cannot move to top of working directory:"
msgstr "Невозможно перейти к корню рабочего каталога репозитория: "
-#: git-gui.sh:867
+#: git-gui.sh:895
msgid "Cannot use funny .git directory:"
msgstr "Каталог.git испорчен: "
-#: git-gui.sh:872
+#: git-gui.sh:900
msgid "No working directory"
msgstr "Отсутствует рабочий каталог"
-#: git-gui.sh:1019
+#: git-gui.sh:1047
msgid "Refreshing file status..."
msgstr "Обновление информации о состоянии файлов..."
-#: git-gui.sh:1084
+#: git-gui.sh:1112
msgid "Scanning for modified files ..."
msgstr "Поиск измененных файлов..."
-#: git-gui.sh:1259 lib/browser.tcl:245
+#: git-gui.sh:1287 lib/browser.tcl:245
msgid "Ready."
msgstr "Готово."
-#: git-gui.sh:1525
+#: git-gui.sh:1553
msgid "Unmodified"
msgstr "Не изменено"
-#: git-gui.sh:1527
+#: git-gui.sh:1555
msgid "Modified, not staged"
msgstr "Изменено, не подготовлено"
-#: git-gui.sh:1528 git-gui.sh:1533
+#: git-gui.sh:1556 git-gui.sh:1561
msgid "Staged for commit"
msgstr "Подготовлено для сохранения"
-#: git-gui.sh:1529 git-gui.sh:1534
+#: git-gui.sh:1557 git-gui.sh:1562
msgid "Portions staged for commit"
msgstr "Части, подготовленные для сохранения"
-#: git-gui.sh:1530 git-gui.sh:1535
+#: git-gui.sh:1558 git-gui.sh:1563
msgid "Staged for commit, missing"
msgstr "Подготовлено для сохранения, отсутствует"
-#: git-gui.sh:1532
+#: git-gui.sh:1560
msgid "Untracked, not staged"
msgstr "Не отслеживается, не подготовлено"
-#: git-gui.sh:1537
+#: git-gui.sh:1565
msgid "Missing"
msgstr "Отсутствует"
-#: git-gui.sh:1538
+#: git-gui.sh:1566
msgid "Staged for removal"
msgstr "Подготовлено для удаления"
-#: git-gui.sh:1539
+#: git-gui.sh:1567
msgid "Staged for removal, still present"
msgstr "Подготовлено для удаления, еще не удалено"
-#: git-gui.sh:1541 git-gui.sh:1542 git-gui.sh:1543 git-gui.sh:1544
+#: git-gui.sh:1569 git-gui.sh:1570 git-gui.sh:1571 git-gui.sh:1572
msgid "Requires merge resolution"
msgstr "Требуется разрешение конфликта при объединении"
-#: git-gui.sh:1579
+#: git-gui.sh:1607
msgid "Starting gitk... please wait..."
msgstr "Запускается gitk... пожалуйста, ждите..."
-#: git-gui.sh:1588
+#: git-gui.sh:1616
#, tcl-format
msgid ""
"Unable to start gitk:\n"
@@ -142,296 +142,295 @@ msgstr ""
"\n"
"%s не существует"
-#: git-gui.sh:1788 lib/choose_repository.tcl:32
+#: git-gui.sh:1816 lib/choose_repository.tcl:35
msgid "Repository"
msgstr "Репозиторий"
-#: git-gui.sh:1789
+#: git-gui.sh:1817
msgid "Edit"
msgstr "Редактировать"
-#: git-gui.sh:1791 lib/choose_rev.tcl:560
+#: git-gui.sh:1819 lib/choose_rev.tcl:560
msgid "Branch"
msgstr "Ветвь"
-#: git-gui.sh:1794 lib/choose_rev.tcl:547
+#: git-gui.sh:1822 lib/choose_rev.tcl:547
msgid "Commit@@noun"
msgstr "Состояние"
-#: git-gui.sh:1797 lib/merge.tcl:121 lib/merge.tcl:150 lib/merge.tcl:168
+#: git-gui.sh:1825 lib/merge.tcl:121 lib/merge.tcl:150 lib/merge.tcl:168
msgid "Merge"
msgstr "Объединить"
-#: git-gui.sh:1798 lib/choose_rev.tcl:556
+#: git-gui.sh:1826 lib/choose_rev.tcl:556
msgid "Remote"
msgstr "Внешние репозитории"
-#: git-gui.sh:1807
+#: git-gui.sh:1835
msgid "Browse Current Branch's Files"
msgstr "Просмотреть файлы текущей ветви"
-#: git-gui.sh:1811
+#: git-gui.sh:1839
msgid "Browse Branch Files..."
msgstr "Показать файлы ветви..."
-#: git-gui.sh:1816
+#: git-gui.sh:1844
msgid "Visualize Current Branch's History"
msgstr "История текущей ветви наглядно"
-#: git-gui.sh:1820
+#: git-gui.sh:1848
msgid "Visualize All Branch History"
msgstr "История всех ветвей наглядно"
-#: git-gui.sh:1827
+#: git-gui.sh:1855
#, tcl-format
msgid "Browse %s's Files"
msgstr "Показать файлы ветви %s"
-#: git-gui.sh:1829
+#: git-gui.sh:1857
#, tcl-format
msgid "Visualize %s's History"
msgstr "История ветви %s наглядно"
-#: git-gui.sh:1834 lib/database.tcl:27 lib/database.tcl:67
+#: git-gui.sh:1862 lib/database.tcl:27 lib/database.tcl:67
msgid "Database Statistics"
msgstr "Статистика базы данных"
-#: git-gui.sh:1837 lib/database.tcl:34
+#: git-gui.sh:1865 lib/database.tcl:34
msgid "Compress Database"
msgstr "Сжать базу данных"
-#: git-gui.sh:1840
+#: git-gui.sh:1868
msgid "Verify Database"
msgstr "Проверить базу данных"
-#: git-gui.sh:1847 git-gui.sh:1851 git-gui.sh:1855 lib/shortcut.tcl:9
-#: lib/shortcut.tcl:45 lib/shortcut.tcl:84
+#: git-gui.sh:1875 git-gui.sh:1879 git-gui.sh:1883 lib/shortcut.tcl:7
+#: lib/shortcut.tcl:39 lib/shortcut.tcl:71
msgid "Create Desktop Icon"
msgstr "Создать ярлык на рабочем столе"
-#: git-gui.sh:1860 lib/choose_repository.tcl:36 lib/choose_repository.tcl:95
+#: git-gui.sh:1888 lib/choose_repository.tcl:176 lib/choose_repository.tcl:184
msgid "Quit"
msgstr "Выход"
-#: git-gui.sh:1867
+#: git-gui.sh:1895
msgid "Undo"
msgstr "Отменить"
-#: git-gui.sh:1870
+#: git-gui.sh:1898
msgid "Redo"
msgstr "Повторить"
-#: git-gui.sh:1874 git-gui.sh:2366
+#: git-gui.sh:1902 git-gui.sh:2395
msgid "Cut"
msgstr "Вырезать"
-#: git-gui.sh:1877 git-gui.sh:2369 git-gui.sh:2440 git-gui.sh:2512
+#: git-gui.sh:1905 git-gui.sh:2398 git-gui.sh:2469 git-gui.sh:2541
#: lib/console.tcl:67
msgid "Copy"
msgstr "Копировать"
-#: git-gui.sh:1880 git-gui.sh:2372
+#: git-gui.sh:1908 git-gui.sh:2401
msgid "Paste"
msgstr "Вставить"
-#: git-gui.sh:1883 git-gui.sh:2375 lib/branch_delete.tcl:26
+#: git-gui.sh:1911 git-gui.sh:2404 lib/branch_delete.tcl:26
#: lib/remote_branch_delete.tcl:38
msgid "Delete"
msgstr "Удалить"
-#: git-gui.sh:1887 git-gui.sh:2379 git-gui.sh:2516 lib/console.tcl:69
+#: git-gui.sh:1915 git-gui.sh:2408 git-gui.sh:2545 lib/console.tcl:69
msgid "Select All"
msgstr "Выделить все"
-#: git-gui.sh:1896
+#: git-gui.sh:1924
msgid "Create..."
msgstr "Создать..."
-#: git-gui.sh:1902
+#: git-gui.sh:1930
msgid "Checkout..."
msgstr "Перейти..."
-#: git-gui.sh:1908
+#: git-gui.sh:1936
msgid "Rename..."
msgstr "Переименовать..."
-#: git-gui.sh:1913 git-gui.sh:2012
+#: git-gui.sh:1941 git-gui.sh:2040
msgid "Delete..."
msgstr "Удалить..."
-#: git-gui.sh:1918
+#: git-gui.sh:1946
msgid "Reset..."
msgstr "Сбросить..."
-#: git-gui.sh:1930 git-gui.sh:2313
+#: git-gui.sh:1958 git-gui.sh:2342
msgid "New Commit"
msgstr "Новое состояние"
-#: git-gui.sh:1938 git-gui.sh:2320
+#: git-gui.sh:1966 git-gui.sh:2349
msgid "Amend Last Commit"
msgstr "Исправить последнее состояние"
-#: git-gui.sh:1947 git-gui.sh:2280 lib/remote_branch_delete.tcl:99
+#: git-gui.sh:1975 git-gui.sh:2309 lib/remote_branch_delete.tcl:99
msgid "Rescan"
msgstr "Перечитать"
-#: git-gui.sh:1953
+#: git-gui.sh:1981
msgid "Stage To Commit"
msgstr "Подготовить для сохранения"
-#: git-gui.sh:1958
+#: git-gui.sh:1986
msgid "Stage Changed Files To Commit"
msgstr "Подготовить измененные файлы для сохранения"
-#: git-gui.sh:1964
+#: git-gui.sh:1992
msgid "Unstage From Commit"
msgstr "Убрать из подготовленного"
-#: git-gui.sh:1969 lib/index.tcl:352
+#: git-gui.sh:1997 lib/index.tcl:393
msgid "Revert Changes"
msgstr "Отменить изменения"
-#: git-gui.sh:1976 git-gui.sh:2292 git-gui.sh:2390
+#: git-gui.sh:2004 git-gui.sh:2321 git-gui.sh:2419
msgid "Sign Off"
msgstr "Подписать"
-#: git-gui.sh:1980 git-gui.sh:2296
+#: git-gui.sh:2008 git-gui.sh:2325
msgid "Commit@@verb"
msgstr "Сохранить"
-#: git-gui.sh:1991
+#: git-gui.sh:2019
msgid "Local Merge..."
msgstr "Локальное объединение..."
-#: git-gui.sh:1996
+#: git-gui.sh:2024
msgid "Abort Merge..."
msgstr "Прервать объединение..."
-#: git-gui.sh:2008
+#: git-gui.sh:2036
msgid "Push..."
msgstr "Отправить..."
-#: git-gui.sh:2019 lib/choose_repository.tcl:41
-#, fuzzy
+#: git-gui.sh:2047 lib/choose_repository.tcl:40
msgid "Apple"
msgstr ""
-#: git-gui.sh:2022 git-gui.sh:2044 lib/about.tcl:13
-#: lib/choose_repository.tcl:44 lib/choose_repository.tcl:50
+#: git-gui.sh:2050 git-gui.sh:2072 lib/about.tcl:13
+#: lib/choose_repository.tcl:43 lib/choose_repository.tcl:49
#, tcl-format
msgid "About %s"
msgstr "О %s"
-#: git-gui.sh:2026
+#: git-gui.sh:2054
msgid "Preferences..."
msgstr "Настройки..."
-#: git-gui.sh:2034 git-gui.sh:2558
+#: git-gui.sh:2062 git-gui.sh:2587
msgid "Options..."
msgstr "Настройки..."
-#: git-gui.sh:2040 lib/choose_repository.tcl:47
+#: git-gui.sh:2068 lib/choose_repository.tcl:46
msgid "Help"
msgstr "Помощь"
-#: git-gui.sh:2081
+#: git-gui.sh:2109
msgid "Online Documentation"
msgstr "Документация в интернете"
-#: git-gui.sh:2165
+#: git-gui.sh:2193
#, tcl-format
msgid "fatal: cannot stat path %s: No such file or directory"
msgstr "критическая ошибка: %s: нет такого файла или каталога"
-#: git-gui.sh:2198
+#: git-gui.sh:2226
msgid "Current Branch:"
msgstr "Текущая ветвь:"
-#: git-gui.sh:2219
+#: git-gui.sh:2247
msgid "Staged Changes (Will Commit)"
msgstr "Подготовлено (будет сохранено)"
-#: git-gui.sh:2239
+#: git-gui.sh:2266
msgid "Unstaged Changes"
msgstr "Изменено (не будет сохранено)"
-#: git-gui.sh:2286
+#: git-gui.sh:2315
msgid "Stage Changed"
msgstr "Подготовить все"
-#: git-gui.sh:2302 lib/transport.tcl:93 lib/transport.tcl:182
+#: git-gui.sh:2331 lib/transport.tcl:93 lib/transport.tcl:182
msgid "Push"
msgstr "Отправить"
-#: git-gui.sh:2332
+#: git-gui.sh:2361
msgid "Initial Commit Message:"
msgstr "Комментарий к первому состоянию:"
-#: git-gui.sh:2333
+#: git-gui.sh:2362
msgid "Amended Commit Message:"
msgstr "Комментарий к исправленному состоянию:"
-#: git-gui.sh:2334
+#: git-gui.sh:2363
msgid "Amended Initial Commit Message:"
msgstr "Комментарий к исправленному первоначальному состоянию:"
-#: git-gui.sh:2335
+#: git-gui.sh:2364
msgid "Amended Merge Commit Message:"
msgstr "Комментарий к исправленному объединению:"
-#: git-gui.sh:2336
+#: git-gui.sh:2365
msgid "Merge Commit Message:"
msgstr "Комментарий к объединению:"
-#: git-gui.sh:2337
+#: git-gui.sh:2366
msgid "Commit Message:"
msgstr "Комментарий к состоянию:"
-#: git-gui.sh:2382 git-gui.sh:2520 lib/console.tcl:71
+#: git-gui.sh:2411 git-gui.sh:2549 lib/console.tcl:71
msgid "Copy All"
msgstr "Копировать все"
-#: git-gui.sh:2406 lib/blame.tcl:104
+#: git-gui.sh:2435 lib/blame.tcl:104
msgid "File:"
msgstr "Файл:"
-#: git-gui.sh:2508
+#: git-gui.sh:2537
msgid "Refresh"
msgstr "Обновить"
-#: git-gui.sh:2529
+#: git-gui.sh:2558
msgid "Apply/Reverse Hunk"
msgstr "Применить/Убрать изменение"
-#: git-gui.sh:2535
+#: git-gui.sh:2564
msgid "Decrease Font Size"
msgstr "Уменьшить размер шрифта"
-#: git-gui.sh:2539
+#: git-gui.sh:2568
msgid "Increase Font Size"
msgstr "Увеличить размер шрифта"
-#: git-gui.sh:2544
+#: git-gui.sh:2573
msgid "Show Less Context"
msgstr "Меньше контекста"
-#: git-gui.sh:2551
+#: git-gui.sh:2580
msgid "Show More Context"
msgstr "Больше контекста"
-#: git-gui.sh:2565
+#: git-gui.sh:2594
msgid "Unstage Hunk From Commit"
msgstr "Не сохранять часть"
-#: git-gui.sh:2567
+#: git-gui.sh:2596
msgid "Stage Hunk For Commit"
msgstr "Подготовить часть для сохранения"
-#: git-gui.sh:2586
+#: git-gui.sh:2615
msgid "Initializing..."
msgstr "Инициализация..."
-#: git-gui.sh:2677
+#: git-gui.sh:2706
#, tcl-format
msgid ""
"Possible environment issues exist.\n"
@@ -448,7 +447,7 @@ msgstr ""
"запущенными из %s\n"
"\n"
-#: git-gui.sh:2707
+#: git-gui.sh:2736
msgid ""
"\n"
"This is due to a known issue with the\n"
@@ -458,7 +457,7 @@ msgstr ""
"Это известная проблема с Tcl,\n"
"распространяемым Cygwin."
-#: git-gui.sh:2712
+#: git-gui.sh:2741
#, tcl-format
msgid ""
"\n"
@@ -579,7 +578,7 @@ msgstr "Создание ветви"
msgid "Create New Branch"
msgstr "Создать новую ветвь"
-#: lib/branch_create.tcl:31 lib/choose_repository.tcl:199
+#: lib/branch_create.tcl:31 lib/choose_repository.tcl:375
msgid "Create"
msgstr "Создать"
@@ -732,9 +731,9 @@ msgstr "[На уровень выше]"
msgid "Browse Branch Files"
msgstr "Показать файлы ветви"
-#: lib/browser.tcl:277 lib/choose_repository.tcl:215
-#: lib/choose_repository.tcl:305 lib/choose_repository.tcl:315
-#: lib/choose_repository.tcl:811
+#: lib/browser.tcl:277 lib/choose_repository.tcl:391
+#: lib/choose_repository.tcl:482 lib/choose_repository.tcl:492
+#: lib/choose_repository.tcl:989
msgid "Browse"
msgstr "Показать"
@@ -788,7 +787,8 @@ msgstr "Рабочая область заблокирована другим п
msgid ""
"Last scanned state does not match repository state.\n"
"\n"
-"Another Git program has modified this repository since the last scan. A rescan must be performed before the current branch can be changed.\n"
+"Another Git program has modified this repository since the last scan. A "
+"rescan must be performed before the current branch can be changed.\n"
"\n"
"The rescan will be automatically started now.\n"
msgstr ""
@@ -822,11 +822,13 @@ msgstr "Ветвь '%s' остается текущей."
msgid ""
"You are no longer on a local branch.\n"
"\n"
-"If you wanted to be on a branch, create one now starting from 'This Detached Checkout'."
+"If you wanted to be on a branch, create one now starting from 'This Detached "
+"Checkout'."
msgstr ""
"Вы находитесь не в локальной ветви.\n"
"\n"
-"Если вы хотите снова вернуться к какой-нибудь ветви, создайте ее сейчас, начиная с 'Текущего отсоединенного состояния'."
+"Если вы хотите снова вернуться к какой-нибудь ветви, создайте ее сейчас, "
+"начиная с 'Текущего отсоединенного состояния'."
#: lib/checkout_op.tcl:446
#, tcl-format
@@ -856,19 +858,21 @@ msgstr "Наглядно"
msgid ""
"Failed to set current branch.\n"
"\n"
-"This working directory is only partially switched. We successfully updated your files, but failed to update an internal Git file.\n"
+"This working directory is only partially switched. We successfully updated "
+"your files, but failed to update an internal Git file.\n"
"\n"
"This should not have occurred. %s will now close and give up."
msgstr ""
"Не удалось установить текущую ветвь.\n"
"\n"
-"Ваш рабочий каталог обновлен только частично. Были обновлены все файлы кроме служебных файлов Git. \n"
+"Ваш рабочий каталог обновлен только частично. Были обновлены все файлы кроме "
+"служебных файлов Git. \n"
"\n"
"Этого не должно было произойти. %s завершается."
#: lib/choose_font.tcl:39
msgid "Select"
-msgstr "Выделить все"
+msgstr "Выбрать"
#: lib/choose_font.tcl:53
msgid "Font Family"
@@ -890,210 +894,226 @@ msgstr ""
"Это пример текста.\n"
"Если Вам нравится этот текст, это может быть Ваш шрифт."
-#: lib/choose_repository.tcl:25
+#: lib/choose_repository.tcl:27
msgid "Git Gui"
msgstr ""
-#: lib/choose_repository.tcl:69 lib/choose_repository.tcl:204
+#: lib/choose_repository.tcl:80 lib/choose_repository.tcl:380
msgid "Create New Repository"
msgstr "Создать новый репозиторий"
-#: lib/choose_repository.tcl:74 lib/choose_repository.tcl:291
+#: lib/choose_repository.tcl:86
+msgid "New..."
+msgstr "Новый..."
+
+#: lib/choose_repository.tcl:93 lib/choose_repository.tcl:468
msgid "Clone Existing Repository"
msgstr "Склонировать существующий репозиторий"
-#: lib/choose_repository.tcl:79 lib/choose_repository.tcl:800
+#: lib/choose_repository.tcl:99
+msgid "Clone..."
+msgstr "Склонировать..."
+
+#: lib/choose_repository.tcl:106 lib/choose_repository.tcl:978
msgid "Open Existing Repository"
msgstr "Выбрать существующий репозиторий"
-#: lib/choose_repository.tcl:91
-msgid "Next >"
-msgstr "Дальше >"
+#: lib/choose_repository.tcl:112
+msgid "Open..."
+msgstr "Открыть..."
-#: lib/choose_repository.tcl:152
+#: lib/choose_repository.tcl:125
+msgid "Recent Repositories"
+msgstr "Недавние репозитории"
+
+#: lib/choose_repository.tcl:131
+msgid "Open Recent Repository:"
+msgstr "Открыть последний репозиторий"
+
+#: lib/choose_repository.tcl:294
#, tcl-format
msgid "Location %s already exists."
msgstr "Путь '%s' уже существует."
-#: lib/choose_repository.tcl:158 lib/choose_repository.tcl:165
-#: lib/choose_repository.tcl:172
+#: lib/choose_repository.tcl:300 lib/choose_repository.tcl:307
+#: lib/choose_repository.tcl:314
#, tcl-format
msgid "Failed to create repository %s:"
msgstr "Не удалось создать репозиторий %s:"
-#: lib/choose_repository.tcl:209 lib/choose_repository.tcl:309
+#: lib/choose_repository.tcl:385 lib/choose_repository.tcl:486
msgid "Directory:"
msgstr "Каталог:"
-#: lib/choose_repository.tcl:238 lib/choose_repository.tcl:363
-#: lib/choose_repository.tcl:834
+#: lib/choose_repository.tcl:415 lib/choose_repository.tcl:544
+#: lib/choose_repository.tcl:1013
msgid "Git Repository"
msgstr "Репозиторий"
-#: lib/choose_repository.tcl:253 lib/choose_repository.tcl:260
+#: lib/choose_repository.tcl:430 lib/choose_repository.tcl:437
#, tcl-format
msgid "Directory %s already exists."
msgstr "Каталог '%s' уже существует."
-#: lib/choose_repository.tcl:265
+#: lib/choose_repository.tcl:442
#, tcl-format
msgid "File %s already exists."
msgstr "Файл '%s' уже существует."
-#: lib/choose_repository.tcl:286
+#: lib/choose_repository.tcl:463
msgid "Clone"
msgstr "Склонировать"
-#: lib/choose_repository.tcl:299
+#: lib/choose_repository.tcl:476
msgid "URL:"
msgstr "Ссылка:"
-#: lib/choose_repository.tcl:319
+#: lib/choose_repository.tcl:496
msgid "Clone Type:"
msgstr "Тип клона:"
-#: lib/choose_repository.tcl:325
+#: lib/choose_repository.tcl:502
msgid "Standard (Fast, Semi-Redundant, Hardlinks)"
msgstr "Стандартный (Быстрый, полуизбыточный, \"жесткие\" ссылки)"
-#: lib/choose_repository.tcl:331
+#: lib/choose_repository.tcl:508
msgid "Full Copy (Slower, Redundant Backup)"
msgstr "Полная копия (Медленный, создает резервную копию)"
-#: lib/choose_repository.tcl:337
+#: lib/choose_repository.tcl:514
msgid "Shared (Fastest, Not Recommended, No Backup)"
msgstr "Общий (Самый быстрый, не рекомендуется, без резервной копии)"
-#: lib/choose_repository.tcl:369 lib/choose_repository.tcl:418
-#: lib/choose_repository.tcl:560 lib/choose_repository.tcl:630
-#: lib/choose_repository.tcl:840 lib/choose_repository.tcl:848
+#: lib/choose_repository.tcl:550 lib/choose_repository.tcl:597
+#: lib/choose_repository.tcl:738 lib/choose_repository.tcl:808
+#: lib/choose_repository.tcl:1019 lib/choose_repository.tcl:1027
#, tcl-format
msgid "Not a Git repository: %s"
msgstr "Каталог не является репозиторием: %s"
-#: lib/choose_repository.tcl:405
+#: lib/choose_repository.tcl:586
msgid "Standard only available for local repository."
msgstr "Стандартный клон возможен только для локального репозитория."
-#: lib/choose_repository.tcl:409
+#: lib/choose_repository.tcl:590
msgid "Shared only available for local repository."
msgstr "Общий клон возможен только для локального репозитория."
-#: lib/choose_repository.tcl:439
+#: lib/choose_repository.tcl:617
msgid "Failed to configure origin"
msgstr "Не могу сконфигурировать исходный репозиторий."
-#: lib/choose_repository.tcl:451
+#: lib/choose_repository.tcl:629
msgid "Counting objects"
msgstr "Считаю объекты"
-#: lib/choose_repository.tcl:452
-#, fuzzy
+#: lib/choose_repository.tcl:630
msgid "buckets"
msgstr ""
-#: lib/choose_repository.tcl:476
+#: lib/choose_repository.tcl:654
#, tcl-format
msgid "Unable to copy objects/info/alternates: %s"
msgstr "Не могу скопировать objects/info/alternates: %s"
-#: lib/choose_repository.tcl:512
+#: lib/choose_repository.tcl:690
#, tcl-format
msgid "Nothing to clone from %s."
msgstr "Нечего клонировать с %s."
-#: lib/choose_repository.tcl:514 lib/choose_repository.tcl:728
-#: lib/choose_repository.tcl:740
+#: lib/choose_repository.tcl:692 lib/choose_repository.tcl:906
+#: lib/choose_repository.tcl:918
msgid "The 'master' branch has not been initialized."
msgstr "Не инициализирована ветвь 'master'."
-#: lib/choose_repository.tcl:527
+#: lib/choose_repository.tcl:705
msgid "Hardlinks are unavailable. Falling back to copying."
msgstr "\"Жесткие ссылки\" не доступны. Буду использовать копирование."
-#: lib/choose_repository.tcl:539
+#: lib/choose_repository.tcl:717
#, tcl-format
msgid "Cloning from %s"
msgstr "Клонирование %s"
-#: lib/choose_repository.tcl:570
+#: lib/choose_repository.tcl:748
msgid "Copying objects"
msgstr "Копирование objects"
-#: lib/choose_repository.tcl:571
+#: lib/choose_repository.tcl:749
msgid "KiB"
msgstr "КБ"
-#: lib/choose_repository.tcl:595
+#: lib/choose_repository.tcl:773
#, tcl-format
msgid "Unable to copy object: %s"
msgstr "Не могу скопировать объект: %s"
-#: lib/choose_repository.tcl:605
+#: lib/choose_repository.tcl:783
msgid "Linking objects"
msgstr "Создание ссылок на objects"
-#: lib/choose_repository.tcl:606
+#: lib/choose_repository.tcl:784
msgid "objects"
msgstr "объекты"
-#: lib/choose_repository.tcl:614
+#: lib/choose_repository.tcl:792
#, tcl-format
msgid "Unable to hardlink object: %s"
msgstr "Не могу \"жестко связать\" объект: %s"
-#: lib/choose_repository.tcl:669
+#: lib/choose_repository.tcl:847
msgid "Cannot fetch branches and objects. See console output for details."
-msgstr "Не могу получить ветви и объекты. Дополнительная информация на консоли."
+msgstr ""
+"Не могу получить ветви и объекты. Дополнительная информация на консоли."
-#: lib/choose_repository.tcl:680
+#: lib/choose_repository.tcl:858
msgid "Cannot fetch tags. See console output for details."
msgstr "Не могу получить метки. Дополнительная информация на консоли."
-#: lib/choose_repository.tcl:704
+#: lib/choose_repository.tcl:882
msgid "Cannot determine HEAD. See console output for details."
msgstr "Не могу определить HEAD. Дополнительная информация на консоли."
-#: lib/choose_repository.tcl:713
+#: lib/choose_repository.tcl:891
#, tcl-format
msgid "Unable to cleanup %s"
msgstr "Не могу очистить %s"
-#: lib/choose_repository.tcl:719
+#: lib/choose_repository.tcl:897
msgid "Clone failed."
msgstr "Клонирование не удалось."
-#: lib/choose_repository.tcl:726
+#: lib/choose_repository.tcl:904
msgid "No default branch obtained."
msgstr "Не было получено ветви по умолчанию."
-#: lib/choose_repository.tcl:737
+#: lib/choose_repository.tcl:915
#, tcl-format
msgid "Cannot resolve %s as a commit."
msgstr "Не могу распознать %s как состояние."
-#: lib/choose_repository.tcl:749
+#: lib/choose_repository.tcl:927
msgid "Creating working directory"
msgstr "Создаю рабочий каталог"
-#: lib/choose_repository.tcl:750 lib/index.tcl:15 lib/index.tcl:80
-#: lib/index.tcl:149
+#: lib/choose_repository.tcl:928 lib/index.tcl:65 lib/index.tcl:127
+#: lib/index.tcl:193
msgid "files"
msgstr "файлов"
-#: lib/choose_repository.tcl:779
+#: lib/choose_repository.tcl:957
msgid "Initial file checkout failed."
msgstr "Не удалось получить начальное состояние файлов репозитория."
-#: lib/choose_repository.tcl:795
+#: lib/choose_repository.tcl:973
msgid "Open"
msgstr "Открыть"
-#: lib/choose_repository.tcl:805
+#: lib/choose_repository.tcl:983
msgid "Repository:"
msgstr "Репозиторий:"
-#: lib/choose_repository.tcl:854
+#: lib/choose_repository.tcl:1033
#, tcl-format
msgid "Failed to open repository %s:"
msgstr "Не удалось открыть репозиторий %s:"
@@ -1116,7 +1136,7 @@ msgstr "Ветвь слежения"
#: lib/choose_rev.tcl:84 lib/choose_rev.tcl:537
msgid "Tag"
-msgstr "Метка"
+msgstr "Таг"
#: lib/choose_rev.tcl:317
#, tcl-format
@@ -1143,7 +1163,8 @@ msgstr "Ссылка"
msgid ""
"There is nothing to amend.\n"
"\n"
-"You are about to create the initial commit. There is no commit before this to amend.\n"
+"You are about to create the initial commit. There is no commit before this "
+"to amend.\n"
msgstr ""
"Отсутствует состояние для исправления.\n"
"\n"
@@ -1153,11 +1174,14 @@ msgstr ""
msgid ""
"Cannot amend while merging.\n"
"\n"
-"You are currently in the middle of a merge that has not been fully completed. You cannot amend the prior commit unless you first abort the current merge activity.\n"
+"You are currently in the middle of a merge that has not been fully "
+"completed. You cannot amend the prior commit unless you first abort the "
+"current merge activity.\n"
msgstr ""
"Невозможно исправить состояние во время объединения.\n"
"\n"
-"Текущее объединение не завершено. Невозможно исправить предыдущее сохраненное состояние не прерывая текущее объединение.\n"
+"Текущее объединение не завершено. Невозможно исправить предыдущее "
+"сохраненное состояние не прерывая текущее объединение.\n"
#: lib/commit.tcl:49
msgid "Error loading commit data for amend:"
@@ -1169,19 +1193,21 @@ msgstr "Невозможно получить информацию об авто
#: lib/commit.tcl:81
msgid "Invalid GIT_COMMITTER_IDENT:"
-msgstr "Неверная GIT_COMMITTER_IDENT:"
+msgstr "Неверный GIT_COMMITTER_IDENT:"
#: lib/commit.tcl:133
msgid ""
"Last scanned state does not match repository state.\n"
"\n"
-"Another Git program has modified this repository since the last scan. A rescan must be performed before another commit can be created.\n"
+"Another Git program has modified this repository since the last scan. A "
+"rescan must be performed before another commit can be created.\n"
"\n"
"The rescan will be automatically started now.\n"
msgstr ""
"Последнее прочитанное состояние репозитория не соответствует текущему.\n"
"\n"
-"С момента последней проверки репозиторий был изменен другой программой Git. Необходимо перечитать репозиторий, прежде чем изменять текущую ветвь. \n"
+"С момента последней проверки репозиторий был изменен другой программой Git. "
+"Необходимо перечитать репозиторий, прежде чем изменять текущую ветвь. \n"
"\n"
"Это будет сделано сейчас автоматически.\n"
@@ -1190,11 +1216,13 @@ msgstr ""
msgid ""
"Unmerged files cannot be committed.\n"
"\n"
-"File %s has merge conflicts. You must resolve them and stage the file before committing.\n"
+"File %s has merge conflicts. You must resolve them and stage the file "
+"before committing.\n"
msgstr ""
"Нельзя сохранить необъединенные файлы.\n"
"\n"
-"Для файла %s возник конфликт объединения. Разрешите конфликт и добавьте к подготовленным файлам перед сохранением.\n"
+"Для файла %s возник конфликт объединения. Разрешите конфликт и добавьте к "
+"подготовленным файлам перед сохранением.\n"
#: lib/commit.tcl:162
#, tcl-format
@@ -1333,13 +1361,15 @@ msgstr "Проверка базы объектов при помощи fsck"
msgid ""
"This repository currently has approximately %i loose objects.\n"
"\n"
-"To maintain optimal performance it is strongly recommended that you compress the database when more than %i loose objects exist.\n"
+"To maintain optimal performance it is strongly recommended that you compress "
+"the database when more than %i loose objects exist.\n"
"\n"
"Compress the database now?"
msgstr ""
"Этот репозиторий сейчас содержит примерно %i свободных объектов\n"
"\n"
-"Для лучшей производительности рекомендуется сжать базу данных, когда есть более %i несвязанных объектов.\n"
+"Для лучшей производительности рекомендуется сжать базу данных, когда есть "
+"более %i несвязанных объектов.\n"
"\n"
"Сжать базу данных сейчас?"
@@ -1355,15 +1385,18 @@ msgid ""
"\n"
"%s has no changes.\n"
"\n"
-"The modification date of this file was updated by another application, but the content within the file was not changed.\n"
+"The modification date of this file was updated by another application, but "
+"the content within the file was not changed.\n"
"\n"
-"A rescan will be automatically started to find other files which may have the same state."
+"A rescan will be automatically started to find other files which may have "
+"the same state."
msgstr ""
"Изменений не обнаружено.\n"
"\n"
"в %s отутствуют изменения.\n"
"\n"
-"Дата изменения файла была обновлена другой программой, но содержимое файла осталось прежним.\n"
+"Дата изменения файла была обновлена другой программой, но содержимое файла "
+"осталось прежним.\n"
"\n"
"Сейчас будет запущено перечитывание репозитория, чтобы найти подобные файлы."
@@ -1413,32 +1446,57 @@ msgstr "предупреждение"
msgid "You must correct the above errors before committing."
msgstr "Прежде чем сохранить, исправьте вышеуказанные ошибки."
-#: lib/index.tcl:241
+#: lib/index.tcl:6
+msgid "Unable to unlock the index."
+msgstr "Не удалось разблокировать индекс"
+
+#: lib/index.tcl:15
+msgid "Index Error"
+msgstr "Ошибка индекса"
+
+#: lib/index.tcl:21
+msgid ""
+"Updating the Git index failed. A rescan will be automatically started to "
+"resynchronize git-gui."
+msgstr ""
+"Не удалось обновить индекс Git. Состояние репозитория будет"
+"перечитано автоматически."
+
+#: lib/index.tcl:27
+msgid "Continue"
+msgstr "Продолжить"
+
+#: lib/index.tcl:31
+msgid "Unlock Index"
+msgstr "Разблокировать индекс"
+
+#: lib/index.tcl:282
#, tcl-format
msgid "Unstaging %s from commit"
msgstr "Удаление %s из подготовленного"
-#: lib/index.tcl:285
+#: lib/index.tcl:326
#, tcl-format
msgid "Adding %s"
msgstr "Добавление %s..."
-#: lib/index.tcl:340
+#: lib/index.tcl:381
#, tcl-format
msgid "Revert changes in file %s?"
msgstr "Отменить изменения в файле %s?"
-#: lib/index.tcl:342
+#: lib/index.tcl:383
#, tcl-format
msgid "Revert changes in these %i files?"
msgstr "Отменить изменения в %i файле(-ах)?"
-#: lib/index.tcl:348
+#: lib/index.tcl:389
msgid "Any unstaged changes will be permanently lost by the revert."
msgstr ""
-"Любые изменения, не подготовленные к сохранению, будут потеряны при данной операции."
+"Любые изменения, не подготовленные к сохранению, будут потеряны при данной "
+"операции."
-#: lib/index.tcl:351
+#: lib/index.tcl:392
msgid "Do Nothing"
msgstr "Ничего не делать"
@@ -1450,19 +1508,22 @@ msgid ""
msgstr ""
"Невозможно выполнить объединение во время исправления.\n"
"\n"
-"Завершите исправление данного состояния перед выполнением операции объединения.\n"
+"Завершите исправление данного состояния перед выполнением операции "
+"объединения.\n"
#: lib/merge.tcl:27
msgid ""
"Last scanned state does not match repository state.\n"
"\n"
-"Another Git program has modified this repository since the last scan. A rescan must be performed before a merge can be performed.\n"
+"Another Git program has modified this repository since the last scan. A "
+"rescan must be performed before a merge can be performed.\n"
"\n"
"The rescan will be automatically started now.\n"
msgstr ""
"Последнее прочитанное состояние репозитория не соответствует текущему.\n"
"\n"
-"С момента последней проверки репозиторий был изменен другой программой Git. Необходимо перечитать репозиторий, прежде чем изменять текущую ветвь.\n"
+"С момента последней проверки репозиторий был изменен другой программой Git. "
+"Необходимо перечитать репозиторий, прежде чем изменять текущую ветвь.\n"
"\n"
"Это будет сделано сейчас автоматически.\n"
@@ -1473,12 +1534,15 @@ msgid ""
"\n"
"File %s has merge conflicts.\n"
"\n"
-"You must resolve them, stage the file, and commit to complete the current merge. Only then can you begin another merge.\n"
+"You must resolve them, stage the file, and commit to complete the current "
+"merge. Only then can you begin another merge.\n"
msgstr ""
"Предыдущее объединение не завершено из-за конфликта.\n"
"\n"
"Для файла %s возник конфликт объединения.\n"
-"Разрешите конфликт, подготовьте файл и сохраните. Только после этого можно начать следующее объединение.\n"
+"\n"
+"Разрешите конфликт, подготовьте файл и сохраните. Только после этого можно "
+"начать следующее объединение.\n"
#: lib/merge.tcl:54
#, tcl-format
@@ -1487,13 +1551,15 @@ msgid ""
"\n"
"File %s is modified.\n"
"\n"
-"You should complete the current commit before starting a merge. Doing so will help you abort a failed merge, should the need arise.\n"
+"You should complete the current commit before starting a merge. Doing so "
+"will help you abort a failed merge, should the need arise.\n"
msgstr ""
"Изменения не сохранены.\n"
"\n"
-"Файл %s изменен.\n"
+"Файл %s изменен.\n"
"\n"
-"Подготовьте и сохраните измения перед началом объединения. В случае необходимости это позволит прервать операцию объединения.\n"
+"Подготовьте и сохраните измения перед началом объединения. В случае "
+"необходимости это позволит прервать операцию объединения.\n"
#: lib/merge.tcl:106
#, tcl-format
@@ -1631,7 +1697,7 @@ msgstr "Шаблон для имени новой ветви"
#: lib/option.tcl:176
msgid "Change Font"
-msgstr "Шрифт интерфейса"
+msgstr "Изменить шрифт"
#: lib/option.tcl:180
#, tcl-format
@@ -1640,7 +1706,6 @@ msgstr "Выберите %s"
# carbon copy
#: lib/option.tcl:186
-#, fuzzy
msgid "pt."
msgstr ""
@@ -1652,18 +1717,6 @@ msgstr "Настройки"
msgid "Failed to completely save options:"
msgstr "Не удалось полностью сохранить настройки:"
-#: lib/remote.tcl:165
-msgid "Prune from"
-msgstr "Чистка"
-
-#: lib/remote.tcl:170
-msgid "Fetch from"
-msgstr "Получение из"
-
-#: lib/remote.tcl:213
-msgid "Push to"
-msgstr "Отправить"
-
#: lib/remote_branch_delete.tcl:29 lib/remote_branch_delete.tcl:34
msgid "Delete Remote Branch"
msgstr "Удалить внешнюю ветвь"
@@ -1707,16 +1760,17 @@ msgid ""
"\n"
" - %s"
msgstr ""
-"Следующие ветви объединены с %s не полностью:"
-"\n"
+"Следующие ветви объединены с %s не полностью:\n"
" - %s"
#: lib/remote_branch_delete.tcl:189
#, tcl-format
-msgid "One or more of the merge tests failed because you have not fetched the necessary commits. Try fetching from %s first."
+msgid ""
+"One or more of the merge tests failed because you have not fetched the "
+"necessary commits. Try fetching from %s first."
msgstr ""
-"Один или несколько тестов на объединение не прошли, потому что "
-"Вы не получили необходимые состояния. Попробуйте сначала получить их из %s."
+"Один или несколько тестов на объединение не прошли, потому что Вы не "
+"получили необходимые состояния. Попытайтесь получить их из %s."
#: lib/remote_branch_delete.tcl:207
msgid "Please select one or more branches to delete."
@@ -1746,11 +1800,23 @@ msgstr "Не указан репозиторий."
msgid "Scanning %s..."
msgstr "Перечитывание %s... "
-#: lib/shortcut.tcl:26 lib/shortcut.tcl:74
-msgid "Cannot write script:"
-msgstr "Невозможно записать скрипт:"
+#: lib/remote.tcl:165
+msgid "Prune from"
+msgstr "Чистка"
+
+#: lib/remote.tcl:170
+msgid "Fetch from"
+msgstr "Получение из"
+
+#: lib/remote.tcl:213
+msgid "Push to"
+msgstr "Отправить"
+
+#: lib/shortcut.tcl:20 lib/shortcut.tcl:61
+msgid "Cannot write shortcut:"
+msgstr "Невозможно записать ссылку:"
-#: lib/shortcut.tcl:149
+#: lib/shortcut.tcl:136
msgid "Cannot write icon:"
msgstr "Невозможно записать значок:"
@@ -1821,5 +1887,7 @@ msgstr "Использовать thin pack (для медленных сетев
#: lib/transport.tcl:168
msgid "Include tags"
-msgstr "Включить метки"
+msgstr "Передать таги"
+#~ msgid "Next >"
+#~ msgstr "Дальше >"
--
1.5.3.4.500.g3a531f
^ permalink raw reply related [relevance 3%]
* [PATCH] Implement git commit as a builtin command.
@ 2007-11-01 19:09 2% Kristian Høgsberg
0 siblings, 0 replies; 200+ results
From: Kristian Høgsberg @ 2007-11-01 19:09 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, Kristian Høgsberg
Move git-commit.sh to contrib/examples.
Signed-off-by: Kristian Høgsberg <krh@redhat.com>
---
Here's the builtin-commit patch again, this time updated to build
against the in-tree strbuf and option parser. Now that Pierre has
done all the work of getting those pieces upstream, I notice that the
C version ends up 20 lines shorter than the shell script :)
There's a couple of changes to the test suite at the end, which
removes some EDITOR=: VISUAL=: hard-coding in a few tests and then
sets the default editor to /bin/true. This is to address the problem
that the C version of launch editor doesn't support any kind of shell
qouting or built-ins. Should we just use system(3) here?
cheers,
Kristian
Makefile | 9 +-
builtin-commit.c | 608 ++++++++++++++++++++++++++++++++++++++
builtin-tag.c | 2 +-
builtin.h | 3 +-
contrib/examples/git-commit.sh | 628 ++++++++++++++++++++++++++++++++++++++++
git-commit.sh | 628 ----------------------------------------
git.c | 3 +-
strbuf.h | 1 +
t/t3501-revert-cherry-pick.sh | 4 +-
t/t3901-i18n-patch.sh | 8 +-
t/test-lib.sh | 4 +-
11 files changed, 1253 insertions(+), 645 deletions(-)
create mode 100644 builtin-commit.c
create mode 100755 contrib/examples/git-commit.sh
delete mode 100755 git-commit.sh
diff --git a/Makefile b/Makefile
index 042f79e..689eb33 100644
--- a/Makefile
+++ b/Makefile
@@ -209,7 +209,7 @@ BASIC_LDFLAGS =
SCRIPT_SH = \
git-bisect.sh git-checkout.sh \
- git-clean.sh git-clone.sh git-commit.sh \
+ git-clean.sh git-clone.sh \
git-ls-remote.sh \
git-merge-one-file.sh git-mergetool.sh git-parse-remote.sh \
git-pull.sh git-rebase.sh git-rebase--interactive.sh \
@@ -256,7 +256,7 @@ EXTRA_PROGRAMS =
BUILT_INS = \
git-format-patch$X git-show$X git-whatchanged$X git-cherry$X \
git-get-tar-commit-id$X git-init$X git-repo-config$X \
- git-fsck-objects$X git-cherry-pick$X \
+ git-fsck-objects$X git-cherry-pick$X git-status$X\
$(patsubst builtin-%.o,git-%$X,$(BUILTIN_OBJS))
# what 'all' will build and 'install' will install, in gitexecdir
@@ -326,6 +326,7 @@ BUILTIN_OBJS = \
builtin-check-attr.o \
builtin-checkout-index.o \
builtin-check-ref-format.o \
+ builtin-commit.o \
builtin-commit-tree.o \
builtin-count-objects.o \
builtin-describe.o \
@@ -364,7 +365,6 @@ BUILTIN_OBJS = \
builtin-rev-parse.o \
builtin-revert.o \
builtin-rm.o \
- builtin-runstatus.o \
builtin-shortlog.o \
builtin-show-branch.o \
builtin-stripspace.o \
@@ -830,9 +830,6 @@ $(patsubst %.perl,%,$(SCRIPT_PERL)): % : %.perl
chmod +x $@+ && \
mv $@+ $@
-git-status: git-commit
- $(QUIET_GEN)cp $< $@+ && mv $@+ $@
-
gitweb/gitweb.cgi: gitweb/gitweb.perl
$(QUIET_GEN)$(RM) $@ $@+ && \
sed -e '1s|#!.*perl|#!$(PERL_PATH_SQ)|' \
diff --git a/builtin-commit.c b/builtin-commit.c
new file mode 100644
index 0000000..56c7427
--- /dev/null
+++ b/builtin-commit.c
@@ -0,0 +1,608 @@
+/*
+ * Builtin "git commit"
+ *
+ * Copyright (c) 2007 Kristian Høgsberg <krh@redhat.com>
+ * Based on git-commit.sh by Junio C Hamano and Linus Torvalds
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "cache.h"
+#include "cache-tree.h"
+#include "builtin.h"
+#include "diff.h"
+#include "diffcore.h"
+#include "commit.h"
+#include "revision.h"
+#include "wt-status.h"
+#include "run-command.h"
+#include "refs.h"
+#include "log-tree.h"
+#include "strbuf.h"
+#include "utf8.h"
+#include "parse-options.h"
+
+static const char * const builtin_commit_usage[] = {
+ "git-commit [options] [--] <filepattern>...",
+ NULL
+};
+
+static unsigned char head_sha1[20], merge_head_sha1[20];
+static char *use_message_buffer;
+static const char commit_editmsg[] = "COMMIT_EDITMSG";
+static struct lock_file lock_file;
+
+static char *logfile, *force_author, *message, *template_file;
+static char *edit_message, *use_message;
+static int all, edit_flag, also, interactive, only, amend, signoff;
+static int quiet, verbose, untracked_files, no_verify;
+
+static int no_edit, initial_commit, in_merge;
+const char *only_include_assumed;
+
+static struct option builtin_commit_options[] = {
+ OPT__QUIET(&quiet),
+ OPT__VERBOSE(&verbose),
+ OPT_GROUP("Commit message options"),
+
+ OPT_STRING('F', "file", &logfile, "FILE", "read log from file"),
+ OPT_STRING(0, "author", &force_author, "AUTHOR", "override author for commit"),
+ OPT_STRING('m', "message", &message, "MESSAGE", "specify commit message"),
+ OPT_STRING('c', "reedit-message", &edit_message, "COMMIT", "reuse and edit message from specified commit "),
+ OPT_STRING('C', "reuse-message", &use_message, "COMMIT", "reuse message from specified commit"),
+ OPT_BOOLEAN('s', "signoff", &signoff, "add Signed-off-by: header"),
+ OPT_STRING('t', "template", &template_file, "FILE", "use specified template file"),
+ OPT_BOOLEAN('e', "edit", &edit_flag, "force edit of commit"),
+
+ OPT_GROUP("Commit contents options"),
+ OPT_BOOLEAN('a', "all", &all, "commit all changed files"),
+ OPT_BOOLEAN('i', "include", &also, "add specified files to index for commit"),
+ OPT_BOOLEAN(0, "interactive", &interactive, "interactively add files"),
+ OPT_BOOLEAN('o', "only", &only, ""),
+ OPT_BOOLEAN('n', "no-verify", &no_verify, "bypass pre-commit hook"),
+ OPT_BOOLEAN(0, "amend", &amend, "amend previous commit"),
+ OPT_BOOLEAN(0, "untracked-files", &untracked_files, "show all untracked files"),
+
+ OPT_END()
+};
+
+static char *
+prepare_index(const char **files, const char *prefix)
+{
+ int fd;
+ struct tree *tree;
+ struct lock_file *next_index_lock;
+
+ fd = hold_locked_index(&lock_file, 1);
+ if (read_cache() < 0)
+ die("index file corrupt");
+
+ if (all) {
+ add_files_to_cache(verbose, NULL, files);
+ if (write_cache(fd, active_cache, active_nr) || close(fd))
+ die("unable to write new_index file");
+ return lock_file.filename;
+ } else if (also) {
+ add_files_to_cache(verbose, prefix, files);
+ if (write_cache(fd, active_cache, active_nr) || close(fd))
+ die("unable to write new_index file");
+ return lock_file.filename;
+ }
+
+ if (interactive)
+ interactive_add();
+
+ if (*files == NULL) {
+ /* Commit index as-is. */
+ rollback_lock_file(&lock_file);
+ return get_index_file();
+ }
+
+ /* update the user index file */
+ add_files_to_cache(verbose, prefix, files);
+ if (write_cache(fd, active_cache, active_nr) || close(fd))
+ die("unable to write new_index file");
+
+ 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");
+ }
+
+ /* Uh oh, abusing lock_file to create a garbage collected file */
+ next_index_lock = xmalloc(sizeof(*next_index_lock));
+ fd = hold_lock_file_for_update(next_index_lock,
+ git_path("next-index-%d", getpid()), 1);
+ add_files_to_cache(verbose, prefix, files);
+ if (write_cache(fd, active_cache, active_nr) || close(fd))
+ die("unable to write new_index file");
+
+ return next_index_lock->filename;
+}
+
+static int run_status(FILE *fp, const char *index_file)
+{
+ struct wt_status s;
+
+ wt_status_prepare(&s);
+
+ if (amend) {
+ s.amend = 1;
+ s.reference = "HEAD^1";
+ }
+ s.verbose = verbose;
+ s.untracked = untracked_files;
+ s.index_file = index_file;
+ s.fp = fp;
+
+ wt_status_print(&s);
+
+ return s.commitable;
+}
+
+static const char sign_off_header[] = "Signed-off-by: ";
+
+static int prepare_log_message(const char *index_file)
+{
+ struct stat statbuf;
+ int commitable;
+ struct strbuf sb;
+ char *buffer;
+ FILE *fp;
+
+ strbuf_init(&sb, 0);
+ if (message) {
+ strbuf_add(&sb, message, strlen(message));
+ } else if (logfile && !strcmp(logfile, "-")) {
+ if (isatty(0))
+ fprintf(stderr, "(reading log message from standard input)\n");
+ if (strbuf_read(&sb, 0, 0) < 0)
+ die("could not read log from standard input");
+ } else if (logfile) {
+ if (strbuf_read_file(&sb, logfile, 0) < 0)
+ die("could not read log file '%s': %s",
+ logfile, strerror(errno));
+ } else if (use_message) {
+ buffer = strstr(use_message_buffer, "\n\n");
+ if (!buffer || buffer[2] == '\0')
+ die("commit has empty message");
+ strbuf_add(&sb, buffer + 2, strlen(buffer + 2));
+ } else if (!stat(git_path("MERGE_MSG"), &statbuf)) {
+ if (strbuf_read_file(&sb, git_path("MERGE_MSG"), 0) < 0)
+ die("could not read MERGE_MSG: %s", strerror(errno));
+ } else if (!stat(git_path("SQUASH_MSG"), &statbuf)) {
+ if (strbuf_read_file(&sb, git_path("SQUASH_MSG"), 0) < 0)
+ die("could not read SQUASH_MSG: %s", strerror(errno));
+ } else if (!stat(template_file, &statbuf)) {
+ if (strbuf_read_file(&sb, template_file, 0) < 0)
+ die("could not read %s: %s",
+ template_file, strerror(errno));
+ }
+
+ fp = fopen(git_path(commit_editmsg), "w");
+ if (fp == NULL)
+ die("could not open %s\n", git_path(commit_editmsg));
+
+ stripspace(&sb, 0);
+ if (fwrite(sb.buf, 1, sb.len, fp) < sb.len)
+ die("could not write commit template: %s\n",
+ strerror(errno));
+
+ if (signoff) {
+ const char *info, *bol;
+
+ info = git_committer_info(1);
+ strbuf_addch(&sb, '\0');
+ bol = strrchr(sb.buf + sb.len - 1, '\n');
+ if (!bol || prefixcmp(bol, sign_off_header))
+ fprintf(fp, "\n");
+ fprintf(fp, "%s%s\n", sign_off_header, git_committer_info(1));
+ }
+
+ strbuf_release(&sb);
+
+ if (in_merge && !no_edit) {
+ fprintf(fp,
+ "#\n"
+ "# It looks like you may be committing a MERGE.\n"
+ "# If this is not correct, please remove the file\n"
+ "# %s\n"
+ "# and try again.\n"
+ "#\n",
+ git_path("MERGE_HEAD"));
+ }
+
+ fprintf(fp,
+ "\n"
+ "# Please enter the commit message for your changes.\n"
+ "# (Comment lines starting with '#' will not be included)\n");
+ if (only_include_assumed)
+ fprintf(fp, "# %s\n", only_include_assumed);
+
+ commitable = run_status(fp, index_file);
+
+ fclose(fp);
+
+ return commitable;
+}
+
+/* Find out if the message starting at position 'start' in the strbuf
+ * contains only whitespace and Signed-off-by lines. */
+static int message_is_empty(struct strbuf *sb, int start)
+{
+ struct strbuf tmpl;
+ const char *nl;
+ int eol, i;
+
+ /* See if the template is just a prefix of the message. */
+ strbuf_init(&tmpl, 0);
+ if (template_file && strbuf_read_file(&tmpl, template_file, 0) > 0) {
+ stripspace(&tmpl, 1);
+ if (start + tmpl.len <= sb->len &&
+ memcmp(tmpl.buf, sb->buf + start, tmpl.len) == 0)
+ start += tmpl.len;
+ }
+ strbuf_release(&tmpl);
+
+ /* Check if the rest is just whitespace and Signed-of-by's. */
+ for (i = start; i < sb->len; i++) {
+ nl = memchr(sb->buf + i, '\n', sb->len - i);
+ if (nl)
+ eol = nl - sb->buf;
+ else
+ eol = sb->len;
+
+ if (strlen(sign_off_header) <= eol - i &&
+ !prefixcmp(sb->buf + i, sign_off_header)) {
+ i = eol;
+ continue;
+ }
+ while (i < eol)
+ if (!isspace(sb->buf[i++]))
+ return 0;
+ }
+
+ return 1;
+}
+
+static void determine_author_info(struct strbuf *sb)
+{
+ char *p, *eol;
+ char *name = NULL, *email = NULL;
+
+ if (use_message) {
+ p = strstr(use_message_buffer, "\nauthor");
+ if (!p)
+ die("invalid commit: %s\n", use_message);
+ p++;
+ eol = strchr(p, '\n');
+ if (!eol)
+ die("invalid commit: %s\n", use_message);
+
+ strbuf_add(sb, p, eol + 1 - p);
+ } else if (force_author) {
+ const char *eoname = strstr(force_author, " <");
+ const char *eomail = strchr(force_author, '>');
+
+ if (!eoname || !eomail)
+ die("malformed --author parameter\n");
+ name = xstrndup(force_author, eoname - force_author);
+ email = xstrndup(eoname + 2, eomail - eoname - 2);
+ strbuf_addf(sb, "author %s\n",
+ fmt_ident(name, email,
+ getenv("GIT_AUTHOR_DATE"), 1));
+ free(name);
+ free(email);
+ } else {
+ strbuf_addf(sb, "author %s\n", git_author_info(1));
+ }
+}
+
+static int parse_and_validate_options(int argc, const char *argv[])
+{
+ int f = 0;
+
+ argc = parse_options(argc, argv, builtin_commit_options,
+ builtin_commit_usage, 0);
+
+ if (logfile || message || use_message)
+ no_edit = 1;
+ if (edit_flag)
+ no_edit = 0;
+
+ if (get_sha1("HEAD", head_sha1))
+ initial_commit = 1;
+
+ if (!get_sha1("MERGE_HEAD", merge_head_sha1))
+ in_merge = 1;
+
+ /* Sanity check options */
+ if (amend && initial_commit)
+ die("You have nothing to amend.");
+ if (amend && in_merge)
+ die("You are in the middle of a merger -- cannot amend.");
+
+ if (use_message)
+ f++;
+ if (edit_message)
+ f++;
+ if (logfile)
+ f++;
+ if (f > 1)
+ die("Only one of -c/-C/-F can be used.");
+ if (message && f > 0)
+ die("Option -m cannot be combined with -c/-C/-F.");
+ if (edit_message)
+ use_message = edit_message;
+ if (amend)
+ use_message = "HEAD";
+ if (use_message) {
+ unsigned char sha1[20];
+ static char utf8[] = "UTF-8";
+ const char *out_enc;
+ char *enc, *end;
+ struct commit *commit;
+
+ if (get_sha1(use_message, sha1))
+ die("could not lookup commit %s", use_message);
+ commit = lookup_commit(sha1);
+ if (!commit || parse_commit(commit))
+ die("could not parse commit %s", use_message);
+
+ enc = strstr(commit->buffer, "\nencoding");
+ if (enc) {
+ end = strchr(enc + 10, '\n');
+ enc = xstrndup(enc + 10, end - (enc + 10));
+ } else {
+ enc = utf8;
+ }
+ out_enc = git_commit_encoding ? git_commit_encoding : utf8;
+
+ use_message_buffer =
+ reencode_string(commit->buffer, out_enc, enc);
+ if (enc != utf8)
+ free(enc);
+ }
+
+ if (also && only)
+ die("Only one of --include/--only can be used.");
+ if (!*argv && (also || (only && !amend)))
+ die("No paths with --include/--only does not make sense.");
+ if (!*argv && only && amend)
+ only_include_assumed = "Clever... amending the last one with dirty index.";
+ if (*argv && !also && !only) {
+ only_include_assumed = "Explicit paths specified without -i nor -o; assuming --only paths...";
+ also = 0;
+ }
+
+ if (all && interactive)
+ die("Cannot use -a, --interactive or -i at the same time.");
+ else if (all && argc > 0)
+ die("Paths with -a does not make sense.");
+ else if (interactive && **argv)
+ die("Paths with --interactive does not make sense.");
+
+ return argc;
+}
+
+int cmd_status(int argc, const char **argv, const char *prefix)
+{
+ const char *index_file;
+ int commitable;
+
+ git_config(git_status_config);
+
+ argc = parse_and_validate_options(argc, argv);
+
+ index_file = prepare_index(argv, prefix);
+
+ commitable = run_status(stdout, index_file);
+
+ rollback_lock_file(&lock_file);
+
+ return commitable ? 0 : 1;
+}
+
+static int run_hook(const char *index_file, const char *name, const char *arg)
+{
+ struct child_process hook;
+ const char *argv[3], *env[2];
+ char index[PATH_MAX];
+
+ argv[0] = git_path("hooks/%s", name);
+ argv[1] = arg;
+ argv[2] = NULL;
+ snprintf(index, sizeof(index), "GIT_INDEX_FILE=%s", index_file);
+ env[0] = index;
+ env[1] = NULL;
+
+ if (access(argv[0], X_OK) < 0)
+ return 0;
+
+ memset(&hook, 0, sizeof(hook));
+ hook.argv = argv;
+ hook.no_stdin = 1;
+ hook.stdout_to_stderr = 1;
+ hook.env = env;
+
+ return run_command(&hook);
+}
+
+static void print_summary(const char *prefix, const unsigned char *sha1)
+{
+ struct rev_info rev;
+ struct commit *commit;
+
+ commit = lookup_commit(sha1);
+ if (!commit)
+ die("couldn't look up newly created commit\n");
+ if (!commit || parse_commit(commit))
+ die("could not parse newly created commit");
+
+ init_revisions(&rev, prefix);
+ setup_revisions(0, NULL, &rev, NULL);
+
+ rev.abbrev = 0;
+ rev.diff = 1;
+ rev.diffopt.output_format =
+ DIFF_FORMAT_SHORTSTAT | DIFF_FORMAT_SUMMARY;
+
+ rev.verbose_header = 1;
+ rev.show_root_diff = 1;
+ rev.commit_format = get_commit_format("format:%h: %s");
+ rev.always_show_header = 1;
+
+ printf("Created %scommit ", initial_commit ? "initial " : "");
+
+ log_tree_commit(&rev, commit);
+}
+
+int git_commit_config(const char *k, const char *v)
+{
+ if (!strcmp(k, "commit.template")) {
+ template_file = xstrdup(v);
+ return 0;
+ }
+
+ return git_status_config(k, v);
+}
+
+static const char commit_utf8_warn[] =
+"Warning: commit message does not conform to UTF-8.\n"
+"You may want to amend it after fixing the message, or set the config\n"
+"variable i18n.commitencoding to the encoding your project uses.\n";
+
+int cmd_commit(int argc, const char **argv, const char *prefix)
+{
+ int header_len, parent_count = 0;
+ struct strbuf sb;
+ const char *index_file, *reflog_msg;
+ char *nl, *header_line;
+ unsigned char commit_sha1[20];
+ struct ref_lock *ref_lock;
+
+ git_config(git_commit_config);
+
+ argc = parse_and_validate_options(argc, argv);
+
+ index_file = prepare_index(argv, prefix);
+
+ if (!no_verify && run_hook(index_file, "pre-commit", NULL))
+ exit(1);
+
+ if (!prepare_log_message(index_file) && !in_merge) {
+ run_status(stdout, index_file);
+ unlink(commit_editmsg);
+ return 1;
+ }
+
+ strbuf_init(&sb, 0);
+
+ /* Start building up the commit header */
+ read_cache_from(index_file);
+ active_cache_tree = cache_tree();
+ if (cache_tree_update(active_cache_tree,
+ active_cache, active_nr, 0, 0) < 0)
+ die("Error building trees");
+ strbuf_addf(&sb, "tree %s\n",
+ sha1_to_hex(active_cache_tree->sha1));
+
+ /* Determine parents */
+ if (initial_commit) {
+ reflog_msg = "commit (initial)";
+ parent_count = 0;
+ } else if (amend) {
+ struct commit_list *c;
+ struct commit *commit;
+
+ reflog_msg = "commit (amend)";
+ commit = lookup_commit(head_sha1);
+ if (!commit || parse_commit(commit))
+ die("could not parse HEAD commit");
+
+ for (c = commit->parents; c; c = c->next)
+ strbuf_addf(&sb, "parent %s\n",
+ sha1_to_hex(c->item->object.sha1));
+ } else if (in_merge) {
+ struct strbuf m;
+ FILE *fp;
+
+ reflog_msg = "commit (merge)";
+ strbuf_addf(&sb, "parent %s\n", sha1_to_hex(head_sha1));
+ strbuf_init(&m, 0);
+ fp = fopen(git_path("MERGE_HEAD"), "r");
+ if (fp == NULL)
+ die("could not open %s for reading: %s",
+ git_path("MERGE_HEAD"), strerror(errno));
+ while (strbuf_getline(&m, fp, '\n') != EOF)
+ strbuf_addf(&sb, "parent %s\n", m.buf);
+ fclose(fp);
+ strbuf_release(&m);
+ } else {
+ reflog_msg = "commit";
+ strbuf_addf(&sb, "parent %s\n", sha1_to_hex(head_sha1));
+ }
+
+ determine_author_info(&sb);
+ strbuf_addf(&sb, "committer %s\n", git_committer_info(1));
+ if (!is_encoding_utf8(git_commit_encoding))
+ strbuf_addf(&sb, "encoding %s\n", git_commit_encoding);
+ strbuf_addch(&sb, '\n');
+
+ /* Get the commit message and validate it */
+ header_len = sb.len;
+ if (!no_edit) {
+ fprintf(stderr, "launching editor, log %s\n", logfile);
+ launch_editor(git_path(commit_editmsg), &sb);
+ }
+ else if (strbuf_read_file(&sb, git_path(commit_editmsg), 0) < 0)
+ die("could not read commit message\n");
+ if (run_hook(index_file, "commit-msg", commit_editmsg))
+ exit(1);
+ stripspace(&sb, 1);
+ if (sb.len < header_len ||
+ message_is_empty(&sb, header_len))
+ die("* no commit message? aborting commit.");
+ strbuf_addch(&sb, '\0');
+ if (is_encoding_utf8(git_commit_encoding) && !is_utf8(sb.buf))
+ fprintf(stderr, commit_utf8_warn);
+
+ if (write_sha1_file(sb.buf, sb.len - 1, commit_type, commit_sha1))
+ die("failed to write commit object");
+
+ ref_lock = lock_any_ref_for_update("HEAD",
+ initial_commit ? NULL : head_sha1,
+ 0);
+
+ nl = strchr(sb.buf + header_len, '\n');
+ header_line = xstrndup(sb.buf + header_len,
+ nl - (sb.buf + header_len));
+ strbuf_release(&sb);
+ strbuf_addf(&sb, "%s: %s\n", reflog_msg, header_line);
+ strbuf_addch(&sb, '\0');
+ free(header_line);
+
+ if (!ref_lock)
+ die("cannot lock HEAD ref");
+ if (write_ref_sha1(ref_lock, commit_sha1, sb.buf) < 0)
+ die("cannot update HEAD ref");
+
+ unlink(git_path("MERGE_HEAD"));
+ unlink(git_path("MERGE_MSG"));
+
+ if (lock_file.filename[0] && commit_locked_index(&lock_file))
+ die("failed to write new index");
+
+ rerere();
+
+ run_hook(index_file, "post-commit", NULL);
+
+ if (!quiet)
+ print_summary(prefix, commit_sha1);
+
+ return 0;
+}
diff --git a/builtin-tag.c b/builtin-tag.c
index 66e5a58..e6bae69 100644
--- a/builtin-tag.c
+++ b/builtin-tag.c
@@ -17,7 +17,7 @@ static const char builtin_tag_usage[] =
static char signingkey[1000];
-static void launch_editor(const char *path, struct strbuf *buffer)
+void launch_editor(const char *path, struct strbuf *buffer)
{
const char *editor, *terminal;
struct child_process child;
diff --git a/builtin.h b/builtin.h
index 9a6213a..0f8456c 100644
--- a/builtin.h
+++ b/builtin.h
@@ -24,6 +24,7 @@ extern int cmd_check_attr(int argc, const char **argv, const char *prefix);
extern int cmd_check_ref_format(int argc, const char **argv, const char *prefix);
extern int cmd_cherry(int argc, const char **argv, const char *prefix);
extern int cmd_cherry_pick(int argc, const char **argv, const char *prefix);
+extern int cmd_commit(int argc, const char **argv, const char *prefix);
extern int cmd_commit_tree(int argc, const char **argv, const char *prefix);
extern int cmd_count_objects(int argc, const char **argv, const char *prefix);
extern int cmd_describe(int argc, const char **argv, const char *prefix);
@@ -68,10 +69,10 @@ extern int cmd_rev_list(int argc, const char **argv, const char *prefix);
extern int cmd_rev_parse(int argc, const char **argv, const char *prefix);
extern int cmd_revert(int argc, const char **argv, const char *prefix);
extern int cmd_rm(int argc, const char **argv, const char *prefix);
-extern int cmd_runstatus(int argc, const char **argv, const char *prefix);
extern int cmd_shortlog(int argc, const char **argv, const char *prefix);
extern int cmd_show(int argc, const char **argv, const char *prefix);
extern int cmd_show_branch(int argc, const char **argv, const char *prefix);
+extern int cmd_status(int argc, const char **argv, const char *prefix);
extern int cmd_stripspace(int argc, const char **argv, const char *prefix);
extern int cmd_symbolic_ref(int argc, const char **argv, const char *prefix);
extern int cmd_tag(int argc, const char **argv, const char *prefix);
diff --git a/contrib/examples/git-commit.sh b/contrib/examples/git-commit.sh
new file mode 100755
index 0000000..fcb8443
--- /dev/null
+++ b/contrib/examples/git-commit.sh
@@ -0,0 +1,628 @@
+#!/bin/sh
+#
+# Copyright (c) 2005 Linus Torvalds
+# Copyright (c) 2006 Junio C Hamano
+
+USAGE='[-a | --interactive] [-s] [-v] [--no-verify] [-m <message> | -F <logfile> | (-C|-c) <commit> | --amend] [-u] [-e] [--author <author>] [--template <file>] [[-i | -o] <path>...]'
+SUBDIRECTORY_OK=Yes
+. git-sh-setup
+require_work_tree
+
+git rev-parse --verify HEAD >/dev/null 2>&1 || initial_commit=t
+
+case "$0" in
+*status)
+ status_only=t
+ ;;
+*commit)
+ status_only=
+ ;;
+esac
+
+refuse_partial () {
+ echo >&2 "$1"
+ echo >&2 "You might have meant to say 'git commit -i paths...', perhaps?"
+ exit 1
+}
+
+TMP_INDEX=
+THIS_INDEX="$GIT_DIR/index"
+NEXT_INDEX="$GIT_DIR/next-index$$"
+rm -f "$NEXT_INDEX"
+save_index () {
+ cp -p "$THIS_INDEX" "$NEXT_INDEX"
+}
+
+run_status () {
+ # If TMP_INDEX is defined, that means we are doing
+ # "--only" partial commit, and that index file is used
+ # to build the tree for the commit. Otherwise, if
+ # NEXT_INDEX exists, that is the index file used to
+ # make the commit. Otherwise we are using as-is commit
+ # so the regular index file is what we use to compare.
+ if test '' != "$TMP_INDEX"
+ then
+ GIT_INDEX_FILE="$TMP_INDEX"
+ export GIT_INDEX_FILE
+ elif test -f "$NEXT_INDEX"
+ then
+ GIT_INDEX_FILE="$NEXT_INDEX"
+ export GIT_INDEX_FILE
+ fi
+
+ if test "$status_only" = "t" -o "$use_status_color" = "t"; then
+ color=
+ else
+ color=--nocolor
+ fi
+ git runstatus ${color} \
+ ${verbose:+--verbose} \
+ ${amend:+--amend} \
+ ${untracked_files:+--untracked}
+}
+
+trap '
+ test -z "$TMP_INDEX" || {
+ test -f "$TMP_INDEX" && rm -f "$TMP_INDEX"
+ }
+ rm -f "$NEXT_INDEX"
+' 0
+
+################################################################
+# Command line argument parsing and sanity checking
+
+all=
+also=
+interactive=
+only=
+logfile=
+use_commit=
+amend=
+edit_flag=
+no_edit=
+log_given=
+log_message=
+verify=t
+quiet=
+verbose=
+signoff=
+force_author=
+only_include_assumed=
+untracked_files=
+templatefile="`git config commit.template`"
+while test $# != 0
+do
+ case "$1" in
+ -F|--F|-f|--f|--fi|--fil|--file)
+ case "$#" in 1) usage ;; esac
+ shift
+ no_edit=t
+ log_given=t$log_given
+ logfile="$1"
+ ;;
+ -F*|-f*)
+ no_edit=t
+ log_given=t$log_given
+ logfile="${1#-[Ff]}"
+ ;;
+ --F=*|--f=*|--fi=*|--fil=*|--file=*)
+ no_edit=t
+ log_given=t$log_given
+ logfile="${1#*=}"
+ ;;
+ -a|--a|--al|--all)
+ all=t
+ ;;
+ --au=*|--aut=*|--auth=*|--autho=*|--author=*)
+ force_author="${1#*=}"
+ ;;
+ --au|--aut|--auth|--autho|--author)
+ case "$#" in 1) usage ;; esac
+ shift
+ force_author="$1"
+ ;;
+ -e|--e|--ed|--edi|--edit)
+ edit_flag=t
+ ;;
+ -i|--i|--in|--inc|--incl|--inclu|--includ|--include)
+ also=t
+ ;;
+ --int|--inte|--inter|--intera|--interac|--interact|--interacti|\
+ --interactiv|--interactive)
+ interactive=t
+ ;;
+ -o|--o|--on|--onl|--only)
+ only=t
+ ;;
+ -m|--m|--me|--mes|--mess|--messa|--messag|--message)
+ case "$#" in 1) usage ;; esac
+ shift
+ log_given=m$log_given
+ log_message="${log_message:+${log_message}
+
+}$1"
+ no_edit=t
+ ;;
+ -m*)
+ log_given=m$log_given
+ log_message="${log_message:+${log_message}
+
+}${1#-m}"
+ no_edit=t
+ ;;
+ --m=*|--me=*|--mes=*|--mess=*|--messa=*|--messag=*|--message=*)
+ log_given=m$log_given
+ log_message="${log_message:+${log_message}
+
+}${1#*=}"
+ no_edit=t
+ ;;
+ -n|--n|--no|--no-|--no-v|--no-ve|--no-ver|--no-veri|--no-verif|\
+ --no-verify)
+ verify=
+ ;;
+ --a|--am|--ame|--amen|--amend)
+ amend=t
+ use_commit=HEAD
+ ;;
+ -c)
+ case "$#" in 1) usage ;; esac
+ shift
+ log_given=t$log_given
+ use_commit="$1"
+ no_edit=
+ ;;
+ --ree=*|--reed=*|--reedi=*|--reedit=*|--reedit-=*|--reedit-m=*|\
+ --reedit-me=*|--reedit-mes=*|--reedit-mess=*|--reedit-messa=*|\
+ --reedit-messag=*|--reedit-message=*)
+ log_given=t$log_given
+ use_commit="${1#*=}"
+ no_edit=
+ ;;
+ --ree|--reed|--reedi|--reedit|--reedit-|--reedit-m|--reedit-me|\
+ --reedit-mes|--reedit-mess|--reedit-messa|--reedit-messag|\
+ --reedit-message)
+ case "$#" in 1) usage ;; esac
+ shift
+ log_given=t$log_given
+ use_commit="$1"
+ no_edit=
+ ;;
+ -C)
+ case "$#" in 1) usage ;; esac
+ shift
+ log_given=t$log_given
+ use_commit="$1"
+ no_edit=t
+ ;;
+ --reu=*|--reus=*|--reuse=*|--reuse-=*|--reuse-m=*|--reuse-me=*|\
+ --reuse-mes=*|--reuse-mess=*|--reuse-messa=*|--reuse-messag=*|\
+ --reuse-message=*)
+ log_given=t$log_given
+ use_commit="${1#*=}"
+ no_edit=t
+ ;;
+ --reu|--reus|--reuse|--reuse-|--reuse-m|--reuse-me|--reuse-mes|\
+ --reuse-mess|--reuse-messa|--reuse-messag|--reuse-message)
+ case "$#" in 1) usage ;; esac
+ shift
+ log_given=t$log_given
+ use_commit="$1"
+ no_edit=t
+ ;;
+ -s|--s|--si|--sig|--sign|--signo|--signof|--signoff)
+ signoff=t
+ ;;
+ -t|--t|--te|--tem|--temp|--templ|--templa|--templat|--template)
+ case "$#" in 1) usage ;; esac
+ shift
+ templatefile="$1"
+ no_edit=
+ ;;
+ -q|--q|--qu|--qui|--quie|--quiet)
+ quiet=t
+ ;;
+ -v|--v|--ve|--ver|--verb|--verbo|--verbos|--verbose)
+ verbose=t
+ ;;
+ -u|--u|--un|--unt|--untr|--untra|--untrac|--untrack|--untracke|\
+ --untracked|--untracked-|--untracked-f|--untracked-fi|--untracked-fil|\
+ --untracked-file|--untracked-files)
+ untracked_files=t
+ ;;
+ --)
+ shift
+ break
+ ;;
+ -*)
+ usage
+ ;;
+ *)
+ break
+ ;;
+ esac
+ shift
+done
+case "$edit_flag" in t) no_edit= ;; esac
+
+################################################################
+# Sanity check options
+
+case "$amend,$initial_commit" in
+t,t)
+ die "You do not have anything to amend." ;;
+t,)
+ if [ -f "$GIT_DIR/MERGE_HEAD" ]; then
+ die "You are in the middle of a merge -- cannot amend."
+ fi ;;
+esac
+
+case "$log_given" in
+tt*)
+ die "Only one of -c/-C/-F can be used." ;;
+*tm*|*mt*)
+ die "Option -m cannot be combined with -c/-C/-F." ;;
+esac
+
+case "$#,$also,$only,$amend" in
+*,t,t,*)
+ die "Only one of --include/--only can be used." ;;
+0,t,,* | 0,,t,)
+ die "No paths with --include/--only does not make sense." ;;
+0,,t,t)
+ only_include_assumed="# Clever... amending the last one with dirty index." ;;
+0,,,*)
+ ;;
+*,,,*)
+ only_include_assumed="# Explicit paths specified without -i nor -o; assuming --only paths..."
+ also=
+ ;;
+esac
+unset only
+case "$all,$interactive,$also,$#" in
+*t,*t,*)
+ die "Cannot use -a, --interactive or -i at the same time." ;;
+t,,[1-9]*)
+ die "Paths with -a does not make sense." ;;
+,t,[1-9]*)
+ die "Paths with --interactive does not make sense." ;;
+,,t,0)
+ die "No paths with -i does not make sense." ;;
+esac
+
+if test ! -z "$templatefile" -a -z "$log_given"
+then
+ if test ! -f "$templatefile"
+ then
+ die "Commit template file does not exist."
+ fi
+fi
+
+################################################################
+# Prepare index to have a tree to be committed
+
+case "$all,$also" in
+t,)
+ if test ! -f "$THIS_INDEX"
+ then
+ die 'nothing to commit (use "git add file1 file2" to include for commit)'
+ fi
+ save_index &&
+ (
+ cd_to_toplevel &&
+ GIT_INDEX_FILE="$NEXT_INDEX" &&
+ export GIT_INDEX_FILE &&
+ git diff-files --name-only -z |
+ git update-index --remove -z --stdin
+ ) || exit
+ ;;
+,t)
+ save_index &&
+ git ls-files --error-unmatch -- "$@" >/dev/null || exit
+
+ git diff-files --name-only -z -- "$@" |
+ (
+ cd_to_toplevel &&
+ GIT_INDEX_FILE="$NEXT_INDEX" &&
+ export GIT_INDEX_FILE &&
+ git update-index --remove -z --stdin
+ ) || exit
+ ;;
+,)
+ if test "$interactive" = t; then
+ git add --interactive || exit
+ fi
+ case "$#" in
+ 0)
+ ;; # commit as-is
+ *)
+ if test -f "$GIT_DIR/MERGE_HEAD"
+ then
+ refuse_partial "Cannot do a partial commit during a merge."
+ fi
+
+ TMP_INDEX="$GIT_DIR/tmp-index$$"
+ W=
+ test -z "$initial_commit" && W=--with-tree=HEAD
+ commit_only=`git ls-files --error-unmatch $W -- "$@"` || exit
+
+ # Build a temporary index and update the real index
+ # the same way.
+ if test -z "$initial_commit"
+ then
+ GIT_INDEX_FILE="$THIS_INDEX" \
+ git read-tree --index-output="$TMP_INDEX" -i -m HEAD
+ else
+ rm -f "$TMP_INDEX"
+ fi || exit
+
+ printf '%s\n' "$commit_only" |
+ GIT_INDEX_FILE="$TMP_INDEX" \
+ git update-index --add --remove --stdin &&
+
+ save_index &&
+ printf '%s\n' "$commit_only" |
+ (
+ GIT_INDEX_FILE="$NEXT_INDEX"
+ export GIT_INDEX_FILE
+ git update-index --add --remove --stdin
+ ) || exit
+ ;;
+ esac
+ ;;
+esac
+
+################################################################
+# If we do as-is commit, the index file will be THIS_INDEX,
+# otherwise NEXT_INDEX after we make this commit. We leave
+# the index as is if we abort.
+
+if test -f "$NEXT_INDEX"
+then
+ USE_INDEX="$NEXT_INDEX"
+else
+ USE_INDEX="$THIS_INDEX"
+fi
+
+case "$status_only" in
+t)
+ # This will silently fail in a read-only repository, which is
+ # what we want.
+ GIT_INDEX_FILE="$USE_INDEX" git update-index -q --unmerged --refresh
+ run_status
+ exit $?
+ ;;
+'')
+ GIT_INDEX_FILE="$USE_INDEX" git update-index -q --refresh || exit
+ ;;
+esac
+
+################################################################
+# Grab commit message, write out tree and make commit.
+
+if test t = "$verify" && test -x "$GIT_DIR"/hooks/pre-commit
+then
+ GIT_INDEX_FILE="${TMP_INDEX:-${USE_INDEX}}" "$GIT_DIR"/hooks/pre-commit \
+ || exit
+fi
+
+if test "$log_message" != ''
+then
+ printf '%s\n' "$log_message"
+elif test "$logfile" != ""
+then
+ if test "$logfile" = -
+ then
+ test -t 0 &&
+ echo >&2 "(reading log message from standard input)"
+ cat
+ else
+ cat <"$logfile"
+ fi
+elif test "$use_commit" != ""
+then
+ encoding=$(git config i18n.commitencoding || echo UTF-8)
+ git show -s --pretty=raw --encoding="$encoding" "$use_commit" |
+ sed -e '1,/^$/d' -e 's/^ //'
+elif test -f "$GIT_DIR/MERGE_MSG"
+then
+ cat "$GIT_DIR/MERGE_MSG"
+elif test -f "$GIT_DIR/SQUASH_MSG"
+then
+ cat "$GIT_DIR/SQUASH_MSG"
+elif test "$templatefile" != ""
+then
+ cat "$templatefile"
+fi | git stripspace >"$GIT_DIR"/COMMIT_EDITMSG
+
+case "$signoff" in
+t)
+ sign=$(git-var GIT_COMMITTER_IDENT | sed -e '
+ s/>.*/>/
+ s/^/Signed-off-by: /
+ ')
+ blank_before_signoff=
+ tail -n 1 "$GIT_DIR"/COMMIT_EDITMSG |
+ grep 'Signed-off-by:' >/dev/null || blank_before_signoff='
+'
+ tail -n 1 "$GIT_DIR"/COMMIT_EDITMSG |
+ grep "$sign"$ >/dev/null ||
+ printf '%s%s\n' "$blank_before_signoff" "$sign" \
+ >>"$GIT_DIR"/COMMIT_EDITMSG
+ ;;
+esac
+
+if test -f "$GIT_DIR/MERGE_HEAD" && test -z "$no_edit"; then
+ echo "#"
+ echo "# It looks like you may be committing a MERGE."
+ echo "# If this is not correct, please remove the file"
+ printf '%s\n' "# $GIT_DIR/MERGE_HEAD"
+ echo "# and try again"
+ echo "#"
+fi >>"$GIT_DIR"/COMMIT_EDITMSG
+
+# Author
+if test '' != "$use_commit"
+then
+ eval "$(get_author_ident_from_commit "$use_commit")"
+ export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_AUTHOR_DATE
+fi
+if test '' != "$force_author"
+then
+ GIT_AUTHOR_NAME=`expr "z$force_author" : 'z\(.*[^ ]\) *<.*'` &&
+ GIT_AUTHOR_EMAIL=`expr "z$force_author" : '.*\(<.*\)'` &&
+ test '' != "$GIT_AUTHOR_NAME" &&
+ test '' != "$GIT_AUTHOR_EMAIL" ||
+ die "malformed --author parameter"
+ export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL
+fi
+
+PARENTS="-p HEAD"
+if test -z "$initial_commit"
+then
+ rloga='commit'
+ if [ -f "$GIT_DIR/MERGE_HEAD" ]; then
+ rloga='commit (merge)'
+ PARENTS="-p HEAD "`sed -e 's/^/-p /' "$GIT_DIR/MERGE_HEAD"`
+ elif test -n "$amend"; then
+ rloga='commit (amend)'
+ PARENTS=$(git cat-file commit HEAD |
+ sed -n -e '/^$/q' -e 's/^parent /-p /p')
+ fi
+ current="$(git rev-parse --verify HEAD)"
+else
+ if [ -z "$(git ls-files)" ]; then
+ echo >&2 'nothing to commit (use "git add file1 file2" to include for commit)'
+ exit 1
+ fi
+ PARENTS=""
+ rloga='commit (initial)'
+ current=''
+fi
+set_reflog_action "$rloga"
+
+if test -z "$no_edit"
+then
+ {
+ echo ""
+ echo "# Please enter the commit message for your changes."
+ echo "# (Comment lines starting with '#' will not be included)"
+ test -z "$only_include_assumed" || echo "$only_include_assumed"
+ run_status
+ } >>"$GIT_DIR"/COMMIT_EDITMSG
+else
+ # we need to check if there is anything to commit
+ run_status >/dev/null
+fi
+if [ "$?" != "0" -a ! -f "$GIT_DIR/MERGE_HEAD" ]
+then
+ rm -f "$GIT_DIR/COMMIT_EDITMSG" "$GIT_DIR/SQUASH_MSG"
+ use_status_color=t
+ run_status
+ exit 1
+fi
+
+case "$no_edit" in
+'')
+ git-var GIT_AUTHOR_IDENT > /dev/null || die
+ git-var GIT_COMMITTER_IDENT > /dev/null || die
+ git_editor "$GIT_DIR/COMMIT_EDITMSG"
+ ;;
+esac
+
+case "$verify" in
+t)
+ if test -x "$GIT_DIR"/hooks/commit-msg
+ then
+ "$GIT_DIR"/hooks/commit-msg "$GIT_DIR"/COMMIT_EDITMSG || exit
+ fi
+esac
+
+if test -z "$no_edit"
+then
+ sed -e '
+ /^diff --git a\/.*/{
+ s///
+ q
+ }
+ /^#/d
+ ' "$GIT_DIR"/COMMIT_EDITMSG
+else
+ cat "$GIT_DIR"/COMMIT_EDITMSG
+fi |
+git stripspace >"$GIT_DIR"/COMMIT_MSG
+
+# Test whether the commit message has any content we didn't supply.
+have_commitmsg=
+grep -v -i '^Signed-off-by' "$GIT_DIR"/COMMIT_MSG |
+ git stripspace > "$GIT_DIR"/COMMIT_BAREMSG
+
+# Is the commit message totally empty?
+if test -s "$GIT_DIR"/COMMIT_BAREMSG
+then
+ if test "$templatefile" != ""
+ then
+ # Test whether this is just the unaltered template.
+ if cnt=`sed -e '/^#/d' < "$templatefile" |
+ git stripspace |
+ diff "$GIT_DIR"/COMMIT_BAREMSG - |
+ wc -l` &&
+ test 0 -lt $cnt
+ then
+ have_commitmsg=t
+ fi
+ else
+ # No template, so the content in the commit message must
+ # have come from the user.
+ have_commitmsg=t
+ fi
+fi
+
+rm -f "$GIT_DIR"/COMMIT_BAREMSG
+
+if test "$have_commitmsg" = "t"
+then
+ if test -z "$TMP_INDEX"
+ then
+ tree=$(GIT_INDEX_FILE="$USE_INDEX" git write-tree)
+ else
+ tree=$(GIT_INDEX_FILE="$TMP_INDEX" git write-tree) &&
+ rm -f "$TMP_INDEX"
+ fi &&
+ commit=$(git commit-tree $tree $PARENTS <"$GIT_DIR/COMMIT_MSG") &&
+ rlogm=$(sed -e 1q "$GIT_DIR"/COMMIT_MSG) &&
+ git update-ref -m "$GIT_REFLOG_ACTION: $rlogm" HEAD $commit "$current" &&
+ rm -f -- "$GIT_DIR/MERGE_HEAD" "$GIT_DIR/MERGE_MSG" &&
+ if test -f "$NEXT_INDEX"
+ then
+ mv "$NEXT_INDEX" "$THIS_INDEX"
+ else
+ : ;# happy
+ fi
+else
+ echo >&2 "* no commit message? aborting commit."
+ false
+fi
+ret="$?"
+rm -f "$GIT_DIR/COMMIT_MSG" "$GIT_DIR/COMMIT_EDITMSG" "$GIT_DIR/SQUASH_MSG"
+
+cd_to_toplevel
+
+git rerere
+
+if test "$ret" = 0
+then
+ git gc --auto
+ if test -x "$GIT_DIR"/hooks/post-commit
+ then
+ "$GIT_DIR"/hooks/post-commit
+ fi
+ if test -z "$quiet"
+ then
+ commit=`git diff-tree --always --shortstat --pretty="format:%h: %s"\
+ --summary --root HEAD --`
+ echo "Created${initial_commit:+ initial} commit $commit"
+ fi
+fi
+
+exit "$ret"
diff --git a/git-commit.sh b/git-commit.sh
deleted file mode 100755
index fcb8443..0000000
--- a/git-commit.sh
+++ /dev/null
@@ -1,628 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2005 Linus Torvalds
-# Copyright (c) 2006 Junio C Hamano
-
-USAGE='[-a | --interactive] [-s] [-v] [--no-verify] [-m <message> | -F <logfile> | (-C|-c) <commit> | --amend] [-u] [-e] [--author <author>] [--template <file>] [[-i | -o] <path>...]'
-SUBDIRECTORY_OK=Yes
-. git-sh-setup
-require_work_tree
-
-git rev-parse --verify HEAD >/dev/null 2>&1 || initial_commit=t
-
-case "$0" in
-*status)
- status_only=t
- ;;
-*commit)
- status_only=
- ;;
-esac
-
-refuse_partial () {
- echo >&2 "$1"
- echo >&2 "You might have meant to say 'git commit -i paths...', perhaps?"
- exit 1
-}
-
-TMP_INDEX=
-THIS_INDEX="$GIT_DIR/index"
-NEXT_INDEX="$GIT_DIR/next-index$$"
-rm -f "$NEXT_INDEX"
-save_index () {
- cp -p "$THIS_INDEX" "$NEXT_INDEX"
-}
-
-run_status () {
- # If TMP_INDEX is defined, that means we are doing
- # "--only" partial commit, and that index file is used
- # to build the tree for the commit. Otherwise, if
- # NEXT_INDEX exists, that is the index file used to
- # make the commit. Otherwise we are using as-is commit
- # so the regular index file is what we use to compare.
- if test '' != "$TMP_INDEX"
- then
- GIT_INDEX_FILE="$TMP_INDEX"
- export GIT_INDEX_FILE
- elif test -f "$NEXT_INDEX"
- then
- GIT_INDEX_FILE="$NEXT_INDEX"
- export GIT_INDEX_FILE
- fi
-
- if test "$status_only" = "t" -o "$use_status_color" = "t"; then
- color=
- else
- color=--nocolor
- fi
- git runstatus ${color} \
- ${verbose:+--verbose} \
- ${amend:+--amend} \
- ${untracked_files:+--untracked}
-}
-
-trap '
- test -z "$TMP_INDEX" || {
- test -f "$TMP_INDEX" && rm -f "$TMP_INDEX"
- }
- rm -f "$NEXT_INDEX"
-' 0
-
-################################################################
-# Command line argument parsing and sanity checking
-
-all=
-also=
-interactive=
-only=
-logfile=
-use_commit=
-amend=
-edit_flag=
-no_edit=
-log_given=
-log_message=
-verify=t
-quiet=
-verbose=
-signoff=
-force_author=
-only_include_assumed=
-untracked_files=
-templatefile="`git config commit.template`"
-while test $# != 0
-do
- case "$1" in
- -F|--F|-f|--f|--fi|--fil|--file)
- case "$#" in 1) usage ;; esac
- shift
- no_edit=t
- log_given=t$log_given
- logfile="$1"
- ;;
- -F*|-f*)
- no_edit=t
- log_given=t$log_given
- logfile="${1#-[Ff]}"
- ;;
- --F=*|--f=*|--fi=*|--fil=*|--file=*)
- no_edit=t
- log_given=t$log_given
- logfile="${1#*=}"
- ;;
- -a|--a|--al|--all)
- all=t
- ;;
- --au=*|--aut=*|--auth=*|--autho=*|--author=*)
- force_author="${1#*=}"
- ;;
- --au|--aut|--auth|--autho|--author)
- case "$#" in 1) usage ;; esac
- shift
- force_author="$1"
- ;;
- -e|--e|--ed|--edi|--edit)
- edit_flag=t
- ;;
- -i|--i|--in|--inc|--incl|--inclu|--includ|--include)
- also=t
- ;;
- --int|--inte|--inter|--intera|--interac|--interact|--interacti|\
- --interactiv|--interactive)
- interactive=t
- ;;
- -o|--o|--on|--onl|--only)
- only=t
- ;;
- -m|--m|--me|--mes|--mess|--messa|--messag|--message)
- case "$#" in 1) usage ;; esac
- shift
- log_given=m$log_given
- log_message="${log_message:+${log_message}
-
-}$1"
- no_edit=t
- ;;
- -m*)
- log_given=m$log_given
- log_message="${log_message:+${log_message}
-
-}${1#-m}"
- no_edit=t
- ;;
- --m=*|--me=*|--mes=*|--mess=*|--messa=*|--messag=*|--message=*)
- log_given=m$log_given
- log_message="${log_message:+${log_message}
-
-}${1#*=}"
- no_edit=t
- ;;
- -n|--n|--no|--no-|--no-v|--no-ve|--no-ver|--no-veri|--no-verif|\
- --no-verify)
- verify=
- ;;
- --a|--am|--ame|--amen|--amend)
- amend=t
- use_commit=HEAD
- ;;
- -c)
- case "$#" in 1) usage ;; esac
- shift
- log_given=t$log_given
- use_commit="$1"
- no_edit=
- ;;
- --ree=*|--reed=*|--reedi=*|--reedit=*|--reedit-=*|--reedit-m=*|\
- --reedit-me=*|--reedit-mes=*|--reedit-mess=*|--reedit-messa=*|\
- --reedit-messag=*|--reedit-message=*)
- log_given=t$log_given
- use_commit="${1#*=}"
- no_edit=
- ;;
- --ree|--reed|--reedi|--reedit|--reedit-|--reedit-m|--reedit-me|\
- --reedit-mes|--reedit-mess|--reedit-messa|--reedit-messag|\
- --reedit-message)
- case "$#" in 1) usage ;; esac
- shift
- log_given=t$log_given
- use_commit="$1"
- no_edit=
- ;;
- -C)
- case "$#" in 1) usage ;; esac
- shift
- log_given=t$log_given
- use_commit="$1"
- no_edit=t
- ;;
- --reu=*|--reus=*|--reuse=*|--reuse-=*|--reuse-m=*|--reuse-me=*|\
- --reuse-mes=*|--reuse-mess=*|--reuse-messa=*|--reuse-messag=*|\
- --reuse-message=*)
- log_given=t$log_given
- use_commit="${1#*=}"
- no_edit=t
- ;;
- --reu|--reus|--reuse|--reuse-|--reuse-m|--reuse-me|--reuse-mes|\
- --reuse-mess|--reuse-messa|--reuse-messag|--reuse-message)
- case "$#" in 1) usage ;; esac
- shift
- log_given=t$log_given
- use_commit="$1"
- no_edit=t
- ;;
- -s|--s|--si|--sig|--sign|--signo|--signof|--signoff)
- signoff=t
- ;;
- -t|--t|--te|--tem|--temp|--templ|--templa|--templat|--template)
- case "$#" in 1) usage ;; esac
- shift
- templatefile="$1"
- no_edit=
- ;;
- -q|--q|--qu|--qui|--quie|--quiet)
- quiet=t
- ;;
- -v|--v|--ve|--ver|--verb|--verbo|--verbos|--verbose)
- verbose=t
- ;;
- -u|--u|--un|--unt|--untr|--untra|--untrac|--untrack|--untracke|\
- --untracked|--untracked-|--untracked-f|--untracked-fi|--untracked-fil|\
- --untracked-file|--untracked-files)
- untracked_files=t
- ;;
- --)
- shift
- break
- ;;
- -*)
- usage
- ;;
- *)
- break
- ;;
- esac
- shift
-done
-case "$edit_flag" in t) no_edit= ;; esac
-
-################################################################
-# Sanity check options
-
-case "$amend,$initial_commit" in
-t,t)
- die "You do not have anything to amend." ;;
-t,)
- if [ -f "$GIT_DIR/MERGE_HEAD" ]; then
- die "You are in the middle of a merge -- cannot amend."
- fi ;;
-esac
-
-case "$log_given" in
-tt*)
- die "Only one of -c/-C/-F can be used." ;;
-*tm*|*mt*)
- die "Option -m cannot be combined with -c/-C/-F." ;;
-esac
-
-case "$#,$also,$only,$amend" in
-*,t,t,*)
- die "Only one of --include/--only can be used." ;;
-0,t,,* | 0,,t,)
- die "No paths with --include/--only does not make sense." ;;
-0,,t,t)
- only_include_assumed="# Clever... amending the last one with dirty index." ;;
-0,,,*)
- ;;
-*,,,*)
- only_include_assumed="# Explicit paths specified without -i nor -o; assuming --only paths..."
- also=
- ;;
-esac
-unset only
-case "$all,$interactive,$also,$#" in
-*t,*t,*)
- die "Cannot use -a, --interactive or -i at the same time." ;;
-t,,[1-9]*)
- die "Paths with -a does not make sense." ;;
-,t,[1-9]*)
- die "Paths with --interactive does not make sense." ;;
-,,t,0)
- die "No paths with -i does not make sense." ;;
-esac
-
-if test ! -z "$templatefile" -a -z "$log_given"
-then
- if test ! -f "$templatefile"
- then
- die "Commit template file does not exist."
- fi
-fi
-
-################################################################
-# Prepare index to have a tree to be committed
-
-case "$all,$also" in
-t,)
- if test ! -f "$THIS_INDEX"
- then
- die 'nothing to commit (use "git add file1 file2" to include for commit)'
- fi
- save_index &&
- (
- cd_to_toplevel &&
- GIT_INDEX_FILE="$NEXT_INDEX" &&
- export GIT_INDEX_FILE &&
- git diff-files --name-only -z |
- git update-index --remove -z --stdin
- ) || exit
- ;;
-,t)
- save_index &&
- git ls-files --error-unmatch -- "$@" >/dev/null || exit
-
- git diff-files --name-only -z -- "$@" |
- (
- cd_to_toplevel &&
- GIT_INDEX_FILE="$NEXT_INDEX" &&
- export GIT_INDEX_FILE &&
- git update-index --remove -z --stdin
- ) || exit
- ;;
-,)
- if test "$interactive" = t; then
- git add --interactive || exit
- fi
- case "$#" in
- 0)
- ;; # commit as-is
- *)
- if test -f "$GIT_DIR/MERGE_HEAD"
- then
- refuse_partial "Cannot do a partial commit during a merge."
- fi
-
- TMP_INDEX="$GIT_DIR/tmp-index$$"
- W=
- test -z "$initial_commit" && W=--with-tree=HEAD
- commit_only=`git ls-files --error-unmatch $W -- "$@"` || exit
-
- # Build a temporary index and update the real index
- # the same way.
- if test -z "$initial_commit"
- then
- GIT_INDEX_FILE="$THIS_INDEX" \
- git read-tree --index-output="$TMP_INDEX" -i -m HEAD
- else
- rm -f "$TMP_INDEX"
- fi || exit
-
- printf '%s\n' "$commit_only" |
- GIT_INDEX_FILE="$TMP_INDEX" \
- git update-index --add --remove --stdin &&
-
- save_index &&
- printf '%s\n' "$commit_only" |
- (
- GIT_INDEX_FILE="$NEXT_INDEX"
- export GIT_INDEX_FILE
- git update-index --add --remove --stdin
- ) || exit
- ;;
- esac
- ;;
-esac
-
-################################################################
-# If we do as-is commit, the index file will be THIS_INDEX,
-# otherwise NEXT_INDEX after we make this commit. We leave
-# the index as is if we abort.
-
-if test -f "$NEXT_INDEX"
-then
- USE_INDEX="$NEXT_INDEX"
-else
- USE_INDEX="$THIS_INDEX"
-fi
-
-case "$status_only" in
-t)
- # This will silently fail in a read-only repository, which is
- # what we want.
- GIT_INDEX_FILE="$USE_INDEX" git update-index -q --unmerged --refresh
- run_status
- exit $?
- ;;
-'')
- GIT_INDEX_FILE="$USE_INDEX" git update-index -q --refresh || exit
- ;;
-esac
-
-################################################################
-# Grab commit message, write out tree and make commit.
-
-if test t = "$verify" && test -x "$GIT_DIR"/hooks/pre-commit
-then
- GIT_INDEX_FILE="${TMP_INDEX:-${USE_INDEX}}" "$GIT_DIR"/hooks/pre-commit \
- || exit
-fi
-
-if test "$log_message" != ''
-then
- printf '%s\n' "$log_message"
-elif test "$logfile" != ""
-then
- if test "$logfile" = -
- then
- test -t 0 &&
- echo >&2 "(reading log message from standard input)"
- cat
- else
- cat <"$logfile"
- fi
-elif test "$use_commit" != ""
-then
- encoding=$(git config i18n.commitencoding || echo UTF-8)
- git show -s --pretty=raw --encoding="$encoding" "$use_commit" |
- sed -e '1,/^$/d' -e 's/^ //'
-elif test -f "$GIT_DIR/MERGE_MSG"
-then
- cat "$GIT_DIR/MERGE_MSG"
-elif test -f "$GIT_DIR/SQUASH_MSG"
-then
- cat "$GIT_DIR/SQUASH_MSG"
-elif test "$templatefile" != ""
-then
- cat "$templatefile"
-fi | git stripspace >"$GIT_DIR"/COMMIT_EDITMSG
-
-case "$signoff" in
-t)
- sign=$(git-var GIT_COMMITTER_IDENT | sed -e '
- s/>.*/>/
- s/^/Signed-off-by: /
- ')
- blank_before_signoff=
- tail -n 1 "$GIT_DIR"/COMMIT_EDITMSG |
- grep 'Signed-off-by:' >/dev/null || blank_before_signoff='
-'
- tail -n 1 "$GIT_DIR"/COMMIT_EDITMSG |
- grep "$sign"$ >/dev/null ||
- printf '%s%s\n' "$blank_before_signoff" "$sign" \
- >>"$GIT_DIR"/COMMIT_EDITMSG
- ;;
-esac
-
-if test -f "$GIT_DIR/MERGE_HEAD" && test -z "$no_edit"; then
- echo "#"
- echo "# It looks like you may be committing a MERGE."
- echo "# If this is not correct, please remove the file"
- printf '%s\n' "# $GIT_DIR/MERGE_HEAD"
- echo "# and try again"
- echo "#"
-fi >>"$GIT_DIR"/COMMIT_EDITMSG
-
-# Author
-if test '' != "$use_commit"
-then
- eval "$(get_author_ident_from_commit "$use_commit")"
- export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_AUTHOR_DATE
-fi
-if test '' != "$force_author"
-then
- GIT_AUTHOR_NAME=`expr "z$force_author" : 'z\(.*[^ ]\) *<.*'` &&
- GIT_AUTHOR_EMAIL=`expr "z$force_author" : '.*\(<.*\)'` &&
- test '' != "$GIT_AUTHOR_NAME" &&
- test '' != "$GIT_AUTHOR_EMAIL" ||
- die "malformed --author parameter"
- export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL
-fi
-
-PARENTS="-p HEAD"
-if test -z "$initial_commit"
-then
- rloga='commit'
- if [ -f "$GIT_DIR/MERGE_HEAD" ]; then
- rloga='commit (merge)'
- PARENTS="-p HEAD "`sed -e 's/^/-p /' "$GIT_DIR/MERGE_HEAD"`
- elif test -n "$amend"; then
- rloga='commit (amend)'
- PARENTS=$(git cat-file commit HEAD |
- sed -n -e '/^$/q' -e 's/^parent /-p /p')
- fi
- current="$(git rev-parse --verify HEAD)"
-else
- if [ -z "$(git ls-files)" ]; then
- echo >&2 'nothing to commit (use "git add file1 file2" to include for commit)'
- exit 1
- fi
- PARENTS=""
- rloga='commit (initial)'
- current=''
-fi
-set_reflog_action "$rloga"
-
-if test -z "$no_edit"
-then
- {
- echo ""
- echo "# Please enter the commit message for your changes."
- echo "# (Comment lines starting with '#' will not be included)"
- test -z "$only_include_assumed" || echo "$only_include_assumed"
- run_status
- } >>"$GIT_DIR"/COMMIT_EDITMSG
-else
- # we need to check if there is anything to commit
- run_status >/dev/null
-fi
-if [ "$?" != "0" -a ! -f "$GIT_DIR/MERGE_HEAD" ]
-then
- rm -f "$GIT_DIR/COMMIT_EDITMSG" "$GIT_DIR/SQUASH_MSG"
- use_status_color=t
- run_status
- exit 1
-fi
-
-case "$no_edit" in
-'')
- git-var GIT_AUTHOR_IDENT > /dev/null || die
- git-var GIT_COMMITTER_IDENT > /dev/null || die
- git_editor "$GIT_DIR/COMMIT_EDITMSG"
- ;;
-esac
-
-case "$verify" in
-t)
- if test -x "$GIT_DIR"/hooks/commit-msg
- then
- "$GIT_DIR"/hooks/commit-msg "$GIT_DIR"/COMMIT_EDITMSG || exit
- fi
-esac
-
-if test -z "$no_edit"
-then
- sed -e '
- /^diff --git a\/.*/{
- s///
- q
- }
- /^#/d
- ' "$GIT_DIR"/COMMIT_EDITMSG
-else
- cat "$GIT_DIR"/COMMIT_EDITMSG
-fi |
-git stripspace >"$GIT_DIR"/COMMIT_MSG
-
-# Test whether the commit message has any content we didn't supply.
-have_commitmsg=
-grep -v -i '^Signed-off-by' "$GIT_DIR"/COMMIT_MSG |
- git stripspace > "$GIT_DIR"/COMMIT_BAREMSG
-
-# Is the commit message totally empty?
-if test -s "$GIT_DIR"/COMMIT_BAREMSG
-then
- if test "$templatefile" != ""
- then
- # Test whether this is just the unaltered template.
- if cnt=`sed -e '/^#/d' < "$templatefile" |
- git stripspace |
- diff "$GIT_DIR"/COMMIT_BAREMSG - |
- wc -l` &&
- test 0 -lt $cnt
- then
- have_commitmsg=t
- fi
- else
- # No template, so the content in the commit message must
- # have come from the user.
- have_commitmsg=t
- fi
-fi
-
-rm -f "$GIT_DIR"/COMMIT_BAREMSG
-
-if test "$have_commitmsg" = "t"
-then
- if test -z "$TMP_INDEX"
- then
- tree=$(GIT_INDEX_FILE="$USE_INDEX" git write-tree)
- else
- tree=$(GIT_INDEX_FILE="$TMP_INDEX" git write-tree) &&
- rm -f "$TMP_INDEX"
- fi &&
- commit=$(git commit-tree $tree $PARENTS <"$GIT_DIR/COMMIT_MSG") &&
- rlogm=$(sed -e 1q "$GIT_DIR"/COMMIT_MSG) &&
- git update-ref -m "$GIT_REFLOG_ACTION: $rlogm" HEAD $commit "$current" &&
- rm -f -- "$GIT_DIR/MERGE_HEAD" "$GIT_DIR/MERGE_MSG" &&
- if test -f "$NEXT_INDEX"
- then
- mv "$NEXT_INDEX" "$THIS_INDEX"
- else
- : ;# happy
- fi
-else
- echo >&2 "* no commit message? aborting commit."
- false
-fi
-ret="$?"
-rm -f "$GIT_DIR/COMMIT_MSG" "$GIT_DIR/COMMIT_EDITMSG" "$GIT_DIR/SQUASH_MSG"
-
-cd_to_toplevel
-
-git rerere
-
-if test "$ret" = 0
-then
- git gc --auto
- if test -x "$GIT_DIR"/hooks/post-commit
- then
- "$GIT_DIR"/hooks/post-commit
- fi
- if test -z "$quiet"
- then
- commit=`git diff-tree --always --shortstat --pretty="format:%h: %s"\
- --summary --root HEAD --`
- echo "Created${initial_commit:+ initial} commit $commit"
- fi
-fi
-
-exit "$ret"
diff --git a/git.c b/git.c
index 4e10581..8522095 100644
--- a/git.c
+++ b/git.c
@@ -298,6 +298,7 @@ static void handle_internal_command(int argc, const char **argv)
{ "check-attr", cmd_check_attr, RUN_SETUP | NEED_WORK_TREE },
{ "cherry", cmd_cherry, RUN_SETUP },
{ "cherry-pick", cmd_cherry_pick, RUN_SETUP | NEED_WORK_TREE },
+ { "commit", cmd_commit, RUN_SETUP | NEED_WORK_TREE },
{ "commit-tree", cmd_commit_tree, RUN_SETUP },
{ "config", cmd_config },
{ "count-objects", cmd_count_objects, RUN_SETUP },
@@ -346,10 +347,10 @@ static void handle_internal_command(int argc, const char **argv)
{ "rev-parse", cmd_rev_parse, RUN_SETUP },
{ "revert", cmd_revert, RUN_SETUP | NEED_WORK_TREE },
{ "rm", cmd_rm, RUN_SETUP | NEED_WORK_TREE },
- { "runstatus", cmd_runstatus, RUN_SETUP | NEED_WORK_TREE },
{ "shortlog", cmd_shortlog, RUN_SETUP | USE_PAGER },
{ "show-branch", cmd_show_branch, RUN_SETUP },
{ "show", cmd_show, RUN_SETUP | USE_PAGER },
+ { "status", cmd_status, RUN_SETUP | NEED_WORK_TREE },
{ "stripspace", cmd_stripspace },
{ "symbolic-ref", cmd_symbolic_ref, RUN_SETUP },
{ "tag", cmd_tag, RUN_SETUP },
diff --git a/strbuf.h b/strbuf.h
index 9b9e861..9720826 100644
--- a/strbuf.h
+++ b/strbuf.h
@@ -113,5 +113,6 @@ extern int strbuf_read_file(struct strbuf *sb, const char *path, size_t hint);
extern int strbuf_getline(struct strbuf *, FILE *, int);
extern void stripspace(struct strbuf *buf, int skip_comments);
+extern void launch_editor(const char *path, struct strbuf *buffer);
#endif /* STRBUF_H */
diff --git a/t/t3501-revert-cherry-pick.sh b/t/t3501-revert-cherry-pick.sh
index 552af1c..2dbe04f 100755
--- a/t/t3501-revert-cherry-pick.sh
+++ b/t/t3501-revert-cherry-pick.sh
@@ -44,7 +44,7 @@ test_expect_success setup '
test_expect_success 'cherry-pick after renaming branch' '
git checkout rename2 &&
- EDITOR=: VISUAL=: git cherry-pick added &&
+ git cherry-pick added &&
test -f opos &&
grep "Add extra line at the end" opos
@@ -53,7 +53,7 @@ test_expect_success 'cherry-pick after renaming branch' '
test_expect_success 'revert after renaming branch' '
git checkout rename1 &&
- EDITOR=: VISUAL=: git revert added &&
+ git revert added &&
test -f spoo &&
! grep "Add extra line at the end" spoo
diff --git a/t/t3901-i18n-patch.sh b/t/t3901-i18n-patch.sh
index 28e9e37..235f372 100755
--- a/t/t3901-i18n-patch.sh
+++ b/t/t3901-i18n-patch.sh
@@ -154,7 +154,7 @@ test_expect_success 'cherry-pick(U/U)' '
git reset --hard master &&
git cherry-pick side^ &&
git cherry-pick side &&
- EDITOR=: VISUAL=: git revert HEAD &&
+ git revert HEAD &&
check_encoding 3
'
@@ -169,7 +169,7 @@ test_expect_success 'cherry-pick(L/L)' '
git reset --hard master &&
git cherry-pick side^ &&
git cherry-pick side &&
- EDITOR=: VISUAL=: git revert HEAD &&
+ git revert HEAD &&
check_encoding 3 8859
'
@@ -184,7 +184,7 @@ test_expect_success 'cherry-pick(U/L)' '
git reset --hard master &&
git cherry-pick side^ &&
git cherry-pick side &&
- EDITOR=: VISUAL=: git revert HEAD &&
+ git revert HEAD &&
check_encoding 3
'
@@ -200,7 +200,7 @@ test_expect_success 'cherry-pick(L/U)' '
git reset --hard master &&
git cherry-pick side^ &&
git cherry-pick side &&
- EDITOR=: VISUAL=: git revert HEAD &&
+ git revert HEAD &&
check_encoding 3 8859
'
diff --git a/t/test-lib.sh b/t/test-lib.sh
index 714de6e..51cbcc1 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -9,8 +9,8 @@ LC_ALL=C
PAGER=cat
TZ=UTC
export LANG LC_ALL PAGER TZ
-EDITOR=:
-VISUAL=:
+EDITOR=/bin/true
+VISUAL=/bin/true
unset GIT_EDITOR
unset AUTHOR_DATE
unset AUTHOR_EMAIL
--
1.5.3.4.206.g58ba4
^ permalink raw reply related [relevance 2%]
* [PATCH] Port git commit to C.
@ 2007-11-08 16:59 2% Kristian Høgsberg
0 siblings, 0 replies; 200+ results
From: Kristian Høgsberg @ 2007-11-08 16:59 UTC (permalink / raw)
To: gitster; +Cc: git, Kristian Høgsberg
This makes git commit a builtin and moves git-commit.sh to
contrib/examples. This also removes the git-runstatus
helper, which was mostly just a git-status.sh implementation detail.
Signed-off-by: Kristian Høgsberg <krh@redhat.com>
---
This has Johannes' updates and Bjoerns command line parsing fixes.
Also fixes the author date problem on amend commits, so this replaces
Johannes' recent [PATCH 3/3] author fix.
cheers,
Kristian
Makefile | 9 +-
builtin-commit.c | 615 +++++++++++++++++++++++++++++++++++++++
builtin.h | 3 +-
contrib/examples/git-commit.sh | 628 ++++++++++++++++++++++++++++++++++++++++
git-commit.sh | 628 ----------------------------------------
git.c | 3 +-
strbuf.h | 1 +
7 files changed, 1251 insertions(+), 636 deletions(-)
create mode 100644 builtin-commit.c
create mode 100755 contrib/examples/git-commit.sh
delete mode 100755 git-commit.sh
diff --git a/Makefile b/Makefile
index 3ec1876..e4c51c6 100644
--- a/Makefile
+++ b/Makefile
@@ -209,7 +209,7 @@ BASIC_LDFLAGS =
SCRIPT_SH = \
git-bisect.sh git-checkout.sh \
- git-clean.sh git-clone.sh git-commit.sh \
+ git-clean.sh git-clone.sh \
git-ls-remote.sh \
git-merge-one-file.sh git-mergetool.sh git-parse-remote.sh \
git-pull.sh git-rebase.sh git-rebase--interactive.sh \
@@ -256,7 +256,7 @@ EXTRA_PROGRAMS =
BUILT_INS = \
git-format-patch$X git-show$X git-whatchanged$X git-cherry$X \
git-get-tar-commit-id$X git-init$X git-repo-config$X \
- git-fsck-objects$X git-cherry-pick$X \
+ git-fsck-objects$X git-cherry-pick$X git-status$X\
$(patsubst builtin-%.o,git-%$X,$(BUILTIN_OBJS))
# what 'all' will build and 'install' will install, in gitexecdir
@@ -326,6 +326,7 @@ BUILTIN_OBJS = \
builtin-check-attr.o \
builtin-checkout-index.o \
builtin-check-ref-format.o \
+ builtin-commit.o \
builtin-commit-tree.o \
builtin-count-objects.o \
builtin-describe.o \
@@ -366,7 +367,6 @@ BUILTIN_OBJS = \
builtin-rev-parse.o \
builtin-revert.o \
builtin-rm.o \
- builtin-runstatus.o \
builtin-shortlog.o \
builtin-show-branch.o \
builtin-stripspace.o \
@@ -832,9 +832,6 @@ $(patsubst %.perl,%,$(SCRIPT_PERL)): % : %.perl
chmod +x $@+ && \
mv $@+ $@
-git-status: git-commit
- $(QUIET_GEN)cp $< $@+ && mv $@+ $@
-
gitweb/gitweb.cgi: gitweb/gitweb.perl
$(QUIET_GEN)$(RM) $@ $@+ && \
sed -e '1s|#!.*perl|#!$(PERL_PATH_SQ)|' \
diff --git a/builtin-commit.c b/builtin-commit.c
new file mode 100644
index 0000000..ae4ca4e
--- /dev/null
+++ b/builtin-commit.c
@@ -0,0 +1,615 @@
+/*
+ * Builtin "git commit"
+ *
+ * Copyright (c) 2007 Kristian Høgsberg <krh@redhat.com>
+ * Based on git-commit.sh by Junio C Hamano and Linus Torvalds
+ */
+
+#include "git-compat-util.h"
+
+#include "cache.h"
+#include "cache-tree.h"
+#include "builtin.h"
+#include "diff.h"
+#include "diffcore.h"
+#include "commit.h"
+#include "revision.h"
+#include "wt-status.h"
+#include "run-command.h"
+#include "refs.h"
+#include "log-tree.h"
+#include "strbuf.h"
+#include "utf8.h"
+#include "parse-options.h"
+
+static const char * const builtin_commit_usage[] = {
+ "git-commit [options] [--] <filepattern>...",
+ NULL
+};
+
+static unsigned char head_sha1[20], merge_head_sha1[20];
+static char *use_message_buffer;
+static const char commit_editmsg[] = "COMMIT_EDITMSG";
+static struct lock_file lock_file;
+
+static char *logfile, *force_author, *message, *template_file;
+static char *edit_message, *use_message;
+static int all, edit_flag, also, interactive, only, amend, signoff;
+static int quiet, verbose, untracked_files, no_verify;
+
+static int no_edit, initial_commit, in_merge;
+const char *only_include_assumed;
+
+static struct option builtin_commit_options[] = {
+ OPT__QUIET(&quiet),
+ OPT__VERBOSE(&verbose),
+ OPT_GROUP("Commit message options"),
+
+ OPT_STRING('F', "file", &logfile, "FILE", "read log from file"),
+ OPT_STRING(0, "author", &force_author, "AUTHOR", "override author for commit"),
+ OPT_STRING('m', "message", &message, "MESSAGE", "specify commit message"),
+ OPT_STRING('c', "reedit-message", &edit_message, "COMMIT", "reuse and edit message from specified commit "),
+ OPT_STRING('C', "reuse-message", &use_message, "COMMIT", "reuse message from specified commit"),
+ OPT_BOOLEAN('s', "signoff", &signoff, "add Signed-off-by: header"),
+ OPT_STRING('t', "template", &template_file, "FILE", "use specified template file"),
+ OPT_BOOLEAN('e', "edit", &edit_flag, "force edit of commit"),
+
+ OPT_GROUP("Commit contents options"),
+ OPT_BOOLEAN('a', "all", &all, "commit all changed files"),
+ OPT_BOOLEAN('i', "include", &also, "add specified files to index for commit"),
+ OPT_BOOLEAN(0, "interactive", &interactive, "interactively add files"),
+ OPT_BOOLEAN('o', "only", &only, ""),
+ OPT_BOOLEAN('n', "no-verify", &no_verify, "bypass pre-commit hook"),
+ OPT_BOOLEAN(0, "amend", &amend, "amend previous commit"),
+ OPT_BOOLEAN(0, "untracked-files", &untracked_files, "show all untracked files"),
+
+ OPT_END()
+};
+
+static char *
+prepare_index(const char **files, const char *prefix)
+{
+ int fd;
+ struct tree *tree;
+ struct lock_file *next_index_lock;
+
+ if (interactive) {
+ interactive_add();
+ return get_index_file();
+ }
+
+ fd = hold_locked_index(&lock_file, 1);
+ if (read_cache() < 0)
+ die("index file corrupt");
+
+ if (all || also) {
+ add_files_to_cache(verbose, also ? prefix : NULL, files);
+ if (write_cache(fd, active_cache, active_nr) || close(fd))
+ die("unable to write new_index file");
+ return lock_file.filename;
+ }
+
+ if (*files == NULL) {
+ /* Commit index as-is. */
+ rollback_lock_file(&lock_file);
+ return get_index_file();
+ }
+
+ /* update the user index file */
+ add_files_to_cache(verbose, prefix, files);
+ if (write_cache(fd, active_cache, active_nr) || close(fd))
+ die("unable to write new_index file");
+
+ 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");
+ }
+
+ /* Use a lock file to garbage collect the temporary index file. */
+ next_index_lock = xmalloc(sizeof(*next_index_lock));
+ fd = hold_lock_file_for_update(next_index_lock,
+ git_path("next-index-%d", getpid()), 1);
+ add_files_to_cache(verbose, prefix, files);
+ if (write_cache(fd, active_cache, active_nr) || close(fd))
+ die("unable to write new_index file");
+
+ return next_index_lock->filename;
+}
+
+static int run_status(FILE *fp, const char *index_file)
+{
+ struct wt_status s;
+
+ wt_status_prepare(&s);
+
+ if (amend) {
+ s.amend = 1;
+ s.reference = "HEAD^1";
+ }
+ s.verbose = verbose;
+ s.untracked = untracked_files;
+ s.index_file = index_file;
+ s.fp = fp;
+
+ wt_status_print(&s);
+
+ return s.commitable;
+}
+
+static const char sign_off_header[] = "Signed-off-by: ";
+
+static int prepare_log_message(const char *index_file)
+{
+ struct stat statbuf;
+ int commitable;
+ struct strbuf sb;
+ char *buffer;
+ FILE *fp;
+
+ strbuf_init(&sb, 0);
+ if (message) {
+ strbuf_add(&sb, message, strlen(message));
+ } else if (logfile && !strcmp(logfile, "-")) {
+ if (isatty(0))
+ fprintf(stderr, "(reading log message from standard input)\n");
+ if (strbuf_read(&sb, 0, 0) < 0)
+ die("could not read log from standard input");
+ } else if (logfile) {
+ if (strbuf_read_file(&sb, logfile, 0) < 0)
+ die("could not read log file '%s': %s",
+ logfile, strerror(errno));
+ } else if (use_message) {
+ buffer = strstr(use_message_buffer, "\n\n");
+ if (!buffer || buffer[2] == '\0')
+ die("commit has empty message");
+ strbuf_add(&sb, buffer + 2, strlen(buffer + 2));
+ } else if (!stat(git_path("MERGE_MSG"), &statbuf)) {
+ if (strbuf_read_file(&sb, git_path("MERGE_MSG"), 0) < 0)
+ die("could not read MERGE_MSG: %s", strerror(errno));
+ } else if (!stat(git_path("SQUASH_MSG"), &statbuf)) {
+ if (strbuf_read_file(&sb, git_path("SQUASH_MSG"), 0) < 0)
+ die("could not read SQUASH_MSG: %s", strerror(errno));
+ } else if (template_file && !stat(template_file, &statbuf)) {
+ if (strbuf_read_file(&sb, template_file, 0) < 0)
+ die("could not read %s: %s",
+ template_file, strerror(errno));
+ }
+
+ fp = fopen(git_path(commit_editmsg), "w");
+ if (fp == NULL)
+ die("could not open %s\n", git_path(commit_editmsg));
+
+ stripspace(&sb, 0);
+ if (fwrite(sb.buf, 1, sb.len, fp) < sb.len)
+ die("could not write commit template: %s\n",
+ strerror(errno));
+
+ if (signoff) {
+ const char *info, *bol;
+
+ info = git_committer_info(1);
+ strbuf_addch(&sb, '\0');
+ bol = strrchr(sb.buf + sb.len - 1, '\n');
+ if (!bol || prefixcmp(bol, sign_off_header))
+ fprintf(fp, "\n");
+ fprintf(fp, "%s%s\n", sign_off_header, git_committer_info(1));
+ }
+
+ strbuf_release(&sb);
+
+ if (in_merge && !no_edit) {
+ fprintf(fp,
+ "#\n"
+ "# It looks like you may be committing a MERGE.\n"
+ "# If this is not correct, please remove the file\n"
+ "# %s\n"
+ "# and try again.\n"
+ "#\n",
+ git_path("MERGE_HEAD"));
+ }
+
+ fprintf(fp,
+ "\n"
+ "# Please enter the commit message for your changes.\n"
+ "# (Comment lines starting with '#' will not be included)\n");
+ if (only_include_assumed)
+ fprintf(fp, "# %s\n", only_include_assumed);
+
+ commitable = run_status(fp, index_file);
+
+ fclose(fp);
+
+ return commitable;
+}
+
+/* Find out if the message starting at position 'start' in the strbuf
+ * contains only whitespace and Signed-off-by lines. */
+static int message_is_empty(struct strbuf *sb, int start)
+{
+ struct strbuf tmpl;
+ const char *nl;
+ int eol, i;
+
+ /* See if the template is just a prefix of the message. */
+ strbuf_init(&tmpl, 0);
+ if (template_file && strbuf_read_file(&tmpl, template_file, 0) > 0) {
+ stripspace(&tmpl, 1);
+ if (start + tmpl.len <= sb->len &&
+ memcmp(tmpl.buf, sb->buf + start, tmpl.len) == 0)
+ start += tmpl.len;
+ strbuf_release(&tmpl);
+ }
+
+ /* Check if the rest is just whitespace and Signed-of-by's. */
+ for (i = start; i < sb->len; i++) {
+ nl = memchr(sb->buf + i, '\n', sb->len - i);
+ if (nl)
+ eol = nl - sb->buf;
+ else
+ eol = sb->len;
+
+ if (strlen(sign_off_header) <= eol - i &&
+ !prefixcmp(sb->buf + i, sign_off_header)) {
+ i = eol;
+ continue;
+ }
+ while (i < eol)
+ if (!isspace(sb->buf[i++]))
+ return 0;
+ }
+
+ return 1;
+}
+
+static void determine_author_info(struct strbuf *sb)
+{
+ char *name, *email, *date;
+
+ name = getenv("GIT_AUTHOR_NAME");
+ email = getenv("GIT_AUTHOR_EMAIL");
+ date = getenv("GIT_AUTHOR_DATE");
+
+ if (use_message) {
+ const char *a, *lb, *rb, *eol;
+
+ a = strstr(use_message_buffer, "\nauthor ");
+ if (!a)
+ die("invalid commit: %s\n", use_message);
+
+ lb = strstr(a + 8, " <");
+ rb = strstr(a + 8, "> ");
+ eol = strchr(a + 8, '\n');
+ if (!lb || !rb || !eol)
+ die("invalid commit: %s\n", use_message);
+
+ name = xstrndup(a + 8, lb - (a + 8));
+ email = xstrndup(lb + 2, rb - (lb + 2));
+ date = xstrndup(rb + 2, eol - (rb + 2));
+ }
+
+ if (force_author) {
+ const char *lb = strstr(force_author, " <");
+ const char *rb = strchr(force_author, '>');
+
+ if (!lb || !rb)
+ die("malformed --author parameter\n");
+ name = xstrndup(force_author, lb - force_author);
+ email = xstrndup(lb + 2, rb - (lb + 2));
+ }
+
+ strbuf_addf(sb, "author %s\n", fmt_ident(name, email, date, 1));
+}
+
+static int parse_and_validate_options(int argc, const char *argv[])
+{
+ int f = 0;
+
+ argc = parse_options(argc, argv, builtin_commit_options,
+ builtin_commit_usage, 0);
+
+ if (logfile || message || use_message)
+ no_edit = 1;
+ if (edit_flag)
+ no_edit = 0;
+
+ if (get_sha1("HEAD", head_sha1))
+ initial_commit = 1;
+
+ if (!get_sha1("MERGE_HEAD", merge_head_sha1))
+ in_merge = 1;
+
+ /* Sanity check options */
+ if (amend && initial_commit)
+ die("You have nothing to amend.");
+ if (amend && in_merge)
+ die("You are in the middle of a merger -- cannot amend.");
+
+ if (use_message)
+ f++;
+ if (edit_message)
+ f++;
+ if (logfile)
+ f++;
+ if (f > 1)
+ die("Only one of -c/-C/-F can be used.");
+ if (message && f > 0)
+ die("Option -m cannot be combined with -c/-C/-F.");
+ if (edit_message)
+ use_message = edit_message;
+ if (amend)
+ use_message = "HEAD";
+ if (use_message) {
+ unsigned char sha1[20];
+ static char utf8[] = "UTF-8";
+ const char *out_enc;
+ char *enc, *end;
+ struct commit *commit;
+
+ if (get_sha1(use_message, sha1))
+ die("could not lookup commit %s", use_message);
+ commit = lookup_commit(sha1);
+ if (!commit || parse_commit(commit))
+ die("could not parse commit %s", use_message);
+
+ enc = strstr(commit->buffer, "\nencoding");
+ if (enc) {
+ end = strchr(enc + 10, '\n');
+ enc = xstrndup(enc + 10, end - (enc + 10));
+ } else {
+ enc = utf8;
+ }
+ out_enc = git_commit_encoding ? git_commit_encoding : utf8;
+
+ if (strcmp(out_enc, enc))
+ use_message_buffer =
+ reencode_string(commit->buffer, out_enc, enc);
+
+ /* If we failed to reencode the buffer, just copy it
+ * byte for byte so the user can try to fix it up.
+ * This also handles the case where input and output
+ * encodings are identical. */
+ if (use_message_buffer == NULL)
+ use_message_buffer = xstrdup(commit->buffer);
+ if (enc != utf8)
+ free(enc);
+ }
+
+ if (!!also + !!only + !!all + !!interactive > 1)
+ die("Only one of --include/--only/--all/--interactive can be used.");
+ if (argc == 0 && (also || (only && !amend)))
+ die("No paths with --include/--only does not make sense.");
+ if (argc == 0 && only && amend)
+ only_include_assumed = "Clever... amending the last one with dirty index.";
+ if (argc > 0 && !also && !only) {
+ only_include_assumed = "Explicit paths specified without -i nor -o; assuming --only paths...";
+ also = 0;
+ }
+
+ if (all && argc > 0)
+ die("Paths with -a does not make sense.");
+ else if (interactive && argc > 0)
+ die("Paths with --interactive does not make sense.");
+
+ return argc;
+}
+
+int cmd_status(int argc, const char **argv, const char *prefix)
+{
+ const char *index_file;
+ int commitable;
+
+ git_config(git_status_config);
+
+ argc = parse_and_validate_options(argc, argv);
+
+ index_file = prepare_index(argv, prefix);
+
+ commitable = run_status(stdout, index_file);
+
+ rollback_lock_file(&lock_file);
+
+ return commitable ? 0 : 1;
+}
+
+static int run_hook(const char *index_file, const char *name, const char *arg)
+{
+ struct child_process hook;
+ const char *argv[3], *env[2];
+ char index[PATH_MAX];
+
+ argv[0] = git_path("hooks/%s", name);
+ argv[1] = arg;
+ argv[2] = NULL;
+ snprintf(index, sizeof(index), "GIT_INDEX_FILE=%s", index_file);
+ env[0] = index;
+ env[1] = NULL;
+
+ if (access(argv[0], X_OK) < 0)
+ return 0;
+
+ memset(&hook, 0, sizeof(hook));
+ hook.argv = argv;
+ hook.no_stdin = 1;
+ hook.stdout_to_stderr = 1;
+ hook.env = env;
+
+ return run_command(&hook);
+}
+
+static void print_summary(const char *prefix, const unsigned char *sha1)
+{
+ struct rev_info rev;
+ struct commit *commit;
+
+ commit = lookup_commit(sha1);
+ if (!commit)
+ die("couldn't look up newly created commit\n");
+ if (!commit || parse_commit(commit))
+ die("could not parse newly created commit");
+
+ init_revisions(&rev, prefix);
+ setup_revisions(0, NULL, &rev, NULL);
+
+ rev.abbrev = 0;
+ rev.diff = 1;
+ rev.diffopt.output_format =
+ DIFF_FORMAT_SHORTSTAT | DIFF_FORMAT_SUMMARY;
+
+ rev.verbose_header = 1;
+ rev.show_root_diff = 1;
+ rev.commit_format = get_commit_format("format:%h: %s");
+ rev.always_show_header = 1;
+
+ printf("Created %scommit ", initial_commit ? "initial " : "");
+
+ log_tree_commit(&rev, commit);
+}
+
+int git_commit_config(const char *k, const char *v)
+{
+ if (!strcmp(k, "commit.template")) {
+ template_file = xstrdup(v);
+ return 0;
+ }
+
+ return git_status_config(k, v);
+}
+
+static const char commit_utf8_warn[] =
+"Warning: commit message does not conform to UTF-8.\n"
+"You may want to amend it after fixing the message, or set the config\n"
+"variable i18n.commitencoding to the encoding your project uses.\n";
+
+int cmd_commit(int argc, const char **argv, const char *prefix)
+{
+ int header_len, parent_count = 0;
+ struct strbuf sb;
+ const char *index_file, *reflog_msg;
+ char *nl, *header_line;
+ unsigned char commit_sha1[20];
+ struct ref_lock *ref_lock;
+
+ git_config(git_commit_config);
+
+ argc = parse_and_validate_options(argc, argv);
+
+ index_file = prepare_index(argv, prefix);
+
+ if (!no_verify && run_hook(index_file, "pre-commit", NULL))
+ exit(1);
+
+ if (!prepare_log_message(index_file) && !in_merge) {
+ run_status(stdout, index_file);
+ unlink(commit_editmsg);
+ return 1;
+ }
+
+ strbuf_init(&sb, 0);
+
+ /* Start building up the commit header */
+ read_cache_from(index_file);
+ active_cache_tree = cache_tree();
+ if (cache_tree_update(active_cache_tree,
+ active_cache, active_nr, 0, 0) < 0)
+ die("Error building trees");
+ strbuf_addf(&sb, "tree %s\n",
+ sha1_to_hex(active_cache_tree->sha1));
+
+ /* Determine parents */
+ if (initial_commit) {
+ reflog_msg = "commit (initial)";
+ parent_count = 0;
+ } else if (amend) {
+ struct commit_list *c;
+ struct commit *commit;
+
+ reflog_msg = "commit (amend)";
+ commit = lookup_commit(head_sha1);
+ if (!commit || parse_commit(commit))
+ die("could not parse HEAD commit");
+
+ for (c = commit->parents; c; c = c->next)
+ strbuf_addf(&sb, "parent %s\n",
+ sha1_to_hex(c->item->object.sha1));
+ } else if (in_merge) {
+ struct strbuf m;
+ FILE *fp;
+
+ reflog_msg = "commit (merge)";
+ strbuf_addf(&sb, "parent %s\n", sha1_to_hex(head_sha1));
+ strbuf_init(&m, 0);
+ fp = fopen(git_path("MERGE_HEAD"), "r");
+ if (fp == NULL)
+ die("could not open %s for reading: %s",
+ git_path("MERGE_HEAD"), strerror(errno));
+ while (strbuf_getline(&m, fp, '\n') != EOF)
+ strbuf_addf(&sb, "parent %s\n", m.buf);
+ fclose(fp);
+ strbuf_release(&m);
+ } else {
+ reflog_msg = "commit";
+ strbuf_addf(&sb, "parent %s\n", sha1_to_hex(head_sha1));
+ }
+
+ determine_author_info(&sb);
+ strbuf_addf(&sb, "committer %s\n", git_committer_info(1));
+ if (!is_encoding_utf8(git_commit_encoding))
+ strbuf_addf(&sb, "encoding %s\n", git_commit_encoding);
+ strbuf_addch(&sb, '\n');
+
+ /* Get the commit message and validate it */
+ header_len = sb.len;
+ if (!no_edit) {
+ fprintf(stderr, "launching editor, log %s\n", logfile);
+ launch_editor(git_path(commit_editmsg), &sb);
+ }
+ else if (strbuf_read_file(&sb, git_path(commit_editmsg), 0) < 0)
+ die("could not read commit message\n");
+ if (run_hook(index_file, "commit-msg", commit_editmsg))
+ exit(1);
+ stripspace(&sb, 1);
+ if (sb.len < header_len ||
+ message_is_empty(&sb, header_len))
+ die("* no commit message? aborting commit.");
+ strbuf_addch(&sb, '\0');
+ if (is_encoding_utf8(git_commit_encoding) && !is_utf8(sb.buf))
+ fprintf(stderr, commit_utf8_warn);
+
+ if (write_sha1_file(sb.buf, sb.len - 1, commit_type, commit_sha1))
+ die("failed to write commit object");
+
+ ref_lock = lock_any_ref_for_update("HEAD",
+ initial_commit ? NULL : head_sha1,
+ 0);
+
+ nl = strchr(sb.buf + header_len, '\n');
+ header_line = xstrndup(sb.buf + header_len,
+ nl - (sb.buf + header_len));
+ strbuf_release(&sb);
+ strbuf_addf(&sb, "%s: %s\n", reflog_msg, header_line);
+ strbuf_addch(&sb, '\0');
+ free(header_line);
+
+ if (!ref_lock)
+ die("cannot lock HEAD ref");
+ if (write_ref_sha1(ref_lock, commit_sha1, sb.buf) < 0)
+ die("cannot update HEAD ref");
+
+ unlink(git_path("MERGE_HEAD"));
+ unlink(git_path("MERGE_MSG"));
+
+ if (lock_file.filename[0] && commit_locked_index(&lock_file))
+ die("failed to write new index");
+
+ rerere();
+
+ run_hook(index_file, "post-commit", NULL);
+
+ if (!quiet)
+ print_summary(prefix, commit_sha1);
+
+ return 0;
+}
diff --git a/builtin.h b/builtin.h
index 2335c01..3d2de27 100644
--- a/builtin.h
+++ b/builtin.h
@@ -24,6 +24,7 @@ extern int cmd_check_attr(int argc, const char **argv, const char *prefix);
extern int cmd_check_ref_format(int argc, const char **argv, const char *prefix);
extern int cmd_cherry(int argc, const char **argv, const char *prefix);
extern int cmd_cherry_pick(int argc, const char **argv, const char *prefix);
+extern int cmd_commit(int argc, const char **argv, const char *prefix);
extern int cmd_commit_tree(int argc, const char **argv, const char *prefix);
extern int cmd_count_objects(int argc, const char **argv, const char *prefix);
extern int cmd_describe(int argc, const char **argv, const char *prefix);
@@ -69,11 +70,11 @@ extern int cmd_rev_list(int argc, const char **argv, const char *prefix);
extern int cmd_rev_parse(int argc, const char **argv, const char *prefix);
extern int cmd_revert(int argc, const char **argv, const char *prefix);
extern int cmd_rm(int argc, const char **argv, const char *prefix);
-extern int cmd_runstatus(int argc, const char **argv, const char *prefix);
extern int cmd_send_pack(int argc, const char **argv, const char *prefix);
extern int cmd_shortlog(int argc, const char **argv, const char *prefix);
extern int cmd_show(int argc, const char **argv, const char *prefix);
extern int cmd_show_branch(int argc, const char **argv, const char *prefix);
+extern int cmd_status(int argc, const char **argv, const char *prefix);
extern int cmd_stripspace(int argc, const char **argv, const char *prefix);
extern int cmd_symbolic_ref(int argc, const char **argv, const char *prefix);
extern int cmd_tag(int argc, const char **argv, const char *prefix);
diff --git a/contrib/examples/git-commit.sh b/contrib/examples/git-commit.sh
new file mode 100755
index 0000000..fcb8443
--- /dev/null
+++ b/contrib/examples/git-commit.sh
@@ -0,0 +1,628 @@
+#!/bin/sh
+#
+# Copyright (c) 2005 Linus Torvalds
+# Copyright (c) 2006 Junio C Hamano
+
+USAGE='[-a | --interactive] [-s] [-v] [--no-verify] [-m <message> | -F <logfile> | (-C|-c) <commit> | --amend] [-u] [-e] [--author <author>] [--template <file>] [[-i | -o] <path>...]'
+SUBDIRECTORY_OK=Yes
+. git-sh-setup
+require_work_tree
+
+git rev-parse --verify HEAD >/dev/null 2>&1 || initial_commit=t
+
+case "$0" in
+*status)
+ status_only=t
+ ;;
+*commit)
+ status_only=
+ ;;
+esac
+
+refuse_partial () {
+ echo >&2 "$1"
+ echo >&2 "You might have meant to say 'git commit -i paths...', perhaps?"
+ exit 1
+}
+
+TMP_INDEX=
+THIS_INDEX="$GIT_DIR/index"
+NEXT_INDEX="$GIT_DIR/next-index$$"
+rm -f "$NEXT_INDEX"
+save_index () {
+ cp -p "$THIS_INDEX" "$NEXT_INDEX"
+}
+
+run_status () {
+ # If TMP_INDEX is defined, that means we are doing
+ # "--only" partial commit, and that index file is used
+ # to build the tree for the commit. Otherwise, if
+ # NEXT_INDEX exists, that is the index file used to
+ # make the commit. Otherwise we are using as-is commit
+ # so the regular index file is what we use to compare.
+ if test '' != "$TMP_INDEX"
+ then
+ GIT_INDEX_FILE="$TMP_INDEX"
+ export GIT_INDEX_FILE
+ elif test -f "$NEXT_INDEX"
+ then
+ GIT_INDEX_FILE="$NEXT_INDEX"
+ export GIT_INDEX_FILE
+ fi
+
+ if test "$status_only" = "t" -o "$use_status_color" = "t"; then
+ color=
+ else
+ color=--nocolor
+ fi
+ git runstatus ${color} \
+ ${verbose:+--verbose} \
+ ${amend:+--amend} \
+ ${untracked_files:+--untracked}
+}
+
+trap '
+ test -z "$TMP_INDEX" || {
+ test -f "$TMP_INDEX" && rm -f "$TMP_INDEX"
+ }
+ rm -f "$NEXT_INDEX"
+' 0
+
+################################################################
+# Command line argument parsing and sanity checking
+
+all=
+also=
+interactive=
+only=
+logfile=
+use_commit=
+amend=
+edit_flag=
+no_edit=
+log_given=
+log_message=
+verify=t
+quiet=
+verbose=
+signoff=
+force_author=
+only_include_assumed=
+untracked_files=
+templatefile="`git config commit.template`"
+while test $# != 0
+do
+ case "$1" in
+ -F|--F|-f|--f|--fi|--fil|--file)
+ case "$#" in 1) usage ;; esac
+ shift
+ no_edit=t
+ log_given=t$log_given
+ logfile="$1"
+ ;;
+ -F*|-f*)
+ no_edit=t
+ log_given=t$log_given
+ logfile="${1#-[Ff]}"
+ ;;
+ --F=*|--f=*|--fi=*|--fil=*|--file=*)
+ no_edit=t
+ log_given=t$log_given
+ logfile="${1#*=}"
+ ;;
+ -a|--a|--al|--all)
+ all=t
+ ;;
+ --au=*|--aut=*|--auth=*|--autho=*|--author=*)
+ force_author="${1#*=}"
+ ;;
+ --au|--aut|--auth|--autho|--author)
+ case "$#" in 1) usage ;; esac
+ shift
+ force_author="$1"
+ ;;
+ -e|--e|--ed|--edi|--edit)
+ edit_flag=t
+ ;;
+ -i|--i|--in|--inc|--incl|--inclu|--includ|--include)
+ also=t
+ ;;
+ --int|--inte|--inter|--intera|--interac|--interact|--interacti|\
+ --interactiv|--interactive)
+ interactive=t
+ ;;
+ -o|--o|--on|--onl|--only)
+ only=t
+ ;;
+ -m|--m|--me|--mes|--mess|--messa|--messag|--message)
+ case "$#" in 1) usage ;; esac
+ shift
+ log_given=m$log_given
+ log_message="${log_message:+${log_message}
+
+}$1"
+ no_edit=t
+ ;;
+ -m*)
+ log_given=m$log_given
+ log_message="${log_message:+${log_message}
+
+}${1#-m}"
+ no_edit=t
+ ;;
+ --m=*|--me=*|--mes=*|--mess=*|--messa=*|--messag=*|--message=*)
+ log_given=m$log_given
+ log_message="${log_message:+${log_message}
+
+}${1#*=}"
+ no_edit=t
+ ;;
+ -n|--n|--no|--no-|--no-v|--no-ve|--no-ver|--no-veri|--no-verif|\
+ --no-verify)
+ verify=
+ ;;
+ --a|--am|--ame|--amen|--amend)
+ amend=t
+ use_commit=HEAD
+ ;;
+ -c)
+ case "$#" in 1) usage ;; esac
+ shift
+ log_given=t$log_given
+ use_commit="$1"
+ no_edit=
+ ;;
+ --ree=*|--reed=*|--reedi=*|--reedit=*|--reedit-=*|--reedit-m=*|\
+ --reedit-me=*|--reedit-mes=*|--reedit-mess=*|--reedit-messa=*|\
+ --reedit-messag=*|--reedit-message=*)
+ log_given=t$log_given
+ use_commit="${1#*=}"
+ no_edit=
+ ;;
+ --ree|--reed|--reedi|--reedit|--reedit-|--reedit-m|--reedit-me|\
+ --reedit-mes|--reedit-mess|--reedit-messa|--reedit-messag|\
+ --reedit-message)
+ case "$#" in 1) usage ;; esac
+ shift
+ log_given=t$log_given
+ use_commit="$1"
+ no_edit=
+ ;;
+ -C)
+ case "$#" in 1) usage ;; esac
+ shift
+ log_given=t$log_given
+ use_commit="$1"
+ no_edit=t
+ ;;
+ --reu=*|--reus=*|--reuse=*|--reuse-=*|--reuse-m=*|--reuse-me=*|\
+ --reuse-mes=*|--reuse-mess=*|--reuse-messa=*|--reuse-messag=*|\
+ --reuse-message=*)
+ log_given=t$log_given
+ use_commit="${1#*=}"
+ no_edit=t
+ ;;
+ --reu|--reus|--reuse|--reuse-|--reuse-m|--reuse-me|--reuse-mes|\
+ --reuse-mess|--reuse-messa|--reuse-messag|--reuse-message)
+ case "$#" in 1) usage ;; esac
+ shift
+ log_given=t$log_given
+ use_commit="$1"
+ no_edit=t
+ ;;
+ -s|--s|--si|--sig|--sign|--signo|--signof|--signoff)
+ signoff=t
+ ;;
+ -t|--t|--te|--tem|--temp|--templ|--templa|--templat|--template)
+ case "$#" in 1) usage ;; esac
+ shift
+ templatefile="$1"
+ no_edit=
+ ;;
+ -q|--q|--qu|--qui|--quie|--quiet)
+ quiet=t
+ ;;
+ -v|--v|--ve|--ver|--verb|--verbo|--verbos|--verbose)
+ verbose=t
+ ;;
+ -u|--u|--un|--unt|--untr|--untra|--untrac|--untrack|--untracke|\
+ --untracked|--untracked-|--untracked-f|--untracked-fi|--untracked-fil|\
+ --untracked-file|--untracked-files)
+ untracked_files=t
+ ;;
+ --)
+ shift
+ break
+ ;;
+ -*)
+ usage
+ ;;
+ *)
+ break
+ ;;
+ esac
+ shift
+done
+case "$edit_flag" in t) no_edit= ;; esac
+
+################################################################
+# Sanity check options
+
+case "$amend,$initial_commit" in
+t,t)
+ die "You do not have anything to amend." ;;
+t,)
+ if [ -f "$GIT_DIR/MERGE_HEAD" ]; then
+ die "You are in the middle of a merge -- cannot amend."
+ fi ;;
+esac
+
+case "$log_given" in
+tt*)
+ die "Only one of -c/-C/-F can be used." ;;
+*tm*|*mt*)
+ die "Option -m cannot be combined with -c/-C/-F." ;;
+esac
+
+case "$#,$also,$only,$amend" in
+*,t,t,*)
+ die "Only one of --include/--only can be used." ;;
+0,t,,* | 0,,t,)
+ die "No paths with --include/--only does not make sense." ;;
+0,,t,t)
+ only_include_assumed="# Clever... amending the last one with dirty index." ;;
+0,,,*)
+ ;;
+*,,,*)
+ only_include_assumed="# Explicit paths specified without -i nor -o; assuming --only paths..."
+ also=
+ ;;
+esac
+unset only
+case "$all,$interactive,$also,$#" in
+*t,*t,*)
+ die "Cannot use -a, --interactive or -i at the same time." ;;
+t,,[1-9]*)
+ die "Paths with -a does not make sense." ;;
+,t,[1-9]*)
+ die "Paths with --interactive does not make sense." ;;
+,,t,0)
+ die "No paths with -i does not make sense." ;;
+esac
+
+if test ! -z "$templatefile" -a -z "$log_given"
+then
+ if test ! -f "$templatefile"
+ then
+ die "Commit template file does not exist."
+ fi
+fi
+
+################################################################
+# Prepare index to have a tree to be committed
+
+case "$all,$also" in
+t,)
+ if test ! -f "$THIS_INDEX"
+ then
+ die 'nothing to commit (use "git add file1 file2" to include for commit)'
+ fi
+ save_index &&
+ (
+ cd_to_toplevel &&
+ GIT_INDEX_FILE="$NEXT_INDEX" &&
+ export GIT_INDEX_FILE &&
+ git diff-files --name-only -z |
+ git update-index --remove -z --stdin
+ ) || exit
+ ;;
+,t)
+ save_index &&
+ git ls-files --error-unmatch -- "$@" >/dev/null || exit
+
+ git diff-files --name-only -z -- "$@" |
+ (
+ cd_to_toplevel &&
+ GIT_INDEX_FILE="$NEXT_INDEX" &&
+ export GIT_INDEX_FILE &&
+ git update-index --remove -z --stdin
+ ) || exit
+ ;;
+,)
+ if test "$interactive" = t; then
+ git add --interactive || exit
+ fi
+ case "$#" in
+ 0)
+ ;; # commit as-is
+ *)
+ if test -f "$GIT_DIR/MERGE_HEAD"
+ then
+ refuse_partial "Cannot do a partial commit during a merge."
+ fi
+
+ TMP_INDEX="$GIT_DIR/tmp-index$$"
+ W=
+ test -z "$initial_commit" && W=--with-tree=HEAD
+ commit_only=`git ls-files --error-unmatch $W -- "$@"` || exit
+
+ # Build a temporary index and update the real index
+ # the same way.
+ if test -z "$initial_commit"
+ then
+ GIT_INDEX_FILE="$THIS_INDEX" \
+ git read-tree --index-output="$TMP_INDEX" -i -m HEAD
+ else
+ rm -f "$TMP_INDEX"
+ fi || exit
+
+ printf '%s\n' "$commit_only" |
+ GIT_INDEX_FILE="$TMP_INDEX" \
+ git update-index --add --remove --stdin &&
+
+ save_index &&
+ printf '%s\n' "$commit_only" |
+ (
+ GIT_INDEX_FILE="$NEXT_INDEX"
+ export GIT_INDEX_FILE
+ git update-index --add --remove --stdin
+ ) || exit
+ ;;
+ esac
+ ;;
+esac
+
+################################################################
+# If we do as-is commit, the index file will be THIS_INDEX,
+# otherwise NEXT_INDEX after we make this commit. We leave
+# the index as is if we abort.
+
+if test -f "$NEXT_INDEX"
+then
+ USE_INDEX="$NEXT_INDEX"
+else
+ USE_INDEX="$THIS_INDEX"
+fi
+
+case "$status_only" in
+t)
+ # This will silently fail in a read-only repository, which is
+ # what we want.
+ GIT_INDEX_FILE="$USE_INDEX" git update-index -q --unmerged --refresh
+ run_status
+ exit $?
+ ;;
+'')
+ GIT_INDEX_FILE="$USE_INDEX" git update-index -q --refresh || exit
+ ;;
+esac
+
+################################################################
+# Grab commit message, write out tree and make commit.
+
+if test t = "$verify" && test -x "$GIT_DIR"/hooks/pre-commit
+then
+ GIT_INDEX_FILE="${TMP_INDEX:-${USE_INDEX}}" "$GIT_DIR"/hooks/pre-commit \
+ || exit
+fi
+
+if test "$log_message" != ''
+then
+ printf '%s\n' "$log_message"
+elif test "$logfile" != ""
+then
+ if test "$logfile" = -
+ then
+ test -t 0 &&
+ echo >&2 "(reading log message from standard input)"
+ cat
+ else
+ cat <"$logfile"
+ fi
+elif test "$use_commit" != ""
+then
+ encoding=$(git config i18n.commitencoding || echo UTF-8)
+ git show -s --pretty=raw --encoding="$encoding" "$use_commit" |
+ sed -e '1,/^$/d' -e 's/^ //'
+elif test -f "$GIT_DIR/MERGE_MSG"
+then
+ cat "$GIT_DIR/MERGE_MSG"
+elif test -f "$GIT_DIR/SQUASH_MSG"
+then
+ cat "$GIT_DIR/SQUASH_MSG"
+elif test "$templatefile" != ""
+then
+ cat "$templatefile"
+fi | git stripspace >"$GIT_DIR"/COMMIT_EDITMSG
+
+case "$signoff" in
+t)
+ sign=$(git-var GIT_COMMITTER_IDENT | sed -e '
+ s/>.*/>/
+ s/^/Signed-off-by: /
+ ')
+ blank_before_signoff=
+ tail -n 1 "$GIT_DIR"/COMMIT_EDITMSG |
+ grep 'Signed-off-by:' >/dev/null || blank_before_signoff='
+'
+ tail -n 1 "$GIT_DIR"/COMMIT_EDITMSG |
+ grep "$sign"$ >/dev/null ||
+ printf '%s%s\n' "$blank_before_signoff" "$sign" \
+ >>"$GIT_DIR"/COMMIT_EDITMSG
+ ;;
+esac
+
+if test -f "$GIT_DIR/MERGE_HEAD" && test -z "$no_edit"; then
+ echo "#"
+ echo "# It looks like you may be committing a MERGE."
+ echo "# If this is not correct, please remove the file"
+ printf '%s\n' "# $GIT_DIR/MERGE_HEAD"
+ echo "# and try again"
+ echo "#"
+fi >>"$GIT_DIR"/COMMIT_EDITMSG
+
+# Author
+if test '' != "$use_commit"
+then
+ eval "$(get_author_ident_from_commit "$use_commit")"
+ export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_AUTHOR_DATE
+fi
+if test '' != "$force_author"
+then
+ GIT_AUTHOR_NAME=`expr "z$force_author" : 'z\(.*[^ ]\) *<.*'` &&
+ GIT_AUTHOR_EMAIL=`expr "z$force_author" : '.*\(<.*\)'` &&
+ test '' != "$GIT_AUTHOR_NAME" &&
+ test '' != "$GIT_AUTHOR_EMAIL" ||
+ die "malformed --author parameter"
+ export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL
+fi
+
+PARENTS="-p HEAD"
+if test -z "$initial_commit"
+then
+ rloga='commit'
+ if [ -f "$GIT_DIR/MERGE_HEAD" ]; then
+ rloga='commit (merge)'
+ PARENTS="-p HEAD "`sed -e 's/^/-p /' "$GIT_DIR/MERGE_HEAD"`
+ elif test -n "$amend"; then
+ rloga='commit (amend)'
+ PARENTS=$(git cat-file commit HEAD |
+ sed -n -e '/^$/q' -e 's/^parent /-p /p')
+ fi
+ current="$(git rev-parse --verify HEAD)"
+else
+ if [ -z "$(git ls-files)" ]; then
+ echo >&2 'nothing to commit (use "git add file1 file2" to include for commit)'
+ exit 1
+ fi
+ PARENTS=""
+ rloga='commit (initial)'
+ current=''
+fi
+set_reflog_action "$rloga"
+
+if test -z "$no_edit"
+then
+ {
+ echo ""
+ echo "# Please enter the commit message for your changes."
+ echo "# (Comment lines starting with '#' will not be included)"
+ test -z "$only_include_assumed" || echo "$only_include_assumed"
+ run_status
+ } >>"$GIT_DIR"/COMMIT_EDITMSG
+else
+ # we need to check if there is anything to commit
+ run_status >/dev/null
+fi
+if [ "$?" != "0" -a ! -f "$GIT_DIR/MERGE_HEAD" ]
+then
+ rm -f "$GIT_DIR/COMMIT_EDITMSG" "$GIT_DIR/SQUASH_MSG"
+ use_status_color=t
+ run_status
+ exit 1
+fi
+
+case "$no_edit" in
+'')
+ git-var GIT_AUTHOR_IDENT > /dev/null || die
+ git-var GIT_COMMITTER_IDENT > /dev/null || die
+ git_editor "$GIT_DIR/COMMIT_EDITMSG"
+ ;;
+esac
+
+case "$verify" in
+t)
+ if test -x "$GIT_DIR"/hooks/commit-msg
+ then
+ "$GIT_DIR"/hooks/commit-msg "$GIT_DIR"/COMMIT_EDITMSG || exit
+ fi
+esac
+
+if test -z "$no_edit"
+then
+ sed -e '
+ /^diff --git a\/.*/{
+ s///
+ q
+ }
+ /^#/d
+ ' "$GIT_DIR"/COMMIT_EDITMSG
+else
+ cat "$GIT_DIR"/COMMIT_EDITMSG
+fi |
+git stripspace >"$GIT_DIR"/COMMIT_MSG
+
+# Test whether the commit message has any content we didn't supply.
+have_commitmsg=
+grep -v -i '^Signed-off-by' "$GIT_DIR"/COMMIT_MSG |
+ git stripspace > "$GIT_DIR"/COMMIT_BAREMSG
+
+# Is the commit message totally empty?
+if test -s "$GIT_DIR"/COMMIT_BAREMSG
+then
+ if test "$templatefile" != ""
+ then
+ # Test whether this is just the unaltered template.
+ if cnt=`sed -e '/^#/d' < "$templatefile" |
+ git stripspace |
+ diff "$GIT_DIR"/COMMIT_BAREMSG - |
+ wc -l` &&
+ test 0 -lt $cnt
+ then
+ have_commitmsg=t
+ fi
+ else
+ # No template, so the content in the commit message must
+ # have come from the user.
+ have_commitmsg=t
+ fi
+fi
+
+rm -f "$GIT_DIR"/COMMIT_BAREMSG
+
+if test "$have_commitmsg" = "t"
+then
+ if test -z "$TMP_INDEX"
+ then
+ tree=$(GIT_INDEX_FILE="$USE_INDEX" git write-tree)
+ else
+ tree=$(GIT_INDEX_FILE="$TMP_INDEX" git write-tree) &&
+ rm -f "$TMP_INDEX"
+ fi &&
+ commit=$(git commit-tree $tree $PARENTS <"$GIT_DIR/COMMIT_MSG") &&
+ rlogm=$(sed -e 1q "$GIT_DIR"/COMMIT_MSG) &&
+ git update-ref -m "$GIT_REFLOG_ACTION: $rlogm" HEAD $commit "$current" &&
+ rm -f -- "$GIT_DIR/MERGE_HEAD" "$GIT_DIR/MERGE_MSG" &&
+ if test -f "$NEXT_INDEX"
+ then
+ mv "$NEXT_INDEX" "$THIS_INDEX"
+ else
+ : ;# happy
+ fi
+else
+ echo >&2 "* no commit message? aborting commit."
+ false
+fi
+ret="$?"
+rm -f "$GIT_DIR/COMMIT_MSG" "$GIT_DIR/COMMIT_EDITMSG" "$GIT_DIR/SQUASH_MSG"
+
+cd_to_toplevel
+
+git rerere
+
+if test "$ret" = 0
+then
+ git gc --auto
+ if test -x "$GIT_DIR"/hooks/post-commit
+ then
+ "$GIT_DIR"/hooks/post-commit
+ fi
+ if test -z "$quiet"
+ then
+ commit=`git diff-tree --always --shortstat --pretty="format:%h: %s"\
+ --summary --root HEAD --`
+ echo "Created${initial_commit:+ initial} commit $commit"
+ fi
+fi
+
+exit "$ret"
diff --git a/git-commit.sh b/git-commit.sh
deleted file mode 100755
index fcb8443..0000000
--- a/git-commit.sh
+++ /dev/null
@@ -1,628 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2005 Linus Torvalds
-# Copyright (c) 2006 Junio C Hamano
-
-USAGE='[-a | --interactive] [-s] [-v] [--no-verify] [-m <message> | -F <logfile> | (-C|-c) <commit> | --amend] [-u] [-e] [--author <author>] [--template <file>] [[-i | -o] <path>...]'
-SUBDIRECTORY_OK=Yes
-. git-sh-setup
-require_work_tree
-
-git rev-parse --verify HEAD >/dev/null 2>&1 || initial_commit=t
-
-case "$0" in
-*status)
- status_only=t
- ;;
-*commit)
- status_only=
- ;;
-esac
-
-refuse_partial () {
- echo >&2 "$1"
- echo >&2 "You might have meant to say 'git commit -i paths...', perhaps?"
- exit 1
-}
-
-TMP_INDEX=
-THIS_INDEX="$GIT_DIR/index"
-NEXT_INDEX="$GIT_DIR/next-index$$"
-rm -f "$NEXT_INDEX"
-save_index () {
- cp -p "$THIS_INDEX" "$NEXT_INDEX"
-}
-
-run_status () {
- # If TMP_INDEX is defined, that means we are doing
- # "--only" partial commit, and that index file is used
- # to build the tree for the commit. Otherwise, if
- # NEXT_INDEX exists, that is the index file used to
- # make the commit. Otherwise we are using as-is commit
- # so the regular index file is what we use to compare.
- if test '' != "$TMP_INDEX"
- then
- GIT_INDEX_FILE="$TMP_INDEX"
- export GIT_INDEX_FILE
- elif test -f "$NEXT_INDEX"
- then
- GIT_INDEX_FILE="$NEXT_INDEX"
- export GIT_INDEX_FILE
- fi
-
- if test "$status_only" = "t" -o "$use_status_color" = "t"; then
- color=
- else
- color=--nocolor
- fi
- git runstatus ${color} \
- ${verbose:+--verbose} \
- ${amend:+--amend} \
- ${untracked_files:+--untracked}
-}
-
-trap '
- test -z "$TMP_INDEX" || {
- test -f "$TMP_INDEX" && rm -f "$TMP_INDEX"
- }
- rm -f "$NEXT_INDEX"
-' 0
-
-################################################################
-# Command line argument parsing and sanity checking
-
-all=
-also=
-interactive=
-only=
-logfile=
-use_commit=
-amend=
-edit_flag=
-no_edit=
-log_given=
-log_message=
-verify=t
-quiet=
-verbose=
-signoff=
-force_author=
-only_include_assumed=
-untracked_files=
-templatefile="`git config commit.template`"
-while test $# != 0
-do
- case "$1" in
- -F|--F|-f|--f|--fi|--fil|--file)
- case "$#" in 1) usage ;; esac
- shift
- no_edit=t
- log_given=t$log_given
- logfile="$1"
- ;;
- -F*|-f*)
- no_edit=t
- log_given=t$log_given
- logfile="${1#-[Ff]}"
- ;;
- --F=*|--f=*|--fi=*|--fil=*|--file=*)
- no_edit=t
- log_given=t$log_given
- logfile="${1#*=}"
- ;;
- -a|--a|--al|--all)
- all=t
- ;;
- --au=*|--aut=*|--auth=*|--autho=*|--author=*)
- force_author="${1#*=}"
- ;;
- --au|--aut|--auth|--autho|--author)
- case "$#" in 1) usage ;; esac
- shift
- force_author="$1"
- ;;
- -e|--e|--ed|--edi|--edit)
- edit_flag=t
- ;;
- -i|--i|--in|--inc|--incl|--inclu|--includ|--include)
- also=t
- ;;
- --int|--inte|--inter|--intera|--interac|--interact|--interacti|\
- --interactiv|--interactive)
- interactive=t
- ;;
- -o|--o|--on|--onl|--only)
- only=t
- ;;
- -m|--m|--me|--mes|--mess|--messa|--messag|--message)
- case "$#" in 1) usage ;; esac
- shift
- log_given=m$log_given
- log_message="${log_message:+${log_message}
-
-}$1"
- no_edit=t
- ;;
- -m*)
- log_given=m$log_given
- log_message="${log_message:+${log_message}
-
-}${1#-m}"
- no_edit=t
- ;;
- --m=*|--me=*|--mes=*|--mess=*|--messa=*|--messag=*|--message=*)
- log_given=m$log_given
- log_message="${log_message:+${log_message}
-
-}${1#*=}"
- no_edit=t
- ;;
- -n|--n|--no|--no-|--no-v|--no-ve|--no-ver|--no-veri|--no-verif|\
- --no-verify)
- verify=
- ;;
- --a|--am|--ame|--amen|--amend)
- amend=t
- use_commit=HEAD
- ;;
- -c)
- case "$#" in 1) usage ;; esac
- shift
- log_given=t$log_given
- use_commit="$1"
- no_edit=
- ;;
- --ree=*|--reed=*|--reedi=*|--reedit=*|--reedit-=*|--reedit-m=*|\
- --reedit-me=*|--reedit-mes=*|--reedit-mess=*|--reedit-messa=*|\
- --reedit-messag=*|--reedit-message=*)
- log_given=t$log_given
- use_commit="${1#*=}"
- no_edit=
- ;;
- --ree|--reed|--reedi|--reedit|--reedit-|--reedit-m|--reedit-me|\
- --reedit-mes|--reedit-mess|--reedit-messa|--reedit-messag|\
- --reedit-message)
- case "$#" in 1) usage ;; esac
- shift
- log_given=t$log_given
- use_commit="$1"
- no_edit=
- ;;
- -C)
- case "$#" in 1) usage ;; esac
- shift
- log_given=t$log_given
- use_commit="$1"
- no_edit=t
- ;;
- --reu=*|--reus=*|--reuse=*|--reuse-=*|--reuse-m=*|--reuse-me=*|\
- --reuse-mes=*|--reuse-mess=*|--reuse-messa=*|--reuse-messag=*|\
- --reuse-message=*)
- log_given=t$log_given
- use_commit="${1#*=}"
- no_edit=t
- ;;
- --reu|--reus|--reuse|--reuse-|--reuse-m|--reuse-me|--reuse-mes|\
- --reuse-mess|--reuse-messa|--reuse-messag|--reuse-message)
- case "$#" in 1) usage ;; esac
- shift
- log_given=t$log_given
- use_commit="$1"
- no_edit=t
- ;;
- -s|--s|--si|--sig|--sign|--signo|--signof|--signoff)
- signoff=t
- ;;
- -t|--t|--te|--tem|--temp|--templ|--templa|--templat|--template)
- case "$#" in 1) usage ;; esac
- shift
- templatefile="$1"
- no_edit=
- ;;
- -q|--q|--qu|--qui|--quie|--quiet)
- quiet=t
- ;;
- -v|--v|--ve|--ver|--verb|--verbo|--verbos|--verbose)
- verbose=t
- ;;
- -u|--u|--un|--unt|--untr|--untra|--untrac|--untrack|--untracke|\
- --untracked|--untracked-|--untracked-f|--untracked-fi|--untracked-fil|\
- --untracked-file|--untracked-files)
- untracked_files=t
- ;;
- --)
- shift
- break
- ;;
- -*)
- usage
- ;;
- *)
- break
- ;;
- esac
- shift
-done
-case "$edit_flag" in t) no_edit= ;; esac
-
-################################################################
-# Sanity check options
-
-case "$amend,$initial_commit" in
-t,t)
- die "You do not have anything to amend." ;;
-t,)
- if [ -f "$GIT_DIR/MERGE_HEAD" ]; then
- die "You are in the middle of a merge -- cannot amend."
- fi ;;
-esac
-
-case "$log_given" in
-tt*)
- die "Only one of -c/-C/-F can be used." ;;
-*tm*|*mt*)
- die "Option -m cannot be combined with -c/-C/-F." ;;
-esac
-
-case "$#,$also,$only,$amend" in
-*,t,t,*)
- die "Only one of --include/--only can be used." ;;
-0,t,,* | 0,,t,)
- die "No paths with --include/--only does not make sense." ;;
-0,,t,t)
- only_include_assumed="# Clever... amending the last one with dirty index." ;;
-0,,,*)
- ;;
-*,,,*)
- only_include_assumed="# Explicit paths specified without -i nor -o; assuming --only paths..."
- also=
- ;;
-esac
-unset only
-case "$all,$interactive,$also,$#" in
-*t,*t,*)
- die "Cannot use -a, --interactive or -i at the same time." ;;
-t,,[1-9]*)
- die "Paths with -a does not make sense." ;;
-,t,[1-9]*)
- die "Paths with --interactive does not make sense." ;;
-,,t,0)
- die "No paths with -i does not make sense." ;;
-esac
-
-if test ! -z "$templatefile" -a -z "$log_given"
-then
- if test ! -f "$templatefile"
- then
- die "Commit template file does not exist."
- fi
-fi
-
-################################################################
-# Prepare index to have a tree to be committed
-
-case "$all,$also" in
-t,)
- if test ! -f "$THIS_INDEX"
- then
- die 'nothing to commit (use "git add file1 file2" to include for commit)'
- fi
- save_index &&
- (
- cd_to_toplevel &&
- GIT_INDEX_FILE="$NEXT_INDEX" &&
- export GIT_INDEX_FILE &&
- git diff-files --name-only -z |
- git update-index --remove -z --stdin
- ) || exit
- ;;
-,t)
- save_index &&
- git ls-files --error-unmatch -- "$@" >/dev/null || exit
-
- git diff-files --name-only -z -- "$@" |
- (
- cd_to_toplevel &&
- GIT_INDEX_FILE="$NEXT_INDEX" &&
- export GIT_INDEX_FILE &&
- git update-index --remove -z --stdin
- ) || exit
- ;;
-,)
- if test "$interactive" = t; then
- git add --interactive || exit
- fi
- case "$#" in
- 0)
- ;; # commit as-is
- *)
- if test -f "$GIT_DIR/MERGE_HEAD"
- then
- refuse_partial "Cannot do a partial commit during a merge."
- fi
-
- TMP_INDEX="$GIT_DIR/tmp-index$$"
- W=
- test -z "$initial_commit" && W=--with-tree=HEAD
- commit_only=`git ls-files --error-unmatch $W -- "$@"` || exit
-
- # Build a temporary index and update the real index
- # the same way.
- if test -z "$initial_commit"
- then
- GIT_INDEX_FILE="$THIS_INDEX" \
- git read-tree --index-output="$TMP_INDEX" -i -m HEAD
- else
- rm -f "$TMP_INDEX"
- fi || exit
-
- printf '%s\n' "$commit_only" |
- GIT_INDEX_FILE="$TMP_INDEX" \
- git update-index --add --remove --stdin &&
-
- save_index &&
- printf '%s\n' "$commit_only" |
- (
- GIT_INDEX_FILE="$NEXT_INDEX"
- export GIT_INDEX_FILE
- git update-index --add --remove --stdin
- ) || exit
- ;;
- esac
- ;;
-esac
-
-################################################################
-# If we do as-is commit, the index file will be THIS_INDEX,
-# otherwise NEXT_INDEX after we make this commit. We leave
-# the index as is if we abort.
-
-if test -f "$NEXT_INDEX"
-then
- USE_INDEX="$NEXT_INDEX"
-else
- USE_INDEX="$THIS_INDEX"
-fi
-
-case "$status_only" in
-t)
- # This will silently fail in a read-only repository, which is
- # what we want.
- GIT_INDEX_FILE="$USE_INDEX" git update-index -q --unmerged --refresh
- run_status
- exit $?
- ;;
-'')
- GIT_INDEX_FILE="$USE_INDEX" git update-index -q --refresh || exit
- ;;
-esac
-
-################################################################
-# Grab commit message, write out tree and make commit.
-
-if test t = "$verify" && test -x "$GIT_DIR"/hooks/pre-commit
-then
- GIT_INDEX_FILE="${TMP_INDEX:-${USE_INDEX}}" "$GIT_DIR"/hooks/pre-commit \
- || exit
-fi
-
-if test "$log_message" != ''
-then
- printf '%s\n' "$log_message"
-elif test "$logfile" != ""
-then
- if test "$logfile" = -
- then
- test -t 0 &&
- echo >&2 "(reading log message from standard input)"
- cat
- else
- cat <"$logfile"
- fi
-elif test "$use_commit" != ""
-then
- encoding=$(git config i18n.commitencoding || echo UTF-8)
- git show -s --pretty=raw --encoding="$encoding" "$use_commit" |
- sed -e '1,/^$/d' -e 's/^ //'
-elif test -f "$GIT_DIR/MERGE_MSG"
-then
- cat "$GIT_DIR/MERGE_MSG"
-elif test -f "$GIT_DIR/SQUASH_MSG"
-then
- cat "$GIT_DIR/SQUASH_MSG"
-elif test "$templatefile" != ""
-then
- cat "$templatefile"
-fi | git stripspace >"$GIT_DIR"/COMMIT_EDITMSG
-
-case "$signoff" in
-t)
- sign=$(git-var GIT_COMMITTER_IDENT | sed -e '
- s/>.*/>/
- s/^/Signed-off-by: /
- ')
- blank_before_signoff=
- tail -n 1 "$GIT_DIR"/COMMIT_EDITMSG |
- grep 'Signed-off-by:' >/dev/null || blank_before_signoff='
-'
- tail -n 1 "$GIT_DIR"/COMMIT_EDITMSG |
- grep "$sign"$ >/dev/null ||
- printf '%s%s\n' "$blank_before_signoff" "$sign" \
- >>"$GIT_DIR"/COMMIT_EDITMSG
- ;;
-esac
-
-if test -f "$GIT_DIR/MERGE_HEAD" && test -z "$no_edit"; then
- echo "#"
- echo "# It looks like you may be committing a MERGE."
- echo "# If this is not correct, please remove the file"
- printf '%s\n' "# $GIT_DIR/MERGE_HEAD"
- echo "# and try again"
- echo "#"
-fi >>"$GIT_DIR"/COMMIT_EDITMSG
-
-# Author
-if test '' != "$use_commit"
-then
- eval "$(get_author_ident_from_commit "$use_commit")"
- export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_AUTHOR_DATE
-fi
-if test '' != "$force_author"
-then
- GIT_AUTHOR_NAME=`expr "z$force_author" : 'z\(.*[^ ]\) *<.*'` &&
- GIT_AUTHOR_EMAIL=`expr "z$force_author" : '.*\(<.*\)'` &&
- test '' != "$GIT_AUTHOR_NAME" &&
- test '' != "$GIT_AUTHOR_EMAIL" ||
- die "malformed --author parameter"
- export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL
-fi
-
-PARENTS="-p HEAD"
-if test -z "$initial_commit"
-then
- rloga='commit'
- if [ -f "$GIT_DIR/MERGE_HEAD" ]; then
- rloga='commit (merge)'
- PARENTS="-p HEAD "`sed -e 's/^/-p /' "$GIT_DIR/MERGE_HEAD"`
- elif test -n "$amend"; then
- rloga='commit (amend)'
- PARENTS=$(git cat-file commit HEAD |
- sed -n -e '/^$/q' -e 's/^parent /-p /p')
- fi
- current="$(git rev-parse --verify HEAD)"
-else
- if [ -z "$(git ls-files)" ]; then
- echo >&2 'nothing to commit (use "git add file1 file2" to include for commit)'
- exit 1
- fi
- PARENTS=""
- rloga='commit (initial)'
- current=''
-fi
-set_reflog_action "$rloga"
-
-if test -z "$no_edit"
-then
- {
- echo ""
- echo "# Please enter the commit message for your changes."
- echo "# (Comment lines starting with '#' will not be included)"
- test -z "$only_include_assumed" || echo "$only_include_assumed"
- run_status
- } >>"$GIT_DIR"/COMMIT_EDITMSG
-else
- # we need to check if there is anything to commit
- run_status >/dev/null
-fi
-if [ "$?" != "0" -a ! -f "$GIT_DIR/MERGE_HEAD" ]
-then
- rm -f "$GIT_DIR/COMMIT_EDITMSG" "$GIT_DIR/SQUASH_MSG"
- use_status_color=t
- run_status
- exit 1
-fi
-
-case "$no_edit" in
-'')
- git-var GIT_AUTHOR_IDENT > /dev/null || die
- git-var GIT_COMMITTER_IDENT > /dev/null || die
- git_editor "$GIT_DIR/COMMIT_EDITMSG"
- ;;
-esac
-
-case "$verify" in
-t)
- if test -x "$GIT_DIR"/hooks/commit-msg
- then
- "$GIT_DIR"/hooks/commit-msg "$GIT_DIR"/COMMIT_EDITMSG || exit
- fi
-esac
-
-if test -z "$no_edit"
-then
- sed -e '
- /^diff --git a\/.*/{
- s///
- q
- }
- /^#/d
- ' "$GIT_DIR"/COMMIT_EDITMSG
-else
- cat "$GIT_DIR"/COMMIT_EDITMSG
-fi |
-git stripspace >"$GIT_DIR"/COMMIT_MSG
-
-# Test whether the commit message has any content we didn't supply.
-have_commitmsg=
-grep -v -i '^Signed-off-by' "$GIT_DIR"/COMMIT_MSG |
- git stripspace > "$GIT_DIR"/COMMIT_BAREMSG
-
-# Is the commit message totally empty?
-if test -s "$GIT_DIR"/COMMIT_BAREMSG
-then
- if test "$templatefile" != ""
- then
- # Test whether this is just the unaltered template.
- if cnt=`sed -e '/^#/d' < "$templatefile" |
- git stripspace |
- diff "$GIT_DIR"/COMMIT_BAREMSG - |
- wc -l` &&
- test 0 -lt $cnt
- then
- have_commitmsg=t
- fi
- else
- # No template, so the content in the commit message must
- # have come from the user.
- have_commitmsg=t
- fi
-fi
-
-rm -f "$GIT_DIR"/COMMIT_BAREMSG
-
-if test "$have_commitmsg" = "t"
-then
- if test -z "$TMP_INDEX"
- then
- tree=$(GIT_INDEX_FILE="$USE_INDEX" git write-tree)
- else
- tree=$(GIT_INDEX_FILE="$TMP_INDEX" git write-tree) &&
- rm -f "$TMP_INDEX"
- fi &&
- commit=$(git commit-tree $tree $PARENTS <"$GIT_DIR/COMMIT_MSG") &&
- rlogm=$(sed -e 1q "$GIT_DIR"/COMMIT_MSG) &&
- git update-ref -m "$GIT_REFLOG_ACTION: $rlogm" HEAD $commit "$current" &&
- rm -f -- "$GIT_DIR/MERGE_HEAD" "$GIT_DIR/MERGE_MSG" &&
- if test -f "$NEXT_INDEX"
- then
- mv "$NEXT_INDEX" "$THIS_INDEX"
- else
- : ;# happy
- fi
-else
- echo >&2 "* no commit message? aborting commit."
- false
-fi
-ret="$?"
-rm -f "$GIT_DIR/COMMIT_MSG" "$GIT_DIR/COMMIT_EDITMSG" "$GIT_DIR/SQUASH_MSG"
-
-cd_to_toplevel
-
-git rerere
-
-if test "$ret" = 0
-then
- git gc --auto
- if test -x "$GIT_DIR"/hooks/post-commit
- then
- "$GIT_DIR"/hooks/post-commit
- fi
- if test -z "$quiet"
- then
- commit=`git diff-tree --always --shortstat --pretty="format:%h: %s"\
- --summary --root HEAD --`
- echo "Created${initial_commit:+ initial} commit $commit"
- fi
-fi
-
-exit "$ret"
diff --git a/git.c b/git.c
index 19a2172..1016e04 100644
--- a/git.c
+++ b/git.c
@@ -298,6 +298,7 @@ static void handle_internal_command(int argc, const char **argv)
{ "check-attr", cmd_check_attr, RUN_SETUP | NEED_WORK_TREE },
{ "cherry", cmd_cherry, RUN_SETUP },
{ "cherry-pick", cmd_cherry_pick, RUN_SETUP | NEED_WORK_TREE },
+ { "commit", cmd_commit, RUN_SETUP | NEED_WORK_TREE },
{ "commit-tree", cmd_commit_tree, RUN_SETUP },
{ "config", cmd_config },
{ "count-objects", cmd_count_objects, RUN_SETUP },
@@ -347,11 +348,11 @@ static void handle_internal_command(int argc, const char **argv)
{ "rev-parse", cmd_rev_parse, RUN_SETUP },
{ "revert", cmd_revert, RUN_SETUP | NEED_WORK_TREE },
{ "rm", cmd_rm, RUN_SETUP | NEED_WORK_TREE },
- { "runstatus", cmd_runstatus, RUN_SETUP | NEED_WORK_TREE },
{ "send-pack", cmd_send_pack, RUN_SETUP },
{ "shortlog", cmd_shortlog, RUN_SETUP | USE_PAGER },
{ "show-branch", cmd_show_branch, RUN_SETUP },
{ "show", cmd_show, RUN_SETUP | USE_PAGER },
+ { "status", cmd_status, RUN_SETUP | NEED_WORK_TREE },
{ "stripspace", cmd_stripspace },
{ "symbolic-ref", cmd_symbolic_ref, RUN_SETUP },
{ "tag", cmd_tag, RUN_SETUP },
diff --git a/strbuf.h b/strbuf.h
index 9b9e861..9720826 100644
--- a/strbuf.h
+++ b/strbuf.h
@@ -113,5 +113,6 @@ extern int strbuf_read_file(struct strbuf *sb, const char *path, size_t hint);
extern int strbuf_getline(struct strbuf *, FILE *, int);
extern void stripspace(struct strbuf *buf, int skip_comments);
+extern void launch_editor(const char *path, struct strbuf *buffer);
#endif /* STRBUF_H */
--
1.5.3.4
^ permalink raw reply related [relevance 2%]
* Re: Cloning from kernel.org, then switching to another repo
@ 2007-11-13 4:14 4% ` Jeff King
0 siblings, 0 replies; 200+ results
From: Jeff King @ 2007-11-13 4:14 UTC (permalink / raw)
To: Jon Smirl; +Cc: Johannes Schindelin, Git Mailing List
On Mon, Nov 12, 2007 at 12:28:28PM -0500, Jon Smirl wrote:
> Actually, fetching from kernel.org first and then switching the origin
> isn't helping. The host is http only since I can't get access to the
> git network port. When I pushed up my local repo it ends up in one big
> pack.
>
> I do this:
> git clone kernel.org
> move the origin
> git pull
> -- it still pulls down the entire pack and takes an hour
Yep, the http fetch code doesn't understand about fetching parts of
packs (there was some discussion about using partial HTTP transfers, but
nobody seems to have cared enough to implement it).
> Will this fix it?
> at my remote host, first clone from kernel.org
> then push my local changes?
Yes, it should. The goal is to not put your changes and the upstream
commits in the same pack. You could also push _just_ the upstream
commits first, then in a different push, send your local changes. But
when they get pushed together, they all end up in the same pack.
-Peff
^ permalink raw reply [relevance 4%]
* Re: [PATCH] Improved and extended t5404
@ 2007-11-14 21:52 3% ` Junio C Hamano
2007-11-14 22:49 3% ` [PATCH] Add test that checks diverse aspects of updating remote and tracking branches Alex Riesen
2007-11-14 21:52 3% ` [PATCH] Improved and extended t5404 Junio C Hamano
2 siblings, 1 reply; 200+ results
From: Junio C Hamano @ 2007-11-14 21:52 UTC (permalink / raw)
To: Alex Riesen; +Cc: git, Jeff King
Alex Riesen <raa.lkml@gmail.com> writes:
> Ignore exit code of git push in t5404, as it is not relevant for the
> test: it already checks whether the references updated correctly.
I think the Subject: goes a lot better with a description like this:
Add test that checks the case where X does Y and make
sure Z happens.
Because we haven't settled on what the exit status from
"git push" command itself should be in such a partial
failure case, do not check the exit status from it for
now.
> diff --git a/t/t5404-tracking-branches.sh b/t/t5404-tracking-branches.sh
> index 20718d4..a51bbdc 100755
> --- a/t/t5404-tracking-branches.sh
> +++ b/t/t5404-tracking-branches.sh
> @@ -10,6 +10,7 @@ test_expect_success 'setup' '
> git commit -m 1 &&
> git branch b1 &&
> git branch b2 &&
> + git branch b3 &&
> git clone . aa &&
> git checkout b1 &&
> ...
So it makes another ref "b3" point at the initial commit,...
> ...
> test_expect_success 'check tracking branches updated correctly after push' '
> cd aa &&
> b1=$(git rev-parse origin/b1) &&
> b2=$(git rev-parse origin/b2) &&
> + b3=$(git rev-parse origin/b3) &&
> git checkout -b b1 origin/b1 &&
> echo aa-b1 >>file &&
> git commit -a -m aa-b1 &&
... then records what was cloned,...
> @@ -32,9 +36,28 @@ test_expect_success 'check tracking branches updated correctly after push' '
> git checkout master &&
> echo aa-master >>file &&
> git commit -a -m aa-master &&
> + {
> + git push
> + test "$(git rev-parse origin/b1)" = "$b1" &&
> + test "$(git rev-parse origin/b2)" = "$b2" &&
> + test "$(git rev-parse origin/b3)" = "$b3" &&
> + test "$(git rev-parse origin/master)" = \
> + "$(git rev-parse master)"
> + }
> +'
... and checks that untouched "b3" stays the same (iow, tests
up-to-date case).
> +
> +test_expect_success 'delete remote branch' '
> + git push origin :refs/heads/b3
> + {
> + git rev-parse origin/b3
> + test $? != 0 || \
> + say "Hmm... Maybe tracking ref should be deleted?"
> + } &&
Ah, you meant that tracking should be deleted so this should be
fixed in the code but the test is disabled for now. Let's be a
bit more explicit about such a temporary disabled test, like
this:
git push origin :refs/heads/b3
# The remote-tracking branch origin/b3 should be deleted;
# we need to update the code and enable this test.
: git rev-parse --verify origin/b3 &&
> + cd "$start_dir" &&
> + {
> + git rev-parse refs/heads/b3
> + test $? != 0
> + }
> '
^ permalink raw reply [relevance 3%]
* Re: [PATCH] Improved and extended t5404
2007-11-14 21:52 3% ` [PATCH] Improved and extended t5404 Junio C Hamano
@ 2007-11-14 21:52 3% ` Junio C Hamano
2 siblings, 0 replies; 200+ results
From: Junio C Hamano @ 2007-11-14 21:52 UTC (permalink / raw)
To: Alex Riesen; +Cc: git, Jeff King
Alex Riesen <raa.lkml@gmail.com> writes:
> Ignore exit code of git push in t5404, as it is not relevant for the
> test: it already checks whether the references updated correctly.
I think the Subject: goes a lot better with a description like this:
Enhance the test to check the case where X does Y and to
make sure Z happens.
Because we haven't settled on what the exit status from
"git push" command itself should be in such a partial
failure case, do not check the exit status from it for
now.
> diff --git a/t/t5404-tracking-branches.sh b/t/t5404-tracking-branches.sh
> index 20718d4..a51bbdc 100755
> --- a/t/t5404-tracking-branches.sh
> +++ b/t/t5404-tracking-branches.sh
> @@ -10,6 +10,7 @@ test_expect_success 'setup' '
> git commit -m 1 &&
> git branch b1 &&
> git branch b2 &&
> + git branch b3 &&
> git clone . aa &&
> git checkout b1 &&
> ...
So it makes another ref "b3" point at the initial commit,...
> ...
> test_expect_success 'check tracking branches updated correctly after push' '
> cd aa &&
> b1=$(git rev-parse origin/b1) &&
> b2=$(git rev-parse origin/b2) &&
> + b3=$(git rev-parse origin/b3) &&
> git checkout -b b1 origin/b1 &&
> echo aa-b1 >>file &&
> git commit -a -m aa-b1 &&
... then records what was cloned,...
> @@ -32,9 +36,28 @@ test_expect_success 'check tracking branches updated correctly after push' '
> git checkout master &&
> echo aa-master >>file &&
> git commit -a -m aa-master &&
> + {
> + git push
> + test "$(git rev-parse origin/b1)" = "$b1" &&
> + test "$(git rev-parse origin/b2)" = "$b2" &&
> + test "$(git rev-parse origin/b3)" = "$b3" &&
> + test "$(git rev-parse origin/master)" = \
> + "$(git rev-parse master)"
> + }
> +'
... and checks that untouched "b3" stays the same (iow, tests
up-to-date case).
> +
> +test_expect_success 'delete remote branch' '
> + git push origin :refs/heads/b3
> + {
> + git rev-parse origin/b3
> + test $? != 0 || \
> + say "Hmm... Maybe tracking ref should be deleted?"
> + } &&
Ah, you meant that tracking should be deleted so this should be
fixed in the code but the test is disabled for now. Let's be a
bit more explicit about such a temporary disabled test, like
this:
git push origin :refs/heads/b3
# The remote-tracking branch origin/b3 should be deleted;
# we need to update the code and enable this test.
: git rev-parse --verify origin/b3 &&
> + cd "$start_dir" &&
> + {
> + git rev-parse refs/heads/b3
> + test $? != 0
> + }
> '
^ permalink raw reply [relevance 3%]
* [PATCH] Add test that checks diverse aspects of updating remote and tracking branches
2007-11-14 21:52 3% ` [PATCH] Improved and extended t5404 Junio C Hamano
@ 2007-11-14 22:49 3% ` Alex Riesen
0 siblings, 0 replies; 200+ results
From: Alex Riesen @ 2007-11-14 22:49 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, Jeff King, Johannes Schindelin
Because we haven't settled on what the exit status from
"git push" command itself should be in such a partial
failure case, do not check the exit status from it for
now.
Signed-off-by: Alex Riesen <raa.lkml@gmail.com>
---
Junio C Hamano, Wed, Nov 14, 2007 22:52:19 +0100:
> Alex Riesen <raa.lkml@gmail.com> writes:
>
> > Ignore exit code of git push in t5404, as it is not relevant for the
> > test: it already checks whether the references updated correctly.
>
> I think the Subject: goes a lot better with a description like this:
>
> Add test that checks the case where X does Y and make
> sure Z happens.
Add test that checks diverse aspects of updating remote and tracking
branches.
> Because we haven't settled on what the exit status from
> "git push" command itself should be in such a partial
> failure case, do not check the exit status from it for
> now.
This I'll leave as is.
> > + git branch b3 &&
>
> So it makes another ref "b3" point at the initial commit,...
Right
> > + b3=$(git rev-parse origin/b3) &&
>
> ... then records what was cloned,...
Precisely
> > + test "$(git rev-parse origin/b3)" = "$b3" &&
>
> ... and checks that untouched "b3" stays the same (iow, tests
> up-to-date case).
Yep.
> > +
> > +test_expect_success 'delete remote branch' '
> > + git push origin :refs/heads/b3
> > + {
> > + git rev-parse origin/b3
> > + test $? != 0 || \
> > + say "Hmm... Maybe tracking ref should be deleted?"
> > + } &&
>
> Ah, you meant that tracking should be deleted so this should be
> fixed in the code but the test is disabled for now. Let's be a
> bit more explicit about such a temporary disabled test, like
> this:
>
> git push origin :refs/heads/b3
>
> # The remote-tracking branch origin/b3 should be deleted;
> # we need to update the code and enable this test.
> : git rev-parse --verify origin/b3 &&
Nice, will take this. Except we have to check for absence of the
tracking branch. git-rev-parse must fail.
t/t5404-tracking-branches.sh | 64 ++++++++++++++++++++++++++++++++++++++++++
1 files changed, 64 insertions(+), 0 deletions(-)
create mode 100755 t/t5404-tracking-branches.sh
diff --git a/t/t5404-tracking-branches.sh b/t/t5404-tracking-branches.sh
new file mode 100755
index 0000000..d861a14
--- /dev/null
+++ b/t/t5404-tracking-branches.sh
@@ -0,0 +1,64 @@
+#!/bin/sh
+
+test_description='tracking branch update checks for git push'
+
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+ echo 1 >file &&
+ git add file &&
+ git commit -m 1 &&
+ git branch b1 &&
+ git branch b2 &&
+ git branch b3 &&
+ git clone . aa &&
+ git checkout b1 &&
+ echo b1 >>file &&
+ git commit -a -m b1 &&
+ git checkout b2 &&
+ echo b2 >>file &&
+ git commit -a -m b2
+'
+
+start_dir="$(pwd)"
+
+test_expect_success 'check tracking branches updated correctly after push' '
+ cd aa &&
+ b1=$(git rev-parse origin/b1) &&
+ b2=$(git rev-parse origin/b2) &&
+ b3=$(git rev-parse origin/b3) &&
+ git checkout -b b1 origin/b1 &&
+ echo aa-b1 >>file &&
+ git commit -a -m aa-b1 &&
+ git checkout -b b2 origin/b2 &&
+ echo aa-b2 >>file &&
+ git commit -a -m aa-b2 &&
+ git checkout master &&
+ echo aa-master >>file &&
+ git commit -a -m aa-master &&
+ {
+ git push
+ test "$(git rev-parse origin/b1)" = "$b1" &&
+ test "$(git rev-parse origin/b2)" = "$b2" &&
+ test "$(git rev-parse origin/b3)" = "$b3" &&
+ test "$(git rev-parse origin/master)" = \
+ "$(git rev-parse master)"
+ }
+'
+
+test_expect_success 'delete remote branch' '
+ git push origin :refs/heads/b3
+ {
+ # The remote-tracking branch origin/b3 should be deleted;
+ # we need to update the code and enable this test.
+ : git rev-parse --verify origin/b3
+ : test $? != 0
+ } &&
+ cd "$start_dir" &&
+ {
+ git rev-parse refs/heads/b3
+ test $? != 0
+ }
+'
+
+test_done
--
1.5.3.5.692.ge1737
^ permalink raw reply related [relevance 3%]
* [PATCH] Add test that checks diverse aspects of updating remote and tracking branches
@ 2007-11-15 20:46 3% ` Alex Riesen
0 siblings, 0 replies; 200+ results
From: Alex Riesen @ 2007-11-15 20:46 UTC (permalink / raw)
To: Jeff King; +Cc: git, Junio C Hamano
Because we haven't settled on what the exit status from
"git push" command itself should be in such a partial
failure case, do not check the exit status from it for
now.
Signed-off-by: Alex Riesen <raa.lkml@gmail.com>
---
Jeff King, Thu, Nov 15, 2007 05:26:26 +0100:
> On Tue, Nov 13, 2007 at 06:10:48PM -0500, Jeff King wrote:
>
> > > This one is on top of what is in next. It also include the check for
> > > deleting remote braches I sent before. Regarding this one: if a remote
> > > branch is deleted, shouldn't the matching tracking branch be removed
> > > as well? The code in master seem to do that.
> >
> > Yes, it should (the code in update_tracking_ref seems to handle that
> > case, but I haven't tested, so I may have bungled something). I am
> > literally walking out the door, now, though, so I will be out of touch
> > for at least a day.
>
> After I became disconnected, I looked at my 'next', and the reason for
> the failure to delete the ref seems to be your is_null_sha1
> error-checking patch, which Junio put in next. But maybe you have
> figured that out in the intervening time. :)
I didn't. But Junio already has all your patches in pu, so I activated
the deletion test and rebased it on top of your patches in his tree
(jk/send-pack, according to merge commit). Tried: works.
t/t5404-tracking-branches.sh | 28 +++++++++++++++++++++++++---
1 files changed, 25 insertions(+), 3 deletions(-)
diff --git a/t/t5404-tracking-branches.sh b/t/t5404-tracking-branches.sh
index 20718d4..a6f60ac 100755
--- a/t/t5404-tracking-branches.sh
+++ b/t/t5404-tracking-branches.sh
@@ -10,6 +10,7 @@ test_expect_success 'setup' '
git commit -m 1 &&
git branch b1 &&
git branch b2 &&
+ git branch b3 &&
git clone . aa &&
git checkout b1 &&
echo b1 >>file &&
@@ -19,10 +20,13 @@ test_expect_success 'setup' '
git commit -a -m b2
'
+start_dir="$(pwd)"
+
test_expect_success 'check tracking branches updated correctly after push' '
cd aa &&
b1=$(git rev-parse origin/b1) &&
b2=$(git rev-parse origin/b2) &&
+ b3=$(git rev-parse origin/b3) &&
git checkout -b b1 origin/b1 &&
echo aa-b1 >>file &&
git commit -a -m aa-b1 &&
@@ -32,9 +36,27 @@ test_expect_success 'check tracking branches updated correctly after push' '
git checkout master &&
echo aa-master >>file &&
git commit -a -m aa-master &&
- git push &&
- test "$(git rev-parse origin/b1)" = "$b1" &&
- test "$(git rev-parse origin/b2)" = "$b2"
+ {
+ git push
+ test "$(git rev-parse origin/b1)" = "$b1" &&
+ test "$(git rev-parse origin/b2)" = "$b2" &&
+ test "$(git rev-parse origin/b3)" = "$b3" &&
+ test "$(git rev-parse origin/master)" = \
+ "$(git rev-parse master)"
+ }
+'
+
+test_expect_success 'delete remote branch' '
+ git push origin :refs/heads/b3
+ {
+ git rev-parse --verify origin/b3
+ test $? != 0
+ } &&
+ cd "$start_dir" &&
+ {
+ git rev-parse refs/heads/b3
+ test $? != 0
+ }
'
test_done
--
1.5.3.5.692.ge1737
^ permalink raw reply related [relevance 3%]
* What's cooking in git.git (topics)
@ 2007-11-17 20:51 1% ` Junio C Hamano
0 siblings, 0 replies; 200+ results
From: Junio C Hamano @ 2007-11-17 20:51 UTC (permalink / raw)
To: git
Here are the topics that have been cooking. Commits prefixed
with '-' are only in 'pu' while commits prefixed with '+' are
in 'next'. The topics list the commits in reverse chronological
order.
----------------------------------------------------------------
[New Topics]
* jc/move-gitk (Sat Nov 17 10:51:16 2007 -0800) 1 commit
- Move gitk to its own subdirectory
----------------------------------------------------------------
[Will cook further in 'next' and then merge to 'master' soon]
* sh/p4 (Thu Nov 15 10:38:45 2007 +0100) 1 commit
+ git-p4: Fix direct import from perforce after fetching changes
through git from origin
* lt/rev-list-interactive (Mon Nov 12 23:16:08 2007 -0800) 5 commits
+ Fix parent rewriting in --early-output
+ revision walker: mini clean-up
+ Enhance --early-output format
+ Add "--early-output" log flag for interactive GUI use
+ Simplify topo-sort logic
* lt/rev-list-gitlink (Sun Nov 11 23:35:23 2007 +0000) 1 commit
+ Fix rev-list when showing objects involving submodules
This fix from Dscho and Linus will need to be cherry-picked to
'maint' as well.
* ds/checkout-upper (Fri Nov 9 20:12:28 2007 +1100) 2 commits
+ git-checkout: Test for relative path use.
+ git-checkout: Support relative paths containing "..".
This will allow you to stay in a subdirectory and check out
paths in directories outside. With Dscho's "git status" that
shows relatives paths (in kh/commit series), this would make
cutting and pasting paths you forgot to "git add" easier.
* ph/parseopt-sh (Mon Nov 12 12:07:40 2007 +0000) 17 commits
+ git-quiltimport.sh fix --patches handling
+ git-am: -i does not take a string parameter.
+ sh-setup: don't let eval output to be shell-expanded.
+ git-sh-setup: fix parseopt `eval` string underquoting
+ Give git-am back the ability to add Signed-off-by lines.
+ git-rev-parse --parseopt
+ scripts: Add placeholders for OPTIONS_SPEC
+ Migrate git-repack.sh to use git-rev-parse --parseopt
+ Migrate git-quiltimport.sh to use git-rev-parse --parseopt
+ Migrate git-checkout.sh to use git-rev-parse --parseopt --keep-
dashdash
+ Migrate git-instaweb.sh to use git-rev-parse --parseopt
+ Migrate git-merge.sh to use git-rev-parse --parseopt
+ Migrate git-am.sh to use git-rev-parse --parseopt
+ Migrate git-clone to use git-rev-parse --parseopt
+ Migrate git-clean.sh to use git-rev-parse --parseopt.
+ Update git-sh-setup(1) to allow transparent use of git-rev-parse -
-parseopt
+ Add a parseopt mode to git-rev-parse to bring parse-options to
shell scripts.
The rate of incoming fix with this topic has slowed down, which
is a good indication that this is getting ready.
* js/mingw-fallouts (Thu Nov 15 12:24:17 2007 -0500) 12 commits
+ rehabilitate some t5302 tests on 32-bit off_t machines
+ Allow ETC_GITCONFIG to be a relative path.
+ Introduce git_etc_gitconfig() that encapsulates access of
ETC_GITCONFIG.
+ Allow a relative builtin template directory.
+ Close files opened by lock_file() before unlinking.
+ builtin run_command: do not exit with -1.
+ Move #include <sys/select.h> and <sys/ioctl.h> to git-compat-
util.h.
+ Use is_absolute_path() in sha1_file.c.
+ Skip t3902-quoted.sh if the file system does not support funny
names.
+ t5302-pack-index: Skip tests of 64-bit offsets if necessary.
+ t7501-commit.sh: Not all seds understand option -i
+ t5300-pack-object.sh: Split the big verify-pack test into smaller
parts.
A set of good general clean-up patches.
* ph/diffopts (Wed Nov 7 11:20:32 2007 +0100) 6 commits
+ Reorder diff_opt_parse options more logically per topics.
+ Make the diff_options bitfields be an unsigned with explicit
masks.
+ Use OPT_BIT in builtin-pack-refs
+ Use OPT_BIT in builtin-for-each-ref
+ Use OPT_SET_INT and OPT_BIT in builtin-branch
+ parse-options new features.
Further code clean-ups.
* cc/bisect (Sat Nov 17 14:35:25 2007 +0100) 5 commits
+ Bisect visualize: use "for-each-ref" to list all good refs.
+ git-bisect: modernize branch shuffling hack
+ git-bisect: use update-ref to mark good/bad commits
+ git-bisect: war on "sed"
+ Bisect reset: remove bisect refs that may have been packed.
----------------------------------------------------------------
[Actively cooking]
* jk/send-pack (Sat Nov 17 07:56:03 2007 -0500) 24 commits
+ send-pack: assign remote errors to each ref
+ send-pack: check ref->status before updating tracking refs
+ send-pack: track errors for each ref
+ Merge branch 'aw/mirror-push' into jk/send-pack
+ Merge branch 'ar/send-pack-remote-track' into jk/send-pack
+ Merge branch 'db/remote-builtin' into jk/send-pack
+ git-push: add documentation for the newly added --mirror mode
+ Add tests for git push'es mirror mode
+ Update the tracking references only if they were succesfully
updated on remote
+ Add a test checking if send-pack updated local tracking branches
correctly
+ git-push: plumb in --mirror mode
+ Teach send-pack a mirror mode
+ Merge master into aw/mirror-push
+ Merge branch 'jk/terse-push' into aw/mirror-push
+ send-pack: segfault fix on forced push
+ Reteach builtin-ls-remote to understand remotes
+ send-pack: require --verbose to show update of tracking refs
+ receive-pack: don't mention successful updates
+ more terse push output
+ Build in ls-remote
+ Build-in send-pack, with an API for other programs to call.
+ Use built-in send-pack.
+ Build-in peek-remote, using transport infrastructure.
+ Miscellaneous const changes and utilities
Looking good.
* jc/spht (Fri Nov 2 17:46:55 2007 -0700) 3 commits
+ core.whitespace: add test for diff whitespace error highlighting
+ git-diff: complain about >=8 consecutive spaces in initial indent
+ War on whitespace: first, a bit of retreat.
Teaching "git apply --whitespace=[warn|strip]" to honor the same
configuration would be a good addition, but this could go to
'master' as is.
* js/reflog-delete (Wed Oct 17 02:50:45 2007 +0100) 1 commit
+ Teach "git reflog" a subcommand to delete single entries
* tt/help (Sun Nov 11 19:57:57 2007 -0500) 2 commits
+ Remove hint to use "git help -a"
+ Make the list of common commands more exclusive
Some people on the list may find the exact list of commands
somewhat debatable. We can fine-tune that in-tree ('pu' does
not count as "in-tree").
----------------------------------------------------------------
[Approaching 'next']
* kh/commit (Sat Nov 17 00:46:33 2007 -0800) 16 commits
- PARK: cruft next-index clean-up
- Replace "runstatus" with "status" in the tests
- t7501-commit: Add test for git commit <file> with dirty index.
- builtin-commit: Clean up an unused variable and a debug fprintf().
- Call refresh_cache() when updating the user index for --only
commits.
- builtin-commit: Add newline when showing which commit was created
- builtin-commit: resurrect behavior for multiple -m options
- builtin-commit --s: add a newline if the last line was not a S-o-b
- builtin-commit: fix --signoff
- git status: show relative paths when run in a subdirectory
- builtin-commit: Refresh cache after adding files.
- builtin-commit: fix reflog message generation
- launch_editor(): read the file, even when EDITOR=:
- Port git commit to C.
- Export launch_editor() and make it accept ':' as a no-op editor.
- Add testcase for amending and fixing author in git commit.
Dscho fixed a few obvious glitches, but indicated he has a
handful more issues with the series. Partial commit is
seriously broken.
* sp/refspec-match (Sun Nov 11 15:01:48 2007 +0100) 4 commits
- refactor fetch's ref matching to use refname_match()
- push: use same rules as git-rev-parse to resolve refspecs
- add refname_match()
- push: support pushing HEAD to real branch name
This changes the semantics slightly but I think it is a move in
the right direction.
* sb/clean (Wed Nov 14 23:00:54 2007 -0600) 3 commits
- Teach git clean to use setup_standard_excludes()
- git-clean: Fix error message if clean.requireForce is not set.
- Make git-clean a builtin
It has a subtle change in behaviour but it does not quite
qualify as a regression. Will merge to "next" shortly. We can
fix the corner case semantics in-tree. I also adjusted the
error message to match the fix from Hannes on 'master'.
----------------------------------------------------------------
[Stalled]
* mh/rebase-skip-hard (Thu Nov 8 08:03:06 2007 +0100) 1 commit
- Do git reset --hard HEAD when using git rebase --skip
Some people on the list may find this debatable. Opinions?
* cr/tag-options (Fri Nov 9 14:42:56 2007 +0100) 1 commit
- Make builtin-tag.c use parse_options.
This changes the handling of multiple -m options without much
good reason. It should be a simple fix, once we know what we
want. I think the existing behaviour of refusing multiple -m
is probably the most sane at this point.
* dz/color-addi (Sat Nov 10 18:03:44 2007 -0600) 3 commits
- Added diff hunk coloring to git-add--interactive
- Let git-add--interactive read colors from .gitconfig
- Added basic color support to git add --interactive
This series has improved quite a bit since the last round, but
another round was requested from the list. Waiting for
refinements.
* nd/maint-work-tree-fix (Sat Nov 3 20:18:06 2007 +0700) 1 commit
+ Add missing inside_work_tree setting in setup_git_directory_gently
There was an additional patch, which still had issues Dscho
pointed out. Waiting for refinements.
* ss/dirty-rebase (Thu Nov 1 22:30:24 2007 +0100) 3 commits
- Make git-svn rebase --dirty pass along --dirty to git-rebase.
- Implement --dirty for git-rebase--interactive.
- Introduce --dirty option to git-rebase, allowing you to start from
a dirty state.
This seems to be optimized for the --dirty case too much. I'd
prefer an implementation that make rebases without --dirty to
pay no penalty (if that is possible, otherwise "as little as
possible").
----------------------------------------------------------------
[Others]
* jc/branch-contains (Wed Nov 7 14:58:09 2007 -0800) 1 commit
- git-branch --with=commit
I did this just for my own fun. --contains might be more
consistent with git-describe but --with is shorter to type ;-)
Besides, it needs documentation and tests.
* jc/maint-format-patch-encoding (Fri Nov 2 17:55:31 2007 -0700) 2 commits
- test format-patch -s: make sure MIME content type is shown as
needed
- format-patch -s: add MIME encoding header if signer's name
requires so
This is to apply to 'maint' later; the equivalent fix is already
in 'master'.
* lt/maint-rev-list-gitlink (Sun Nov 11 23:35:23 2007 +0000) 1 commit
- Fix rev-list when showing objects involving submodules
This is to apply to 'maint' later; the equivalent fix is already
in 'next' and will be merged to 'master' soon.
* jc/pathspec (Thu Sep 13 13:38:19 2007 -0700) 3 commits
- pathspec_can_match(): move it from builtin-ls-tree.c to tree.c
- ls-tree.c: refactor show_recursive() and rename it.
- tree-diff.c: split out a function to match a single pattern.
* jk/rename (Tue Oct 30 00:24:42 2007 -0400) 3 commits
- handle renames using similarity engine
- introduce generic similarity library
- change hash table calling conventions
* jc/cherry-pick (Tue Nov 13 12:38:51 2007 -0800) 1 commit
- revert/cherry-pick: start refactoring call to merge_recursive
* jc/nu (Sun Oct 14 22:07:34 2007 -0700) 3 commits
- merge-nu: a new merge backend without using unpack_trees()
- read_tree: take an explicit index structure
- gcc 4.2.1 -Werror -Wall -ansi -pedantic -std=c99: minimum fix
^ permalink raw reply [relevance 1%]
* Re: Adding Git to Better SCM Initiative : Comparison
@ 2007-11-29 1:48 3% ` Robin Rosenberg
0 siblings, 0 replies; 200+ results
From: Robin Rosenberg @ 2007-11-29 1:48 UTC (permalink / raw)
To: Jakub Narebski; +Cc: git
onsdag 28 november 2007 skrev Jakub Narebski:
> I'd like to add Git to comparison table of SCMs at Better SCM
> Initiative site:
> http://better-scm.berlios.de
>
> To do that, I need to fill in infomration about Git. Most
> of questions / items didn't give much problem, but there
> are a few on which I would like your input.
>
> (Yes, I know that such SCM comparisons are usually biased towards the
> idea of what are most important features of a version control system.
> Nevertheless...)
[...]
> 4. Repository Permissions
>
> Is it possible to define permissions on access to different
> parts of a remote repository? Or is access open for all?
>
> "Partial (?). It is possible to lock down repository
> (access to branches and tags) using hooks."
>
> I don't know if it is possible to do finer level ACLs, i.e. if it
> is possible to lock subdirectories or files in Git. Although for
> distributed SCMs ACL doesn't matter much: check diffstat and merge or
> not from trusted people. We have "network of trust" (BTW. Karl Fogel
> in OSSBook recommends 'soft' control of access control to repository,
> on social rather than on technical level).
I think what is most interesting here is access to content for which git has
just about nothing worth mentioning, Just admit it. "Truth in advertising".
I did start doing this so here's my version (pre-msysgit). Please try to bring up the defintion
of "atomic" again with the author. I did complain a little but nothing happened. The issue is
that Clearcase is listed as having "atomic" commits which is not true for any usable definition
of atomic in SCM context. With the definition in use there I think CVS should be considered
having atomic commits too, at least I've never seen a half-committed file there.
% svn diff
Index: src/comparison/scm-comparison.xml
===================================================================
--- src/comparison/scm-comparison.xml (revision 290)
+++ src/comparison/scm-comparison.xml (arbetskopia)
@@ -71,6 +71,9 @@
<impl id="ls-sync">
<name>LibreSource Synchronizer</name>
</impl>
+ <impl id="git">
+ <name>Git</name>
+ </impl>
</implementations>
<timestamp>
$Id$
@@ -182,6 +185,13 @@
needs to be up-to-date before doing a rename/move operation.
This operation will be committed directly.
</s>
+ <s id="git">
+ Yes (or no depending on interpretation). Git typically detects
+ renames and copies based on content regardless of whether the
+ committer indicated the fact. The detection is content based
+ rather than file-id based. There is explicit rename too, but
+ it is not used much.
+ </s>
</compare>
</section>
<section id="copy">
@@ -236,6 +246,10 @@
limitations in Windows environments)
</s>
<s id="ls-sync">No, copies will start there own history.</s>
+ <s id="git">Yes(or no depending on interpretation). Git detects
+ copies and moves based on content. It does not track
+ history on a file-id based scheme.
+ </s>
</compare>
</section>
<section id="repos_clone">
@@ -288,6 +302,11 @@
Yes, but is not documented and its based on the dataflow feature of the
LibreSource Synchronizer.
</s>
+ <s id="git">
+ Yes. This is a fundamental part of using Git. A Git user typically always
+ has a full copy of the entire repostory (well compressed) that is initialized
+ using a clone command.
+ </s>
</compare>
</section>
<section id="push">
@@ -331,6 +350,7 @@
<s id="cmsynergy">Yes, as long as you have the (more expensive) Distributed package.</s>
<s id="clearcase">Yes, using Clearcase Multisite.</s>
<s id="ls-sync">Yes, it's what we call a dataflow.</s>
+ <s id="git">Yes. This is a fundamental part of using Git.</s>
</compare>
</section>
<section id="permissions">
@@ -417,7 +437,8 @@
multi-platform environments.
</s>
<s id="ls-sync">Permissions are set for the whole repository or branch.</s>
- </compare>
+ <s id="git">No, but bad changes can be reverted before they are published.</s>
+ </compare>
</section>
<section id="changesets">
<title>Changesets' Support</title>
@@ -490,6 +511,11 @@
Partial support. There are implicit changeset that are generated on
each commit.
</s>
+ <s id="git">Yes. Actually Git is snapshot based which means Git records
+ the full state in every commit, which means that any two
+ commits can be compared directly very quickly, although the
+ repository is typically browsed as a series of change sets.
+ </s>
</compare>
</section>
<section id="annotate">
@@ -534,6 +560,9 @@
Yes locally without any server connection with the standard graphical
Java client.
</s>
+ <s id="git">Yes. It can also detect the origin of copied and moved source
+ lines.
+ </s>
</compare>
</section>
</section>
@@ -610,6 +639,12 @@
It is possible to commit only a certain directory. However, one must
check out the entire repository as a whole.
</s>
+ <s id="git">No. However it is possible to commit only selected
+ changes in the working tree rather than everything. Subproject
+ support makes it possible to split large projects into several
+ repositories and link them. Related repositories need not be
+ checked out or cloned.
+ </s>
</compare>
</section>
<section id="tracking_uncommited_changes">
@@ -659,6 +694,10 @@
Yes, with the Synchronizer Studio (default Java client) or with the
standard diff command (diff -r . .so6/xxx/REFCOPY/)
</s>
+ <s id="git">Yes. In addition commits are local and will not be seen
+ until he/she decides to publish them making it possible to
+ track multiple versions locally before publishing.
+ </s>
</compare>
</section>
<section id="per_file_commit_messages">
@@ -714,6 +753,7 @@
for a per-changeset message.
</s>
<s id="ls-sync">No. Commit messages are per changeset.</s>
+ <s id="git">No. The same message applies the the commit as a whole.</s>
</compare>
</section>
</section>
@@ -828,6 +868,11 @@
documentation. Installing and getting started with the GUI is very easy
though. (update/commit-next-next-next-finished)
</s>
+ <s id="git">
+ There a good tutorials manual pages and a supportive community.
+ Basic usage is simple, but advanced usage requires understanding of
+ what makes git different.
+ </s>
</compare>
</section>
<section id="ease_of_deployment">
@@ -950,6 +995,10 @@
LibreSource repository web page.
(links: create workspace, update, commit, studio...)
</s>
+ <s id="git">
+ Very simple to deploy on Unix-like systems. Windows installs
+ is not fully developed yet. Installing in cygwin is simple though.
+ </s>
</compare>
</section>
<section id="command_set">
@@ -1048,6 +1097,13 @@
Basic commands available (commit/update), but it's really simple to
use the GUI. Ant task are also available.
</s>
+ <s id="git">Basic usage could be considered similar, but trying
+ to use Git like CVS would be counterproductive since many
+ cases of CVS usage is by design not possible in Git. The
+ number of command is large. ~140 but only ~20 commands
+ are typically used and less than ten will do for casual
+ users.
+ </s>
</compare>
</section>
<section id="networking">
@@ -1152,6 +1208,13 @@
<s id="ls-sync">
Good. Use of HTTP to get through firwalls.
</s>
+ <s id="git">
+ Excellent. Normal usage is off-line, but networking is
+ used for sharing changes Networking including ssh,
+ a special git protocol http and mail can be used to share
+ changes, both incoming and outgoing. Mail can be used
+ via IMAP and mbox files.
+ </s>
</compare>
</section>
<section id="portability">
@@ -1249,6 +1312,11 @@
Excellent. Clients and servers work on any Java 1.5-compatible
platform. (Windows, Linux and Mac OS X )
</s>
+ <s id="git">
+ Very good for POSIX compatible environments. A non-cygwin
+ port for windows is underway. There are some graphical
+ tools available for windows in cygwin.
+ </s>
</compare>
</section>
</section>
@@ -1323,6 +1391,7 @@
Yes, without diff features but with a better awareness support.
(allow to know at any time on each version each one is working on)
</s>
+ <s id="git">Yes. gitweb</s>
</compare>
</section>
<section id="availability_of_guis">
@@ -1421,6 +1490,10 @@
is automatically launched from the repository web page and
another one which is an Eclipse plugin.
</s>
+ <s id="git">
+ A number of good GUI's are availble for basic usage,
+ but typical usage is command based.
+ </s>
</compare>
</section>
</section>
@@ -1501,7 +1574,8 @@
additional licensing.
</s>
<s id="ls-sync">QPL - The Qt Public License (OpenSource)</s>
- </compare>
+ <s id="git">GPL</s>
+ </compare>
</section>
</section>
</contents>
-- robin
^ permalink raw reply [relevance 3%]
* Building git-1.5.3.7 on HP-UX 11.00
@ 2007-12-04 13:09 2% H.Merijn Brand
0 siblings, 0 replies; 200+ results
From: H.Merijn Brand @ 2007-12-04 13:09 UTC (permalink / raw)
To: git; +Cc: Sam Vilain
1. It won't compile at all with HP C-ANSI-C, so I have to use gcc-3.4.6
I added this to Makefile to get it compiled
ifeq ($(uname_S),HP-UX)
# HP-UX
BASIC_LDFLAGS += -L/usr/local/ssl/lib -L/usr/local/lib
EXTLIBS += -ldce
NO_HSTRERROR = YesPlease
NO_ICONV = YesPlease
NO_INET_NTOP = YesPlease
NO_INET_PTON = YesPlease
endif
make test then fails:
/pro/3gl/LINUX/git-1.5.3.7 178 > make test
LINK git-convert-objects
LINK git
BUILTIN git-format-patch
BUILTIN git-show
BUILTIN git-whatchanged
BUILTIN git-cherry
BUILTIN git-get-tar-commit-id
BUILTIN git-init
BUILTIN git-repo-config
BUILTIN git-fsck-objects
BUILTIN git-cherry-pick
BUILTIN git-add
BUILTIN git-annotate
BUILTIN git-apply
BUILTIN git-archive
BUILTIN git-blame
BUILTIN git-branch
BUILTIN git-bundle
BUILTIN git-cat-file
BUILTIN git-check-attr
BUILTIN git-checkout-index
BUILTIN git-check-ref-format
BUILTIN git-commit-tree
BUILTIN git-count-objects
BUILTIN git-describe
BUILTIN git-diff
BUILTIN git-diff-files
BUILTIN git-diff-index
BUILTIN git-diff-tree
BUILTIN git-fetch--tool
BUILTIN git-fmt-merge-msg
BUILTIN git-for-each-ref
BUILTIN git-fsck
BUILTIN git-gc
BUILTIN git-grep
BUILTIN git-init-db
BUILTIN git-log
BUILTIN git-ls-files
BUILTIN git-ls-tree
BUILTIN git-mailinfo
BUILTIN git-mailsplit
BUILTIN git-merge-base
BUILTIN git-merge-file
BUILTIN git-mv
BUILTIN git-name-rev
BUILTIN git-pack-objects
BUILTIN git-prune
BUILTIN git-prune-packed
BUILTIN git-push
BUILTIN git-read-tree
BUILTIN git-reflog
BUILTIN git-config
BUILTIN git-rerere
BUILTIN git-rev-list
BUILTIN git-rev-parse
BUILTIN git-revert
BUILTIN git-rm
BUILTIN git-runstatus
BUILTIN git-shortlog
BUILTIN git-show-branch
BUILTIN git-stripspace
BUILTIN git-symbolic-ref
BUILTIN git-tag
BUILTIN git-tar-tree
BUILTIN git-unpack-objects
BUILTIN git-update-index
BUILTIN git-update-ref
BUILTIN git-upload-archive
BUILTIN git-verify-pack
BUILTIN git-verify-tag
BUILTIN git-write-tree
BUILTIN git-show-ref
BUILTIN git-pack-refs
SUBDIR git-gui
INDEX lib/
SUBDIR perl
SUBDIR templates
make -C t/ all
make[1]: Entering directory `/pro/3gl/LINUX/git-1.5.3.7/t'
*** t0000-basic.sh ***
* ok 1: .git/objects should be empty after git init in an empty repo.
* ok 2: .git/objects should have 3 subdirectories.
* ok 3: git update-index without --add should fail adding.
* ok 4: git update-index with --add should succeed.
* ok 5: writing tree out with git write-tree
* ok 6: validate object ID of a known tree.
* ok 7: git update-index without --remove should fail removing.
* ok 8: git update-index with --remove should be able to remove.
* ok 9: git write-tree should be able to write an empty tree.
* ok 10: validate object ID of a known tree.
* ok 11: adding various types of objects with git update-index --add.
* ok 12: showing stage with git ls-files --stage
* ok 13: validate git ls-files output for a known tree.
* ok 14: writing tree out with git write-tree.
* ok 15: validate object ID for a known tree.
* ok 16: showing tree with git ls-tree
* ok 17: git ls-tree output for a known tree.
* ok 18: showing tree with git ls-tree -r
* ok 19: git ls-tree -r output for a known tree.
* ok 20: showing tree with git ls-tree -r -t
* ok 21: git ls-tree -r output for a known tree.
* ok 22: writing partial tree out with git write-tree --prefix.
* ok 23: validate object ID for a known tree.
* ok 24: writing partial tree out with git write-tree --prefix.
* ok 25: validate object ID for a known tree.
* ok 26: put invalid objects into the index.
* ok 27: writing this tree without --missing-ok.
* ok 28: writing this tree with --missing-ok.
* ok 29: git read-tree followed by write-tree should be idempotent.
* ok 30: validate git diff-files output for a know cache/work tree state.
* ok 31: git update-index --refresh should succeed.
* ok 32: no diff after checkout and git update-index --refresh.
* ok 33: git commit-tree records the correct tree in a commit.
* ok 34: git commit-tree records the correct parent in a commit.
* ok 35: git commit-tree omits duplicated parent in a commit.
* ok 36: update-index D/F conflict
* ok 37: absolute path works as expected
* passed all 37 test(s)
*** t0001-init.sh ***
* FAIL 1: plain
(
unset GIT_DIR GIT_WORK_TREE &&
mkdir plain &&
cd plain &&
git init
) &&
check_config plain/.git false unset
* ok 2: plain with GIT_WORK_TREE
* FAIL 3: plain bare
(
unset GIT_DIR GIT_WORK_TREE GIT_CONFIG &&
mkdir plain-bare-1 &&
cd plain-bare-1 &&
git --bare init
) &&
check_config plain-bare-1 true unset
* ok 4: plain bare with GIT_WORK_TREE
* ok 5: GIT_DIR bare
* ok 6: GIT_DIR non-bare
* ok 7: GIT_DIR & GIT_WORK_TREE (1)
* ok 8: GIT_DIR & GIT_WORK_TREE (2)
* failed 2 among 8 test(s)
make[1]: *** [t0001-init.sh] Error 1
make[1]: Leaving directory `/pro/3gl/LINUX/git-1.5.3.7/t'
make: *** [test] Error 2
Exit 2
and make install probably expects a broken^Wdifferent install than HP-UX has:
/pro/3gl/LINUX/git-1.5.3.7 181 > make install
SUBDIR git-gui
INDEX lib/
SUBDIR perl
SUBDIR templates
install -d -m755 '/pro/local/bin'
rm: /pro/local/bin/ directory
Usage: mv [-f] [-i] [-e warn|force|ignore] f1 f2
mv [-f] [-i] [-e warn|force|ignore] f1 ... fn d1
mv [-f] [-i] [-e warn|force|ignore] d1 d2
install -d -m755 '/pro/local/bin'
rm: /pro/local/bin/ directory
Usage: mv [-f] [-i] [-e warn|force|ignore] f1 f2
mv [-f] [-i] [-e warn|force|ignore] f1 ... fn d1
mv [-f] [-i] [-e warn|force|ignore] d1 d2
install git-convert-objects git-fetch-pack git-hash-object git-index-pack git-local-fetch git-fast-import git-daemon git-merge-index git-mktag git-mktree git-patch-id git-peek-remote git-receive-pack git-send-pack git-shell git-show-index git-ssh-fetch git-ssh-upload git-unpack-file git-update-server-info git-upload-pack git-pack-redundant git-var git-merge-tree git-imap-send git-merge-recursive git-ssh-pull git-ssh-push git-bisect git-checkout git-clean git-clone git-commit git-fetch git-ls-remote git-merge-one-file git-mergetool git-parse-remote git-pull git-rebase git-rebase--interactive git-repack git-request-pull git-reset git-sh-setup git-am git-merge git-merge-stupid git-merge-octopus git-merge-resolve git-merge-ours git-lost-found git-quiltimport git-submodule git-filter-branch gi
t-stash git-add--interactive git-archimport git-cvsimport git-relink git-cvsserver git-remote git-svnimport git-cvsexportcommit git-send-email git-svn git-status git-instaweb git-merge-subt!
ree '/pro/local/bin'
install git '/pro/local/bin'
make -C templates DESTDIR='' install
make[1]: Entering directory `/pro/3gl/LINUX/git-1.5.3.7/templates'
install -d -m755 '/pro/local/share/git-core/templates/'
Usage: mv [-f] [-i] [-e warn|force|ignore] f1 f2
mv [-f] [-i] [-e warn|force|ignore] f1 ... fn d1
mv [-f] [-i] [-e warn|force|ignore] d1 d2
(cd blt && tar cf - .) | \
(cd '/pro/local/share/git-core/templates/' && tar xf -)
/bin/sh: /pro/local/share/git-core/templates/: not found.
make[1]: *** [install] Error 1
make[1]: Leaving directory `/pro/3gl/LINUX/git-1.5.3.7/templates'
make: *** [install] Error 2
Exit 2
I have two:
14241 100555 -r-x 1 bin 1888 12 Jun 2002 10:58 /opt/imake/bin/install
634 100555 -r-x 1 bin 5147 7 Nov 1997 09:00 /usr/sbin/install
--
H.Merijn Brand Amsterdam Perl Mongers (http://amsterdam.pm.org/)
using & porting perl 5.6.2, 5.8.x, 5.10.x on HP-UX 10.20, 11.00, 11.11,
& 11.23, SuSE 10.1 & 10.2, AIX 5.2, and Cygwin. http://qa.perl.org
http://mirrors.develooper.com/hpux/ http://www.test-smoke.org
http://www.goldmark.org/jeff/stupid-disclaimers/
^ permalink raw reply [relevance 2%]
* Git and securing a repository
@ 2008-01-02 7:13 3% Gonzalo Garramuño
2008-01-02 6:34 2% ` Felipe Balbi
2008-01-02 16:18 1% ` Daniel Barkalow
0 siblings, 2 replies; 200+ results
From: Gonzalo Garramuño @ 2008-01-02 7:13 UTC (permalink / raw)
To: git
I've been using git for some time and love it. For open source projects
there's clearly nothing currently better.
However, I am now using git for proprietary elements, which in the
future I may need or want to partially restrict access to. The idea
being that at my company some (junior) developers should not be given
access to some elements. That means either that some full git
repository should be password protected or even portions of the same
repository.
Another desirable way to protect elements might be only giving
clone/pull access to a repository (or portion of it) but not permissions
to push in changes.
I have not seen or read much about how git deals with accesses and
permissions. Can anyone point me to some documentation if some or all
of this is possible?
--
Gonzalo Garramuño
ggarra@advancedsl.com.ar
AMD4400 - ASUS48N-E
GeForce7300GT
Xubuntu Gutsy
^ permalink raw reply [relevance 3%]
* Re: Git and securing a repository
2008-01-02 7:13 3% Git and securing a repository Gonzalo Garramuño
@ 2008-01-02 6:34 2% ` Felipe Balbi
2008-01-02 16:18 1% ` Daniel Barkalow
1 sibling, 0 replies; 200+ results
From: Felipe Balbi @ 2008-01-02 6:34 UTC (permalink / raw)
To: Gonzalo Garramuño; +Cc: git
On Jan 2, 2008 2:13 AM, Gonzalo Garramuño <ggarra@advancedsl.com.ar> wrote:
>
> I've been using git for some time and love it. For open source projects
> there's clearly nothing currently better.
>
> However, I am now using git for proprietary elements, which in the
> future I may need or want to partially restrict access to. The idea
> being that at my company some (junior) developers should not be given
> access to some elements. That means either that some full git
> repository should be password protected or even portions of the same
> repository.
>
> Another desirable way to protect elements might be only giving
> clone/pull access to a repository (or portion of it) but not permissions
> to push in changes.
push access is only available through ssh, so if your developer
doesn't have a ssh account on the server, he can't push code to it
>
> I have not seen or read much about how git deals with accesses and
> permissions. Can anyone point me to some documentation if some or all
> of this is possible?
it's easy on the full repository case, create different groups and
share git repositories by groups, after that chmod o-rwx -R
/path/to/repository.git.
If a user is not the owner nor is part of that group in particular, it
wouldn't be able to push any code to the repository.
btw, if you don't start git-daemon you could use ssh to pull code as well.
thinking on the partial repository access, maybe git submodule would
help, but i've never used it.
--
Best Regards,
Felipe Balbi
felipebalbi@users.sourceforge.net
^ permalink raw reply [relevance 2%]
* Re: Git and securing a repository
2008-01-02 7:13 3% Git and securing a repository Gonzalo Garramuño
2008-01-02 6:34 2% ` Felipe Balbi
@ 2008-01-02 16:18 1% ` Daniel Barkalow
1 sibling, 0 replies; 200+ results
From: Daniel Barkalow @ 2008-01-02 16:18 UTC (permalink / raw)
To: Gonzalo Garramuño; +Cc: git
[-- Attachment #1: Type: TEXT/PLAIN, Size: 2124 bytes --]
On Wed, 2 Jan 2008, Gonzalo Garramuño wrote:
> I've been using git for some time and love it. For open source projects
> there's clearly nothing currently better.
>
> However, I am now using git for proprietary elements, which in the future I
> may need or want to partially restrict access to. The idea being that at my
> company some (junior) developers should not be given access to some elements.
> That means either that some full git repository should be password protected
> or even portions of the same repository.
>
> Another desirable way to protect elements might be only giving clone/pull
> access to a repository (or portion of it) but not permissions to push in
> changes.
In order to understand the security model, you have to remember that git
is designed as a distributed system. Authorization is fundamentally not at
a project level, but rather at a repository level, and clones are all
different repositories. This makes portability of the mechanism less
important, because a particular set of authorization rules only applies to
a particular repository, which is going to be on some single system.
For that matter, git doesn't run with any special privileges in general;
if a user can affect the repository with git operations, that user can
affect the repository by hand, so git-specific rules aren't helpful.
(Although I suppose it would be theoretically useful to make git-shell,
the shell that only runs git programs, able to apply restrictions, since
it is used in a context where the user doesn't have any other access to
the filesystem.)
For read access restrictions, you want to use submodules (or entirely
separate projects); git is fundamentally unhappy running with less than
all of the project accessible, except for when a project references
another project with submodules. And, of course, if the code base is such
that users can do useful work without any access to some of the files,
those files must be optional and somewhat separate from the necessary
portions, and it makes sense to handle them separately anyway.
-Daniel
*This .sig left intentionally blank*
^ permalink raw reply [relevance 1%]
* Re: valgrind test script integration
@ 2008-01-12 11:36 2% ` Jeff King
0 siblings, 0 replies; 200+ results
From: Jeff King @ 2008-01-12 11:36 UTC (permalink / raw)
To: git
On Sat, Jan 12, 2008 at 06:10:44AM -0500, Jeff King wrote:
> - We only catch calls to 'git', not 'git-foo' (and in fact for that
> reason this doesn't catch the t7300 bug by itself, since that uses
> git-clean). A follow-on patch will deal with this.
And here it is.
This replaces all usage of "git-foo" with "git foo" in the
test scripts. The replacement was done semi-manually; a
fully automatic replacement won't work because the pattern
"git-" appears in several other contexts (e.g.,
"--git-dir=", ref names, filenames, etc).
Obviously another route would be intercepting git-* calls,
as well, but my impression is that we are ultimately heading
towards a "git foo is the right way" situation, in which
case this cleanup is eventually necessary anyway.
[the original got eaten by the list since the patch is almost 150K;
the diffstat is below, and I am making the patch available at
git://repo.or.cz/git/peff.git master
]
t/t1400-update-ref.sh | 10 +-
t/t2005-checkout-index-symlinks.sh | 4 +-
t/t2050-git-dir-relative.sh | 4 +-
t/t2102-update-index-symlinks.sh | 2 +-
t/t2200-add-update.sh | 12 +-
t/t3020-ls-files-error-unmatch.sh | 2 +-
t/t3030-merge-recursive.sh | 14 +-
t/t3200-branch.sh | 16 +-
t/t3210-pack-refs.sh | 4 +-
t/t3400-rebase.sh | 6 +-
t/t3401-rebase-partial.sh | 20 +-
t/t3500-cherry.sh | 12 +-
t/t3600-rm.sh | 4 +-
t/t3800-mktag.sh | 8 +-
t/t3900-i18n-commit.sh | 6 +-
t/t3901-i18n-patch.sh | 16 +-
t/t4012-diff-binary.sh | 2 +-
t/t4103-apply-binary.sh | 26 ++--
t/t5300-pack-object.sh | 14 +-
t/t5301-sliding-window.sh | 4 +-
t/t5302-pack-index.sh | 10 +-
t/t5400-send-pack.sh | 30 ++--
t/t5401-update-hooks.sh | 4 +-
t/t5402-post-merge-hook.sh | 4 +-
t/t5403-post-checkout-hook.sh | 4 +-
t/t5500-fetch-pack.sh | 4 +-
t/t5510-fetch.sh | 2 +-
t/t5530-upload-pack-error.sh | 4 +-
t/t5600-clone-fail-cleanup.sh | 6 +-
t/t6006-rev-list-format.sh | 6 +-
t/t6025-merge-symlinks.sh | 32 ++--
t/t6026-merge-attr.sh | 12 +-
t/t6030-bisect-porcelain.sh | 2 +-
t/t6120-describe.sh | 30 ++--
t/t6300-for-each-ref.sh | 28 ++--
t/t7001-mv.sh | 12 +-
t/t7003-filter-branch.sh | 18 +-
t/t7004-tag.sh | 316 ++++++++++++++++----------------
t/t7101-reset.sh | 6 +-
t/t7300-clean.sh | 38 ++--
t/t7400-submodule-basic.sh | 46 +++---
t/t7501-commit.sh | 44 +++---
t/t9100-git-svn-basic.sh | 44 +++---
t/t9101-git-svn-props.sh | 62 +++---
t/t9102-git-svn-deep-rmdir.sh | 6 +-
t/t9104-git-svn-follow-parent.sh | 36 ++--
t/t9105-git-svn-commit-diff.sh | 8 +-
t/t9106-git-svn-commit-diff-clobber.sh | 12 +-
t/t9107-git-svn-migrate.sh | 16 +-
t/t9108-git-svn-glob.sh | 4 +-
t/t9110-git-svn-use-svm-props.sh | 8 +-
t/t9111-git-svn-use-svnsync-props.sh | 8 +-
t/t9112-git-svn-md5less-file.sh | 4 +-
t/t9116-git-svn-log.sh | 4 +-
t/t9119-git-svn-info.sh | 120 ++++++------
t/t9200-git-cvsexportcommit.sh | 10 +-
t/t9300-fast-import.sh | 64 ++++----
t/t9400-git-cvsserver-server.sh | 30 ++--
58 files changed, 640 insertions(+), 640 deletions(-)
^ permalink raw reply [relevance 2%]
* Git Gui: initial french translation: fr.po
@ 2008-01-15 5:24 1% Christian Couder
0 siblings, 0 replies; 200+ results
From: Christian Couder @ 2008-01-15 5:24 UTC (permalink / raw)
To: Shawn O. Pearce, Junio Hamano; +Cc: git
[-- Attachment #1: Type: text/plain, Size: 609 bytes --]
Here are some of the choices made to translate Git Gui to french:
- commit -> "commit" (noun) or "commiter" (verb)
- stage (index) -> "pré-commit" (noun) or "pré-commiter" (verb)
- (re)scan -> "(re)synchroniser"
- reset -> "réinitialiser"
- checkout -> "emprunt" (noun) or "emprunter" (verb)
- revision expression -> "expression de révison"
I am not completely happy with these, but it's a start...
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
I just attached the file instead of sending the patch because I fear
some encoding breakages.
[-- Attachment #2: fr.po --]
[-- Type: application/octet-stream, Size: 47936 bytes --]
# translation of fr.po to French
# Translation of git-gui to French.
# Copyright (C) 2008 Shawn Pearce, et al.
# This file is distributed under the same license as the git package.
#
# Christian Couder <chriscool@tuxfamily.org>, 2008.
msgid ""
msgstr ""
"Project-Id-Version: fr\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2007-11-24 10:36+0100\n"
"PO-Revision-Date: 2008-01-14 21:08+0100\n"
"Last-Translator: Christian Couder <chriscool@tuxfamily.org>\n"
"Language-Team: French\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: KBabel 1.11.4\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
#: git-gui.sh:41 git-gui.sh:604 git-gui.sh:618 git-gui.sh:631 git-gui.sh:714
#: git-gui.sh:733
msgid "git-gui: fatal error"
msgstr "git-gui: erreur fatale"
#: git-gui.sh:565
#, tcl-format
msgid "Invalid font specified in %s:"
msgstr "Invalide fonte spécifiée dans %s :"
#: git-gui.sh:590
msgid "Main Font"
msgstr "Fonte principale"
#: git-gui.sh:591
msgid "Diff/Console Font"
msgstr "Fonte diff/console"
#: git-gui.sh:605
msgid "Cannot find git in PATH."
msgstr "Impossible de trouver git dans PATH."
#: git-gui.sh:632
msgid "Cannot parse Git version string:"
msgstr "Impossible de parser la version de Git :"
#: git-gui.sh:650
#, tcl-format
msgid ""
"Git version cannot be determined.\n"
"\n"
"%s claims it is version '%s'.\n"
"\n"
"%s requires at least Git 1.5.0 or later.\n"
"\n"
"Assume '%s' is version 1.5.0?\n"
msgstr ""
"Impossible de déterminer la version de Git.\n"
"\n"
"%s affirme qu'il s'agit de la version '%s'.\n"
"\n"
"%s nécessite au moins Git 1.5.0.\n"
"\n"
"Peut'on considérer que '%s' est en version 1.5.0 ?\n"
#: git-gui.sh:888
msgid "Git directory not found:"
msgstr "Impossible de trouver le répertoire de Git :"
#: git-gui.sh:895
msgid "Cannot move to top of working directory:"
msgstr "Impossible d'aller à la racine du répertoire de travail :"
#: git-gui.sh:902
msgid "Cannot use funny .git directory:"
msgstr "Impossible d'utiliser un drôle de répertoire git :"
#: git-gui.sh:907
msgid "No working directory"
msgstr "Pas de répertoire de travail"
#: git-gui.sh:1054
msgid "Refreshing file status..."
msgstr "Rafraichissement du status des fichiers..."
#: git-gui.sh:1119
msgid "Scanning for modified files ..."
msgstr "Recherche de fichiers modifiés..."
#: git-gui.sh:1294 lib/browser.tcl:245
msgid "Ready."
msgstr "Prêt."
#: git-gui.sh:1560
msgid "Unmodified"
msgstr "Non modifié"
#: git-gui.sh:1562
msgid "Modified, not staged"
msgstr "Modifié, non pré-commité"
#: git-gui.sh:1563 git-gui.sh:1568
msgid "Staged for commit"
msgstr "Pré-commité"
#: git-gui.sh:1564 git-gui.sh:1569
msgid "Portions staged for commit"
msgstr "En partie pré-commité"
#: git-gui.sh:1565 git-gui.sh:1570
msgid "Staged for commit, missing"
msgstr "Pré-commité, manquant"
#: git-gui.sh:1567
msgid "Untracked, not staged"
msgstr "Non suivi, non pré-commité"
#: git-gui.sh:1572
msgid "Missing"
msgstr "Manquant"
#: git-gui.sh:1573
msgid "Staged for removal"
msgstr "Pré-commité pour suppression"
#: git-gui.sh:1574
msgid "Staged for removal, still present"
msgstr "Pré-commité pour suppression, toujours présent"
#: git-gui.sh:1576 git-gui.sh:1577 git-gui.sh:1578 git-gui.sh:1579
msgid "Requires merge resolution"
msgstr "Nécessite la résolution d'une fusion"
#: git-gui.sh:1614
msgid "Starting gitk... please wait..."
msgstr "Lancement de gitk... merci de patienter..."
#: git-gui.sh:1623
#, tcl-format
msgid ""
"Unable to start gitk:\n"
"\n"
"%s does not exist"
msgstr ""
"Impossible de lancer gitk :\n"
"\n"
"%s inexistant"
#: git-gui.sh:1823 lib/choose_repository.tcl:35
msgid "Repository"
msgstr "Référentiel"
#: git-gui.sh:1824
msgid "Edit"
msgstr "Editer"
#: git-gui.sh:1826 lib/choose_rev.tcl:560
msgid "Branch"
msgstr "Branche"
#: git-gui.sh:1829 lib/choose_rev.tcl:547
msgid "Commit@@noun"
msgstr "Commit"
#: git-gui.sh:1832 lib/merge.tcl:121 lib/merge.tcl:150 lib/merge.tcl:168
msgid "Merge"
msgstr "Fusionner"
#: git-gui.sh:1833 lib/choose_rev.tcl:556
msgid "Remote"
msgstr "Référentiel distant"
#: git-gui.sh:1842
msgid "Browse Current Branch's Files"
msgstr "Visionner fichiers dans branche courante"
#: git-gui.sh:1846
msgid "Browse Branch Files..."
msgstr "Visionner fichiers de branche"
#: git-gui.sh:1851
msgid "Visualize Current Branch's History"
msgstr "Visualiser historique branche courante"
#: git-gui.sh:1855
msgid "Visualize All Branch History"
msgstr "Visualiser historique toutes branches"
#: git-gui.sh:1862
#, tcl-format
msgid "Browse %s's Files"
msgstr "Visionner fichiers de %s"
#: git-gui.sh:1864
#, tcl-format
msgid "Visualize %s's History"
msgstr "Visualiser historique de %s"
#: git-gui.sh:1869 lib/database.tcl:27 lib/database.tcl:67
msgid "Database Statistics"
msgstr "Statistiques base de donnée"
#: git-gui.sh:1872 lib/database.tcl:34
msgid "Compress Database"
msgstr "Comprimer base de donnée"
#: git-gui.sh:1875
msgid "Verify Database"
msgstr "Vérifier base de donnée"
#: git-gui.sh:1882 git-gui.sh:1886 git-gui.sh:1890 lib/shortcut.tcl:7
#: lib/shortcut.tcl:39 lib/shortcut.tcl:71
msgid "Create Desktop Icon"
msgstr "Créer icône sur bureau"
#: git-gui.sh:1895 lib/choose_repository.tcl:176 lib/choose_repository.tcl:184
msgid "Quit"
msgstr "Quitter"
#: git-gui.sh:1902
msgid "Undo"
msgstr "Défaire"
#: git-gui.sh:1905
msgid "Redo"
msgstr "Refaire"
#: git-gui.sh:1909 git-gui.sh:2403
msgid "Cut"
msgstr "Couper"
#: git-gui.sh:1912 git-gui.sh:2406 git-gui.sh:2477 git-gui.sh:2549
#: lib/console.tcl:67
msgid "Copy"
msgstr "Copier"
#: git-gui.sh:1915 git-gui.sh:2409
msgid "Paste"
msgstr "Coller"
#: git-gui.sh:1918 git-gui.sh:2412 lib/branch_delete.tcl:26
#: lib/remote_branch_delete.tcl:38
msgid "Delete"
msgstr "Supprimer"
#: git-gui.sh:1922 git-gui.sh:2416 git-gui.sh:2553 lib/console.tcl:69
msgid "Select All"
msgstr "Tout sélectionner"
#: git-gui.sh:1931
msgid "Create..."
msgstr "Créer..."
#: git-gui.sh:1937
msgid "Checkout..."
msgstr "Emprunter... "
#: git-gui.sh:1943
msgid "Rename..."
msgstr "Renommer..."
#: git-gui.sh:1948 git-gui.sh:2048
msgid "Delete..."
msgstr "Supprimer..."
#: git-gui.sh:1953
msgid "Reset..."
msgstr "Réinitialiser..."
#: git-gui.sh:1965 git-gui.sh:2350
msgid "New Commit"
msgstr "Nouveau commit"
#: git-gui.sh:1973 git-gui.sh:2357
msgid "Amend Last Commit"
msgstr "Corriger dernier commit"
#: git-gui.sh:1982 git-gui.sh:2317 lib/remote_branch_delete.tcl:99
msgid "Rescan"
msgstr "Resynchroniser"
#: git-gui.sh:1988
msgid "Stage To Commit"
msgstr "Commiter un pré-commit"
#: git-gui.sh:1994
msgid "Stage Changed Files To Commit"
msgstr "Commiter fichiers modifiés dans pré-commit"
#: git-gui.sh:2000
msgid "Unstage From Commit"
msgstr "Commit vers pré-commit"
#: git-gui.sh:2005 lib/index.tcl:393
msgid "Revert Changes"
msgstr "Inverser modification"
#: git-gui.sh:2012 git-gui.sh:2329 git-gui.sh:2427
msgid "Sign Off"
msgstr "Se désinscrire"
#: git-gui.sh:2016 git-gui.sh:2333
msgid "Commit@@verb"
msgstr "Commiter"
#: git-gui.sh:2027
msgid "Local Merge..."
msgstr "Fusion locale..."
#: git-gui.sh:2032
msgid "Abort Merge..."
msgstr "Abandonner fusion..."
#: git-gui.sh:2044
msgid "Push..."
msgstr "Pousser..."
#: git-gui.sh:2055 lib/choose_repository.tcl:40
msgid "Apple"
msgstr "Pomme"
#: git-gui.sh:2058 git-gui.sh:2080 lib/about.tcl:13
#: lib/choose_repository.tcl:43 lib/choose_repository.tcl:49
#, tcl-format
msgid "About %s"
msgstr "A propos de %s"
#: git-gui.sh:2062
msgid "Preferences..."
msgstr "Préférences..."
#: git-gui.sh:2070 git-gui.sh:2595
msgid "Options..."
msgstr "Options..."
#: git-gui.sh:2076 lib/choose_repository.tcl:46
msgid "Help"
msgstr "Aide"
#: git-gui.sh:2117
msgid "Online Documentation"
msgstr "Documentation en ligne"
#: git-gui.sh:2201
#, tcl-format
msgid "fatal: cannot stat path %s: No such file or directory"
msgstr "fatale : pas d'infos sur le chemin %s : Fichier ou répertoire inexistant"
#: git-gui.sh:2234
msgid "Current Branch:"
msgstr "Branche courante :"
#: git-gui.sh:2255
msgid "Staged Changes (Will Commit)"
msgstr "Modifications pré-commitées"
#: git-gui.sh:2274
msgid "Unstaged Changes"
msgstr "Modifications non pré-commitées"
#: git-gui.sh:2323
msgid "Stage Changed"
msgstr "Pré-commit modifié"
#: git-gui.sh:2339 lib/transport.tcl:93 lib/transport.tcl:182
msgid "Push"
msgstr "Pousser"
#: git-gui.sh:2369
msgid "Initial Commit Message:"
msgstr "Message de commit initial :"
#: git-gui.sh:2370
msgid "Amended Commit Message:"
msgstr "Message de commit corrigé :"
#: git-gui.sh:2371
msgid "Amended Initial Commit Message:"
msgstr "Message de commit initial corrigé :"
#: git-gui.sh:2372
msgid "Amended Merge Commit Message:"
msgstr "Message de commit de fusion corrigé :"
#: git-gui.sh:2373
msgid "Merge Commit Message:"
msgstr "Message de commit de fusion :"
#: git-gui.sh:2374
msgid "Commit Message:"
msgstr "Message de commit :"
#: git-gui.sh:2419 git-gui.sh:2557 lib/console.tcl:71
msgid "Copy All"
msgstr "Copier tout"
#: git-gui.sh:2443 lib/blame.tcl:104
msgid "File:"
msgstr "Fichier :"
#: git-gui.sh:2545
msgid "Refresh"
msgstr "Rafraichir"
#: git-gui.sh:2566
msgid "Apply/Reverse Hunk"
msgstr "Appliquer/Inverser section"
#: git-gui.sh:2572
msgid "Decrease Font Size"
msgstr "Réduire fonte"
#: git-gui.sh:2576
msgid "Increase Font Size"
msgstr "Agrandir fonte"
#: git-gui.sh:2581
msgid "Show Less Context"
msgstr "Montrer moins de contexte"
#: git-gui.sh:2588
msgid "Show More Context"
msgstr "Montrer plus de contexte"
#: git-gui.sh:2602
msgid "Unstage Hunk From Commit"
msgstr "Enlever section pré-commitée"
#: git-gui.sh:2604
msgid "Stage Hunk For Commit"
msgstr "Pré-commiter section"
#: git-gui.sh:2623
msgid "Initializing..."
msgstr "Initialisation..."
#: git-gui.sh:2718
#, tcl-format
msgid ""
"Possible environment issues exist.\n"
"\n"
"The following environment variables are probably\n"
"going to be ignored by any Git subprocess run\n"
"by %s:\n"
"\n"
msgstr ""
"Des problèmes d'environnement sont possibles.\n"
"\n"
"Les variables d'environnement suivantes seront\n"
"probablement ignorées par tous les\n"
"sous-processus de Git lancés par %s\n"
"\n"
#: git-gui.sh:2748
msgid ""
"\n"
"This is due to a known issue with the\n"
"Tcl binary distributed by Cygwin."
msgstr ""
"\n"
"Ceci est du à un problème connu avec\n"
"le binaire Tcl distribué par Cygwin."
#: git-gui.sh:2753
#, tcl-format
msgid ""
"\n"
"\n"
"A good replacement for %s\n"
"is placing values for the user.name and\n"
"user.email settings into your personal\n"
"~/.gitconfig file.\n"
msgstr ""
"\n"
"\n"
"Un bon remplacement pour %s\n"
"est de mettre les valeurs pour 'user.name' (nom\n"
"de l'utilisateur) et 'user.email' (addresse email\n"
"de l'utilisateur) dans votre fichier '~/.gitconfig'."
#: lib/about.tcl:25
msgid "git-gui - a graphical user interface for Git."
msgstr "git-gui - une interface graphique utilisateur pour Git"
#: lib/blame.tcl:77
msgid "File Viewer"
msgstr "Visionneur de fichier"
#: lib/blame.tcl:81
msgid "Commit:"
msgstr "Commit :"
#: lib/blame.tcl:249
msgid "Copy Commit"
msgstr "Copier commit"
#: lib/blame.tcl:369
#, tcl-format
msgid "Reading %s..."
msgstr "Lecture de %s..."
#: lib/blame.tcl:473
msgid "Loading copy/move tracking annotations..."
msgstr "Chargement des annotations de suivi des copies/déplacements..."
#: lib/blame.tcl:493
msgid "lines annotated"
msgstr "lignes annotées"
#: lib/blame.tcl:674
msgid "Loading original location annotations..."
msgstr "Chargement des annotations d'emplacement original"
#: lib/blame.tcl:677
msgid "Annotation complete."
msgstr "Annotation terminée."
#: lib/blame.tcl:731
msgid "Loading annotation..."
msgstr "Chargement des annotations..."
#: lib/blame.tcl:787
msgid "Author:"
msgstr "Auteur :"
#: lib/blame.tcl:791
msgid "Committer:"
msgstr "Commiteur :"
#: lib/blame.tcl:796
msgid "Original File:"
msgstr "Fichier original :"
#: lib/blame.tcl:910
msgid "Originally By:"
msgstr "A l'origine par :"
#: lib/blame.tcl:916
msgid "In File:"
msgstr "Dans le fichier :"
#: lib/blame.tcl:921
msgid "Copied Or Moved Here By:"
msgstr "Copié ou déplacé ici par :"
#: lib/branch_checkout.tcl:14 lib/branch_checkout.tcl:19
msgid "Checkout Branch"
msgstr "Emprunter branche"
#: lib/branch_checkout.tcl:23
msgid "Checkout"
msgstr "Emprunter"
#: lib/branch_checkout.tcl:27 lib/branch_create.tcl:35
#: lib/branch_delete.tcl:32 lib/branch_rename.tcl:30 lib/browser.tcl:281
#: lib/checkout_op.tcl:522 lib/choose_font.tcl:43 lib/merge.tcl:172
#: lib/option.tcl:90 lib/remote_branch_delete.tcl:42 lib/transport.tcl:97
msgid "Cancel"
msgstr "Annuler"
#: lib/branch_checkout.tcl:32 lib/browser.tcl:286
msgid "Revision"
msgstr "Révision"
#: lib/branch_checkout.tcl:36 lib/branch_create.tcl:69 lib/option.tcl:202
msgid "Options"
msgstr "Options"
#: lib/branch_checkout.tcl:39 lib/branch_create.tcl:92
msgid "Fetch Tracking Branch"
msgstr "Branche suivant récupération"
#: lib/branch_checkout.tcl:44
msgid "Detach From Local Branch"
msgstr "Détacher de branche locale"
#: lib/branch_create.tcl:22
msgid "Create Branch"
msgstr "Créer branche"
#: lib/branch_create.tcl:27
msgid "Create New Branch"
msgstr "Créer nouvelle branche"
#: lib/branch_create.tcl:31 lib/choose_repository.tcl:375
msgid "Create"
msgstr "Créer"
#: lib/branch_create.tcl:40
msgid "Branch Name"
msgstr "Nom de branche"
#: lib/branch_create.tcl:43
msgid "Name:"
msgstr "Nom :"
#: lib/branch_create.tcl:58
msgid "Match Tracking Branch Name"
msgstr "Trouver nom de branche de suivi"
#: lib/branch_create.tcl:66
msgid "Starting Revision"
msgstr "Début de révision"
#: lib/branch_create.tcl:72
msgid "Update Existing Branch:"
msgstr "Mettre à jour branche existante :"
#: lib/branch_create.tcl:75
msgid "No"
msgstr "Non"
#: lib/branch_create.tcl:80
msgid "Fast Forward Only"
msgstr "Avance rapide seulement"
#: lib/branch_create.tcl:85 lib/checkout_op.tcl:514
msgid "Reset"
msgstr "Réinitialiser"
#: lib/branch_create.tcl:97
msgid "Checkout After Creation"
msgstr "Emprunt après création"
#: lib/branch_create.tcl:131
msgid "Please select a tracking branch."
msgstr "Merci de choisir une branche de suivi"
#: lib/branch_create.tcl:140
#, tcl-format
msgid "Tracking branch %s is not a branch in the remote repository."
msgstr "La branche de suivi %s n'est pas une branche dans le référentiel distant."
#: lib/branch_create.tcl:153 lib/branch_rename.tcl:86
msgid "Please supply a branch name."
msgstr "Merci de fournir un nom de branche."
#: lib/branch_create.tcl:164 lib/branch_rename.tcl:106
#, tcl-format
msgid "'%s' is not an acceptable branch name."
msgstr "'%s' n'est pas un nom de branche acceptable."
#: lib/branch_delete.tcl:15
msgid "Delete Branch"
msgstr "Supprimer branche"
#: lib/branch_delete.tcl:20
msgid "Delete Local Branch"
msgstr "Supprimer branche locale"
#: lib/branch_delete.tcl:37
msgid "Local Branches"
msgstr "Branches locales"
#: lib/branch_delete.tcl:52
msgid "Delete Only If Merged Into"
msgstr "Supprimer ssi fusion dedans"
#: lib/branch_delete.tcl:54
msgid "Always (Do not perform merge test.)"
msgstr "Toujours (Ne pas faire de test de fusion.)"
#: lib/branch_delete.tcl:103
#, tcl-format
msgid "The following branches are not completely merged into %s:"
msgstr "Les branches suivantes ne sont pas complètement fusionnées dans %s :"
#: lib/branch_delete.tcl:115
msgid ""
"Recovering deleted branches is difficult. \n"
"\n"
" Delete the selected branches?"
msgstr ""
"Récupérer des branches supprimées est difficile.\n"
"\n"
"Supprimer les branches sélectionnées ?"
#: lib/branch_delete.tcl:141
#, tcl-format
msgid ""
"Failed to delete branches:\n"
"%s"
msgstr ""
"La suppression des branches suivantes a échouée :\n"
"%s"
#: lib/branch_rename.tcl:14 lib/branch_rename.tcl:22
msgid "Rename Branch"
msgstr "Renommer branche"
#: lib/branch_rename.tcl:26
msgid "Rename"
msgstr "Renommer"
#: lib/branch_rename.tcl:36
msgid "Branch:"
msgstr "Branche :"
#: lib/branch_rename.tcl:39
msgid "New Name:"
msgstr "Nouveau nom :"
#: lib/branch_rename.tcl:75
msgid "Please select a branch to rename."
msgstr "Merci de sélectionner une branche à renommer."
#: lib/branch_rename.tcl:96 lib/checkout_op.tcl:179
#, tcl-format
msgid "Branch '%s' already exists."
msgstr "La branche '%s' existe déjà."
#: lib/branch_rename.tcl:117
#, tcl-format
msgid "Failed to rename '%s'."
msgstr "Le renommage de '%s' a échoué."
#: lib/browser.tcl:17
msgid "Starting..."
msgstr "Lancement..."
#: lib/browser.tcl:26
msgid "File Browser"
msgstr "Visionneur de fichier"
#: lib/browser.tcl:125 lib/browser.tcl:142
#, tcl-format
msgid "Loading %s..."
msgstr "Chargement de %s..."
#: lib/browser.tcl:186
msgid "[Up To Parent]"
msgstr "[Jusqu'au parent]"
#: lib/browser.tcl:266 lib/browser.tcl:272
msgid "Browse Branch Files"
msgstr "Visionner fichiers de branches"
#: lib/browser.tcl:277 lib/choose_repository.tcl:391
#: lib/choose_repository.tcl:482 lib/choose_repository.tcl:492
#: lib/choose_repository.tcl:989
msgid "Browse"
msgstr "Visionner"
#: lib/checkout_op.tcl:79
#, tcl-format
msgid "Fetching %s from %s"
msgstr "Récupération de %s à partir de %s"
#: lib/checkout_op.tcl:127
#, tcl-format
msgid "fatal: Cannot resolve %s"
msgstr "Erreur fatale : Impossible de résoudre %s"
#: lib/checkout_op.tcl:140 lib/console.tcl:79 lib/database.tcl:31
msgid "Close"
msgstr "Fermer"
#: lib/checkout_op.tcl:169
#, tcl-format
msgid "Branch '%s' does not exist."
msgstr "La branche '%s' n'existe pas."
#: lib/checkout_op.tcl:206
#, tcl-format
msgid ""
"Branch '%s' already exists.\n"
"\n"
"It cannot fast-forward to %s.\n"
"A merge is required."
msgstr ""
"La branche '%s' existe déjà.\n"
"\n"
"Impossible d'avancer rapidement à %s.\n"
"Une fusion est nécessaire."
#: lib/checkout_op.tcl:220
#, tcl-format
msgid "Merge strategy '%s' not supported."
msgstr "La stratégie de fusion '%s' n'est pas supportée."
#: lib/checkout_op.tcl:239
#, tcl-format
msgid "Failed to update '%s'."
msgstr "La mise à jour de '%s' a échouée."
#: lib/checkout_op.tcl:251
msgid "Staging area (index) is already locked."
msgstr "L'espace de pré-commit ('index' ou 'staging') est déjà vérouillé."
#: lib/checkout_op.tcl:266
msgid ""
"Last scanned state does not match repository state.\n"
"\n"
"Another Git program has modified this repository since the last scan. A "
"rescan must be performed before the current branch can be changed.\n"
"\n"
"The rescan will be automatically started now.\n"
msgstr ""
"L'état lors de la dernière synchronisation ne correspond plus à l'état du référentiel.\n"
"\n"
"Un autre programme Git a modifié ce référentiel depuis la dernière synchronisation. Une resynchronisation doit être effectuée avant de pouvoir modifier la branche courante.\n"
"\n"
"Cela va être fait tout de suite automatiquement.\n"
#: lib/checkout_op.tcl:322
#, tcl-format
msgid "Updating working directory to '%s'..."
msgstr "Mise à jour du répertoire courant avec '%s'..."
#: lib/checkout_op.tcl:353
#, tcl-format
msgid "Aborted checkout of '%s' (file level merging is required)."
msgstr "Emprunt de '%s' abandonné. (Il est nécessaire de fusionner des fichiers.)"
#: lib/checkout_op.tcl:354
msgid "File level merge required."
msgstr "Il est nécessaire de fusionner des fichiers."
#: lib/checkout_op.tcl:358
#, tcl-format
msgid "Staying on branch '%s'."
msgstr "Le répertoire de travail reste sur la branche '%s'."
#: lib/checkout_op.tcl:429
msgid ""
"You are no longer on a local branch.\n"
"\n"
"If you wanted to be on a branch, create one now starting from 'This Detached "
"Checkout'."
msgstr ""
"Vous n'êtes plus ur une branche locale.\n"
"\n"
"Si vous vouliez être sur une branche, créez en une maintenant en partant de 'Cet emprunt détaché'."
#: lib/checkout_op.tcl:446
#, tcl-format
msgid "Checked out '%s'."
msgstr "'%s' emprunté."
#: lib/checkout_op.tcl:478
#, tcl-format
msgid "Resetting '%s' to '%s' will lose the following commits:"
msgstr "Réinitialiser '%s' à '%s' va faire perdre les commits suivants :"
#: lib/checkout_op.tcl:500
msgid "Recovering lost commits may not be easy."
msgstr "Récupérer les commits perdus ne sera peut être pas facile."
#: lib/checkout_op.tcl:505
#, tcl-format
msgid "Reset '%s'?"
msgstr "Réinitialiser '%s' ?"
#: lib/checkout_op.tcl:510 lib/merge.tcl:164
msgid "Visualize"
msgstr "Visualiser"
#: lib/checkout_op.tcl:578
#, tcl-format
msgid ""
"Failed to set current branch.\n"
"\n"
"This working directory is only partially switched. We successfully updated "
"your files, but failed to update an internal Git file.\n"
"\n"
"This should not have occurred. %s will now close and give up."
msgstr ""
"Le changement de la branche courante a échoué.\n"
"\n"
"Le répertoire courant n'est que partiellement modifié. Les fichiers ont été mis à jour avec succès, mais la mise à jour d'un fichier interne à Git a échouée.\n"
"\n"
"Cela n'aurait pas du se produire. %s va abandonner et se terminer."
#: lib/choose_font.tcl:39
msgid "Select"
msgstr "Sélectionner"
#: lib/choose_font.tcl:53
msgid "Font Family"
msgstr "Famille de fonte"
#: lib/choose_font.tcl:73
msgid "Font Size"
msgstr "Taille de fonte"
#: lib/choose_font.tcl:90
msgid "Font Example"
msgstr "Exemple de fonte"
#: lib/choose_font.tcl:101
msgid ""
"This is example text.\n"
"If you like this text, it can be your font."
msgstr ""
"C'est un texte d'exemple.\n"
"Si vous aimez ce texte, vous pouvez choisir cette fonte."
#: lib/choose_repository.tcl:27
msgid "Git Gui"
msgstr "Git Gui"
#: lib/choose_repository.tcl:80 lib/choose_repository.tcl:380
msgid "Create New Repository"
msgstr "Créer nouveau référentiel"
#: lib/choose_repository.tcl:86
msgid "New..."
msgstr "Nouveau..."
#: lib/choose_repository.tcl:93 lib/choose_repository.tcl:468
msgid "Clone Existing Repository"
msgstr "Cloner référentiel existant"
#: lib/choose_repository.tcl:99
msgid "Clone..."
msgstr "Cloner..."
#: lib/choose_repository.tcl:106 lib/choose_repository.tcl:978
msgid "Open Existing Repository"
msgstr "Ouvrir référentiel existant"
#: lib/choose_repository.tcl:112
msgid "Open..."
msgstr "Ouvrir..."
#: lib/choose_repository.tcl:125
msgid "Recent Repositories"
msgstr "Référentiels récents"
#: lib/choose_repository.tcl:131
msgid "Open Recent Repository:"
msgstr "Ouvrir référentiel récent :"
#: lib/choose_repository.tcl:294
#, tcl-format
msgid "Location %s already exists."
msgstr "L'emplacement %s existe déjà."
#: lib/choose_repository.tcl:300 lib/choose_repository.tcl:307
#: lib/choose_repository.tcl:314
#, tcl-format
msgid "Failed to create repository %s:"
msgstr "La création du référentiel %s a échouée :"
#: lib/choose_repository.tcl:385 lib/choose_repository.tcl:486
msgid "Directory:"
msgstr "Répertoire :"
#: lib/choose_repository.tcl:415 lib/choose_repository.tcl:544
#: lib/choose_repository.tcl:1013
msgid "Git Repository"
msgstr "Référentiel Git"
#: lib/choose_repository.tcl:430 lib/choose_repository.tcl:437
#, tcl-format
msgid "Directory %s already exists."
msgstr "Le répertoire %s existe déjà."
#: lib/choose_repository.tcl:442
#, tcl-format
msgid "File %s already exists."
msgstr "Le fichier %s existe déjà."
#: lib/choose_repository.tcl:463
msgid "Clone"
msgstr "Cloner"
#: lib/choose_repository.tcl:476
msgid "URL:"
msgstr "URL :"
#: lib/choose_repository.tcl:496
msgid "Clone Type:"
msgstr "Type de clonage :"
#: lib/choose_repository.tcl:502
msgid "Standard (Fast, Semi-Redundant, Hardlinks)"
msgstr "Standard (rapide, semi-redondant, liens durs)"
#: lib/choose_repository.tcl:508
msgid "Full Copy (Slower, Redundant Backup)"
msgstr "Copy complète (plus lent, sauvegarde redondante)"
#: lib/choose_repository.tcl:514
msgid "Shared (Fastest, Not Recommended, No Backup)"
msgstr "Partagé (le plus rapide, non recommandé, pas de sauvegarde)"
#: lib/choose_repository.tcl:550 lib/choose_repository.tcl:597
#: lib/choose_repository.tcl:738 lib/choose_repository.tcl:808
#: lib/choose_repository.tcl:1019 lib/choose_repository.tcl:1027
#, tcl-format
msgid "Not a Git repository: %s"
msgstr "'%s' n'est pas un référentiel Git."
#: lib/choose_repository.tcl:586
msgid "Standard only available for local repository."
msgstr "Standard n'est disponible que pour un référentiel local."
#: lib/choose_repository.tcl:590
msgid "Shared only available for local repository."
msgstr "Partagé n'est disponible que pour un référentiel local."
#: lib/choose_repository.tcl:617
msgid "Failed to configure origin"
msgstr "La configuration de l'origine a échouée."
#: lib/choose_repository.tcl:629
msgid "Counting objects"
msgstr "Comptage des objets"
#: lib/choose_repository.tcl:630
msgid "buckets"
msgstr "paniers"
#: lib/choose_repository.tcl:654
#, tcl-format
msgid "Unable to copy objects/info/alternates: %s"
msgstr "Impossible de copier 'objects/info/alternates' : %s"
#: lib/choose_repository.tcl:690
#, tcl-format
msgid "Nothing to clone from %s."
msgstr "Il n'y a rien à cloner depuis %s."
#: lib/choose_repository.tcl:692 lib/choose_repository.tcl:906
#: lib/choose_repository.tcl:918
msgid "The 'master' branch has not been initialized."
msgstr "Cette branche 'master' n'a pas été initialisée."
#: lib/choose_repository.tcl:705
msgid "Hardlinks are unavailable. Falling back to copying."
msgstr "Les liens durs ne sont pas disponibles. On se résoud à copier."
#: lib/choose_repository.tcl:717
#, tcl-format
msgid "Cloning from %s"
msgstr "Clonage depuis %s"
#: lib/choose_repository.tcl:748
msgid "Copying objects"
msgstr "Copie des objets"
#: lib/choose_repository.tcl:749
msgid "KiB"
msgstr "KiB"
#: lib/choose_repository.tcl:773
#, tcl-format
msgid "Unable to copy object: %s"
msgstr "Impossible de copier l'objet : %s"
#: lib/choose_repository.tcl:783
msgid "Linking objects"
msgstr "Liaison des objets"
#: lib/choose_repository.tcl:784
msgid "objects"
msgstr "objets"
#: lib/choose_repository.tcl:792
#, tcl-format
msgid "Unable to hardlink object: %s"
msgstr "Impossible créer un lien dur pour l'objet : %s"
#: lib/choose_repository.tcl:847
msgid "Cannot fetch branches and objects. See console output for details."
msgstr "Impossible de récupérer les branches et objets. Voir la sortie console pour plus de détails."
#: lib/choose_repository.tcl:858
msgid "Cannot fetch tags. See console output for details."
msgstr "Impossible de récupérer les marques. Voir la sortie console pour plus de détails."
#: lib/choose_repository.tcl:882
msgid "Cannot determine HEAD. See console output for details."
msgstr "Impossible de déterminer HEAD. Voir la sortie console pour plus de détails."
#: lib/choose_repository.tcl:891
#, tcl-format
msgid "Unable to cleanup %s"
msgstr "Impossible de nettoyer %s"
#: lib/choose_repository.tcl:897
msgid "Clone failed."
msgstr "Le clonage a échoué."
#: lib/choose_repository.tcl:904
msgid "No default branch obtained."
msgstr "Aucune branche par défaut n'a été obtenue."
#: lib/choose_repository.tcl:915
#, tcl-format
msgid "Cannot resolve %s as a commit."
msgstr "Impossible de résoudre %s comme commit."
#: lib/choose_repository.tcl:927
msgid "Creating working directory"
msgstr "Création du répertoire de travail"
#: lib/choose_repository.tcl:928 lib/index.tcl:65 lib/index.tcl:127
#: lib/index.tcl:193
msgid "files"
msgstr "fichiers"
#: lib/choose_repository.tcl:957
msgid "Initial file checkout failed."
msgstr "L'emprunt initial de fichier a échoué."
#: lib/choose_repository.tcl:973
msgid "Open"
msgstr "Ouvrir"
#: lib/choose_repository.tcl:983
msgid "Repository:"
msgstr "Référentiel :"
#: lib/choose_repository.tcl:1033
#, tcl-format
msgid "Failed to open repository %s:"
msgstr "Impossible d'ouvrir le référentiel %s :"
#: lib/choose_rev.tcl:53
msgid "This Detached Checkout"
msgstr "Cet emprunt détaché"
#: lib/choose_rev.tcl:60
msgid "Revision Expression:"
msgstr "Expression de révision :"
#: lib/choose_rev.tcl:74
msgid "Local Branch"
msgstr "Branche locale"
#: lib/choose_rev.tcl:79
msgid "Tracking Branch"
msgstr "Suivi de branche"
#: lib/choose_rev.tcl:84 lib/choose_rev.tcl:537
msgid "Tag"
msgstr "Marque"
#: lib/choose_rev.tcl:317
#, tcl-format
msgid "Invalid revision: %s"
msgstr "Révision invalide : %s"
#: lib/choose_rev.tcl:338
msgid "No revision selected."
msgstr "Pas de révision selectionnée."
#: lib/choose_rev.tcl:346
msgid "Revision expression is empty."
msgstr "L'expression de révision est vide."
#: lib/choose_rev.tcl:530
msgid "Updated"
msgstr "Misa à jour"
#: lib/choose_rev.tcl:558
msgid "URL"
msgstr "URL"
#: lib/commit.tcl:9
msgid ""
"There is nothing to amend.\n"
"\n"
"You are about to create the initial commit. There is no commit before this "
"to amend.\n"
msgstr ""
"Il n'y a rien à corriger.\n"
"\n"
"Vous allez créer le commit initial. Il n'y a pas de commit avant celui-ci à corriger.\n"
#: lib/commit.tcl:18
msgid ""
"Cannot amend while merging.\n"
"\n"
"You are currently in the middle of a merge that has not been fully "
"completed. You cannot amend the prior commit unless you first abort the "
"current merge activity.\n"
msgstr ""
"Impossible de corriger pendant une fusion.\n"
"\n"
"Vous êtes actuellement au milieu d'une fusion qui n'a pas été completement terminée. Vous ne pouvez pas corriger le commit précédant sauf si vous abandonnez la fusion courante.\n"
#: lib/commit.tcl:49
msgid "Error loading commit data for amend:"
msgstr "Erreur lors du chargement des données de commit pour correction :"
#: lib/commit.tcl:76
msgid "Unable to obtain your identity:"
msgstr "Impossible d'obtenir votre identité :"
#: lib/commit.tcl:81
msgid "Invalid GIT_COMMITTER_IDENT:"
msgstr "GIT_COMMITTER_IDENT invalide :"
#: lib/commit.tcl:133
msgid ""
"Last scanned state does not match repository state.\n"
"\n"
"Another Git program has modified this repository since the last scan. A "
"rescan must be performed before another commit can be created.\n"
"\n"
"The rescan will be automatically started now.\n"
msgstr ""
"L'état lors de la dernière synchronisation ne correspond plus à l'état du référentiel.\n"
"\n"
"Un autre programme Git a modifié ce référentiel depuis la dernière synchronisation. Une resynshronisation doit être effectuée avant de pouvoir créer un nouveau commit.\n"
"\n"
"Cela va être fait tout de suite automatiquement.\n"
#: lib/commit.tcl:154
#, tcl-format
msgid ""
"Unmerged files cannot be committed.\n"
"\n"
"File %s has merge conflicts. You must resolve them and stage the file "
"before committing.\n"
msgstr ""
"Des fichiers non fusionnés ne peuvent être commités.\n"
"\n"
"Le fichier %s a des conflicts de fusion. Vous devez les résoudre et pré-commiter le fichier avant de pouvoir commiter.\n"
#: lib/commit.tcl:162
#, tcl-format
msgid ""
"Unknown file state %s detected.\n"
"\n"
"File %s cannot be committed by this program.\n"
msgstr ""
"Un état de fichier inconnu %s a été détecté.\n"
"\n"
"Le fichier %s ne peut pas être commité par ce programme.\n"
#: lib/commit.tcl:170
msgid ""
"No changes to commit.\n"
"\n"
"You must stage at least 1 file before you can commit.\n"
msgstr ""
"Pas de modification à commiter.\n"
"\n"
"Vous devez pré-commiter au moins 1 fichier avant de pouvoir commiter.\n"
#: lib/commit.tcl:183
msgid ""
"Please supply a commit message.\n"
"\n"
"A good commit message has the following format:\n"
"\n"
"- First line: Describe in one sentence what you did.\n"
"- Second line: Blank\n"
"- Remaining lines: Describe why this change is good.\n"
msgstr ""
"Merci de fournir un message de commit.\n"
"\n"
"Un bon message de commit a le format suivant :\n"
"\n"
"- Première ligne : décrire en une phrase ce que vous avez fait.\n"
"- Deuxième ligne : rien.\n"
"- Lignes suivantes : Décrire pourquoi ces modifications sont bonnes.\n"
#: lib/commit.tcl:257
msgid "write-tree failed:"
msgstr "write-tree a échoué :"
#: lib/commit.tcl:275
#, tcl-format
msgid "Commit %s appears to be corrupt"
msgstr "Le commit %s semble être corrompu"
#: lib/commit.tcl:279
msgid ""
"No changes to commit.\n"
"\n"
"No files were modified by this commit and it was not a merge commit.\n"
"\n"
"A rescan will be automatically started now.\n"
msgstr ""
"Pas de modification à commiter.\n"
"\n"
"Aucun fichier n'a été modifié par ce commit et il ne s'agit pas d'un commit de fusion.\n"
"\n"
"Une resynchronisation va être lancée tout de suite automatiquement.\n"
#: lib/commit.tcl:286
msgid "No changes to commit."
msgstr "Pas de modifications à commiter."
#: lib/commit.tcl:303
#, tcl-format
msgid "warning: Tcl does not support encoding '%s'."
msgstr "attention : Tcl ne supporte pas l'encodage '%s'."
#: lib/commit.tcl:317
msgid "commit-tree failed:"
msgstr "commit-tree a échoué :"
#: lib/commit.tcl:339
msgid "update-ref failed:"
msgstr "update-ref a échoué"
#: lib/commit.tcl:430
#, tcl-format
msgid "Created commit %s: %s"
msgstr "Commit créé %s : %s"
#: lib/console.tcl:57
msgid "Working... please wait..."
msgstr "Travail en cours... merci de patienter..."
#: lib/console.tcl:183
msgid "Success"
msgstr "Succès"
#: lib/console.tcl:196
msgid "Error: Command Failed"
msgstr "Erreur : échec de la commande"
#: lib/database.tcl:43
msgid "Number of loose objects"
msgstr "Nombre d'objets en fichier particulier"
#: lib/database.tcl:44
msgid "Disk space used by loose objects"
msgstr "Espace disque utilisé par les fichiers particuliers"
#: lib/database.tcl:45
msgid "Number of packed objects"
msgstr "Nombre d'objets empaquetés"
#: lib/database.tcl:46
msgid "Number of packs"
msgstr "Nombre de paquets d'objets"
#: lib/database.tcl:47
msgid "Disk space used by packed objects"
msgstr "Espace disque utilisé par les objets empaquetés"
#: lib/database.tcl:48
msgid "Packed objects waiting for pruning"
msgstr "Objets empaquetés attendant d'être supprimés"
#: lib/database.tcl:49
msgid "Garbage files"
msgstr "Fichiers poubelle"
#: lib/database.tcl:72ets
msgid "Compressing the object database"
msgstr "Compression de la base des objets"
#: lib/database.tcl:83
msgid "Verifying the object database with fsck-objects"
msgstr "Vérification de la base des objets avec fsck-objects"
#: lib/database.tcl:108
#, tcl-format
msgid ""
"This repository currently has approximately %i loose objects.\n"
"\n"
"To maintain optimal performance it is strongly recommended that you compress "
"the database when more than %i loose objects exist.\n"
"\n"
"Compress the database now?"
msgstr ""
"Ce référentiel comprend actuellement environ %i objets ayant leur fichier particulier.\n"
"\n"
"Pour conserver une performance optimale, il est fortement recommandé de comprimer la base quand plus de %i objets ayant leur fichier particulier existent.\n"
"\n"
"Comprimer la base maintenant ?"
#: lib/date.tcl:25
#, tcl-format
msgid "Invalid date from Git: %s"
msgstr "Date invalide de Git : %s"
#: lib/diff.tcl:42
#, tcl-format
msgid ""
"No differences detected.\n"
"\n"
"%s has no changes.\n"
"\n"
"The modification date of this file was updated by another application, but "
"the content within the file was not changed.\n"
"\n"
"A rescan will be automatically started to find other files which may have "
"the same state."
msgstr ""
"Aucune différence détectée.\n"
"\n"
"%s ne comporte aucune modification.\n"
"\n"
"La date de modification de ce fichier a été mise à jour par une autre application, mais le contenu du fichier n'a pas changé.\n"
"\n"
"Une resynchronisation va être lancée automatiquement pour trouver d'autres fichiers qui pourraient se trouver dans le même état."
#: lib/diff.tcl:81
#, tcl-format
msgid "Loading diff of %s..."
msgstr "Chargement des différences de %s..."
#: lib/diff.tcl:114 lib/diff.tcl:184
#, tcl-format
msgid "Unable to display %s"
msgstr "Impossible d'afficher %s"
#: lib/diff.tcl:115
msgid "Error loading file:"
msgstr "Erreur lors du chargement du fichier :"
#: lib/diff.tcl:122
msgid "Git Repository (subproject)"
msgstr "Référentiel Git (sous projet)"
#: lib/diff.tcl:134
msgid "* Binary file (not showing content)."
msgstr "* Fichier binaire (pas d'apperçu du contenu)."
#: lib/diff.tcl:185
msgid "Error loading diff:"
msgstr "Erreur lors du chargement des différences :"
#: lib/diff.tcl:302
msgid "Failed to unstage selected hunk."
msgstr "La suppression dans le pré-commit de la section sélectionnée a échouée."
#: lib/diff.tcl:309
msgid "Failed to stage selected hunk."
msgstr "Le pré-commit de la section sélectionnée a échoué."
#: lib/error.tcl:12 lib/error.tcl:102
msgid "error"
msgstr "erreur"
#: lib/error.tcl:28
msgid "warning"
msgstr "attention"
#: lib/error.tcl:81
msgid "You must correct the above errors before committing."
msgstr "Vous devez corriger les erreurs suivantes avant de pouvoir commiter."
#: lib/index.tcl:6
msgid "Unable to unlock the index."
msgstr "Impossible de dévérouiller le pré-commit."
#: lib/index.tcl:15
msgid "Index Error"
msgstr "Erreur de pré-commit"
#: lib/index.tcl:21
msgid ""
"Updating the Git index failed. A rescan will be automatically started to "
"resynchronize git-gui."
msgstr "Le pré-commit a échoué. Une resynchronisation va être lancée automatiquement."
#: lib/index.tcl:27
msgid "Continue"
msgstr "Continuer"
#: lib/index.tcl:31
msgid "Unlock Index"
msgstr "Dévérouiller le pré-commit"
#: lib/index.tcl:282
#, tcl-format
msgid "Unstaging %s from commit"
msgstr "Supprimer %s du commit"
#: lib/index.tcl:326
#, tcl-format
msgid "Adding %s"
msgstr "Ajouter %s"
#: lib/index.tcl:381
#, tcl-format
msgid "Revert changes in file %s?"
msgstr "Inverser les modifications dans le fichier %s ? "
#: lib/index.tcl:383
#, tcl-format
msgid "Revert changes in these %i files?"
msgstr "Inverser les modifications dans ces %i fichiers ?"
#: lib/index.tcl:389
msgid "Any unstaged changes will be permanently lost by the revert."
msgstr "Toutes les modifications non pré-commitées seront définitivement perdues lors de l'inversion."
#: lib/index.tcl:392
msgid "Do Nothing"
msgstr "Ne rien faire"
#: lib/merge.tcl:13
msgid ""
"Cannot merge while amending.\n"
"\n"
"You must finish amending this commit before starting any type of merge.\n"
msgstr ""
"Impossible de fucionner pendant une correction.\n"
"\n"
"Vous devez finir de corriger ce commit avant de lancer une quelconque fusion.\n"
#: lib/merge.tcl:27
msgid ""
"Last scanned state does not match repository state.\n"
"\n"
"Another Git program has modified this repository since the last scan. A "
"rescan must be performed before a merge can be performed.\n"
"\n"
"The rescan will be automatically started now.\n"
msgstr ""
"L'état lors de la dernière synchronisation ne correspond plus à l'état du référentiel.\n"
"\n"
"Un autre programme Git a modifié ce référentiel depuis la dernière synchronisation. Une resynchronisation doit être effectuée avant de pouvoir fusionner de nouveau.\n"
"\n"
"Cela va être fait tout de suite automatiquement\n"
#: lib/merge.tcl:44
#, tcl-format
msgid ""
"You are in the middle of a conflicted merge.\n"
"\n"
"File %s has merge conflicts.\n"
"\n"
"You must resolve them, stage the file, and commit to complete the current "
"merge. Only then can you begin another merge.\n"
msgstr ""
"Vous êtes au milieu d'une fusion conflictuelle.\n"
"\n"
"Le fichier %s a des conflicts de fusion.\n"
"\n"
"Vous devez les résoudre, puis pré-commiter le fichier, et enfin commiter pour terminer la fusion courante. Seulementà ce moment là, il sera possible d'effectuer une nouvelle fusion.\n"
#: lib/merge.tcl:54
#, tcl-format
msgid ""
"You are in the middle of a change.\n"
"\n"
"File %s is modified.\n"
"\n"
"You should complete the current commit before starting a merge. Doing so "
"will help you abort a failed merge, should the need arise.\n"
msgstr ""
"Vous êtes au milieu d'une modification.\n"
"\n"
"Le fichier %s est modifié.\n"
"\n"
"Vous devriez terminer le commit courant avant de lancer une fusion. En faisait comme cela, vous éviterez de devoir éventuellement abandonner une fusion ayant échouée.\n"
#: lib/merge.tcl:106
#, tcl-format
msgid "%s of %s"
msgstr "%s de %s"
#: lib/merge.tcl:119
#, tcl-format
msgid "Merging %s and %s"
msgstr "Fusion de %s et %s"
#: lib/merge.tcl:131
msgid "Merge completed successfully."
msgstr "La fusion s'est faite avec succès."
#: lib/merge.tcl:133
msgid "Merge failed. Conflict resolution is required."
msgstr "La fusion a echouée. Il est nécessaire de résoudre les conflicts."
#: lib/merge.tcl:158
#, tcl-format
msgid "Merge Into %s"
msgstr "Fusion dans %s"
#: lib/merge.tcl:177
msgid "Revision To Merge"
msgstr "Révision à fusionner"
#: lib/merge.tcl:212
msgid ""
"Cannot abort while amending.\n"
"\n"
"You must finish amending this commit.\n"
msgstr ""
"Impossible d'abandonner en cours de correction.\n"
"\n"
"Vous devez finir de corriger ce commit.\n"
#: lib/merge.tcl:222
msgid ""
"Abort merge?\n"
"\n"
"Aborting the current merge will cause *ALL* uncommitted changes to be lost.\n"
"\n"
"Continue with aborting the current merge?"
msgstr ""
"Abandonner la fusion ?\n"
"\n"
"Abandonner la fusion courante entrainera la perte de TOUTES les modifications non commitées.\n"
"\n"
"Abandonner quand même la fusion courante ?"
#: lib/merge.tcl:228
msgid ""
"Reset changes?\n"
"\n"
"Resetting the changes will cause *ALL* uncommitted changes to be lost.\n"
"\n"
"Continue with resetting the current changes?"
msgstr ""
"Réinitialiser les modifications ?\n"
"\n"
"Réinitialiser les modifications va faire perdre TOUTES les modifications non commitées.\n"
"\n"
"Réinitialiser quand même les modifications courantes ?"
#: lib/merge.tcl:239
msgid "Aborting"
msgstr "Abandon"
#: lib/merge.tcl:266
msgid "Abort failed."
msgstr "L'abandon a échoué."
#: lib/merge.tcl:268
msgid "Abort completed. Ready."
msgstr "Abandon teminé. Prêt."
#: lib/option.tcl:82
msgid "Restore Defaults"
msgstr "Remettre les valeurs par défaut"
#: lib/option.tcl:86
msgid "Save"
msgstr "Sauvegarder"
#: lib/option.tcl:96
#, tcl-format
msgid "%s Repository"
msgstr "Référentiel de %s"
#: lib/option.tcl:97
msgid "Global (All Repositories)"
msgstr "Globales (tous les référentiels)"
#: lib/option.tcl:103
msgid "User Name"
msgstr "Nom d'utilisateur"
#: lib/option.tcl:104
msgid "Email Address"
msgstr "Adresse email"
#: lib/option.tcl:106
msgid "Summarize Merge Commits"
msgstr "Résumer les commits de fusion"
#: lib/option.tcl:107
msgid "Merge Verbosity"
msgstr "Fusion bavarde"
#: lib/option.tcl:108
msgid "Show Diffstat After Merge"
msgstr "Montrer statistiques de diff après fusion"
#: lib/option.tcl:110
msgid "Trust File Modification Timestamps"
msgstr "Faire confiance aux dates de modification de fichiers "
#: lib/option.tcl:111
msgid "Prune Tracking Branches During Fetch"
msgstr "Nettoyer les branches de suivi pendant la récupération"
#: lib/option.tcl:112
msgid "Match Tracking Branches"
msgstr "Faire correspondre les branches de suivi"
#: lib/option.tcl:113
msgid "Number of Diff Context Lines"
msgstr "Nombre de lignes de contexte dans les diffs"
#: lib/option.tcl:114
msgid "New Branch Name Template"
msgstr "Nouveau modèle de nom de branche"
#: lib/option.tcl:176
msgid "Change Font"
msgstr "Modifier les fontes"
#: lib/option.tcl:180
#, tcl-format
msgid "Choose %s"
msgstr "Choisir %s"
#: lib/option.tcl:186
msgid "pt."
msgstr "pt."
#: lib/option.tcl:200
msgid "Preferences"
msgstr "Préférences"
#: lib/option.tcl:235
msgid "Failed to completely save options:"
msgstr "La sauvegarde complète des options a échouée :"
#: lib/remote_branch_delete.tcl:29 lib/remote_branch_delete.tcl:34
msgid "Delete Remote Branch"
msgstr "Supprimer branche distante"
#: lib/remote_branch_delete.tcl:47
msgid "From Repository"
msgstr "Référentiel"
#: lib/remote_branch_delete.tcl:50 lib/transport.tcl:123
msgid "Remote:"
msgstr "Branche distante :"
#: lib/remote_branch_delete.tcl:66 lib/transport.tcl:138
msgid "Arbitrary URL:"
msgstr "URL arbitraire :"
#: lib/remote_branch_delete.tcl:84
msgid "Branches"
msgstr "Branches"
#: lib/remote_branch_delete.tcl:109
msgid "Delete Only If"
msgstr "Supprimer seulement si"
#: lib/remote_branch_delete.tcl:111
msgid "Merged Into:"
msgstr "Fusionné dans :"
#: lib/remote_branch_delete.tcl:119
msgid "Always (Do not perform merge checks)"
msgstr "Toujours (ne pas vérifier les fusions)"
#: lib/remote_branch_delete.tcl:152
msgid "A branch is required for 'Merged Into'."
msgstr "Une branche est nécessaire pour 'Fusionné dans'."
#: lib/remote_branch_delete.tcl:184
#, tcl-format
msgid ""
"The following branches are not completely merged into %s:\n"
"\n"
" - %s"
msgstr ""
"Les branches suivantes ne sont pas complètement fusionnées dans %s :\n"
"\n"
" - %s"
#: lib/remote_branch_delete.tcl:189
#, tcl-format
msgid ""
"One or more of the merge tests failed because you have not fetched the "
"necessary commits. Try fetching from %s first."
msgstr "Une ou plusieurs des tests de fusion ont échoués parce que vous n'avez pas récupéré les commits nécessaires. Essayez de récupéré à partir de %s d'abord."
#: lib/remote_branch_delete.tcl:207
msgid "Please select one or more branches to delete."
msgstr "Merci de sélectionner une ou plusieurs branches à supprimer."
#: lib/remote_branch_delete.tcl:216
msgid ""
"Recovering deleted branches is difficult.\n"
"\n"
"Delete the selected branches?"
msgstr ""
"Récupérer des branches supprimées est difficile.\n"
"\n"
"Souhaitez vous supprimer les branches sélectionnées ?"
#: lib/remote_branch_delete.tcl:226
#, tcl-format
msgid "Deleting branches from %s"
msgstr "Supprimer les branches de %s"
#: lib/remote_branch_delete.tcl:286
msgid "No repository selected."
msgstr "Aucun référentiel n'est sélectionné."
#: lib/remote_branch_delete.tcl:291
#, tcl-format
msgid "Scanning %s..."
msgstr "Synchronisation de %s..."
#: lib/remote.tcl:165
msgid "Prune from"
msgstr "Nettoyer de"
#: lib/remote.tcl:170
msgid "Fetch from"
msgstr "Récupérer de"
#: lib/remote.tcl:213
msgid "Push to"
msgstr "Pousser vers"
#: lib/shortcut.tcl:20 lib/shortcut.tcl:61
msgid "Cannot write shortcut:"
msgstr "Impossible d'écrire le raccourcis :"
#: lib/shortcut.tcl:136
msgid "Cannot write icon:"
msgstr "Impossible d'écrire l'icône :"
#: lib/status_bar.tcl:83
#, tcl-format
msgid "%s ... %*i of %*i %s (%3i%%)"
msgstr "%s ... %*i de %*i %s (%3i%%)"
#: lib/transport.tcl:6
#, tcl-format
msgid "fetch %s"
msgstr "récupérer %s"
#: lib/transport.tcl:7
#, tcl-format
msgid "Fetching new changes from %s"
msgstr "Récupération des dernières modifications de %s"
#: lib/transport.tcl:18
#, tcl-format
msgid "remote prune %s"
msgstr "nettoyer à distance %s"
#: lib/transport.tcl:19
#, tcl-format
msgid "Pruning tracking branches deleted from %s"
msgstr "Nettoyer les branches de suivi supprimées de %s"
#: lib/transport.tcl:25 lib/transport.tcl:71
#, tcl-format
msgid "push %s"
msgstr "pousser %s"
#: lib/transport.tcl:26
#, tcl-format
msgid "Pushing changes to %s"
msgstr "Les modifications sont poussées vers %s"
#: lib/transport.tcl:72
#, tcl-format
msgid "Pushing %s %s to %s"
msgstr "Pousse %s %s vers %s"
#: lib/transport.tcl:89
msgid "Push Branches"
msgstr "Pousser branches"
#: lib/transport.tcl:103
msgid "Source Branches"
msgstr "Branches source"
#: lib/transport.tcl:120
msgid "Destination Repository"
msgstr "Référentiel de destination"
#: lib/transport.tcl:158
msgid "Transfer Options"
msgstr "Transférer options"
#: lib/transport.tcl:160
msgid "Force overwrite existing branch (may discard changes)"
msgstr "Forcer l'écrasement d'une branche existante (peut supprimer des modifications)"
#: lib/transport.tcl:164
msgid "Use thin pack (for slow network connections)"
msgstr "Utiliser des petits paquets (pour les connexions lentes)"
#: lib/transport.tcl:168
msgid "Include tags"
msgstr "Inclure les marques"
^ permalink raw reply [relevance 1%]
* Re: [PATCH] http-push: making HTTP push more robust and more user-friendly
@ 2008-01-19 15:21 2% ` Grégoire Barbier
0 siblings, 0 replies; 200+ results
From: Grégoire Barbier @ 2008-01-19 15:21 UTC (permalink / raw)
To: Junio C Hamano, Johannes Schindelin; +Cc: git, Mike Hommey
Hi Junio, Hi Johannes,
I recently sent three patches about http-push:
> $gmane/70406 <1200250979-19604-1-git-send-email-gb@gbarbier.org>
> $gmane/70407 <1200250979-19604-2-git-send-email-gb@gbarbier.org>
> $gmane/70405 <1200250979-19604-3-git-send-email-gb@gbarbier.org>
I saw that Junio has already applied one of them (the one that disable
http-push without USE_CURL_MULTI).
I wont talk about the second one "fix webdav lock leak" in the present
mail but in another one, since Johannes has found severe bugs in it. I
prefer to make them separate subjects.
As for the third patch ("making HTTP push more robust and more
user-friendly"), I recall the commit message here:
> Grégoire Barbier <gb@gbarbier.org> writes:
> > Fail when info/refs exists and is already locked (avoiding strange
> > behaviour and errors, and maybe avoiding some repository
> > corruption).
> >
> > Warn if the URL does not end with '/' (since 302 is not yet
> > handled)
> >
> > More explicit error message when the URL or password is not set
> > correctly (instead of "no DAV locking support").
> >
> > DAV locking time of 1 minute instead of 10 minutes (avoid waiting
> > 10 minutes for a orphan lock to expire before anyone can do a push
> > on the repo).
I agree that it should be improved seriously in several ways. I will
submit the patch again with following improvements.
1) I will split the patch into several ones, to enable Junio to apply it
partially.
Junio C Hamano a écrit :
> there is no correct timeout that is good for everybody, the last item
> might be contentious.
2) I won't change the timeout to avoid possible side effects for other
things I don't know about since I'm rather new to git.
Johannes Schindelin a écrit :
> This patch makes http-push Warn if URL does not end if "/", but it
> would be even better to just handle it... we know exactly that HTTP
> URLs _must_ end in a slash.
3) Rather than warning if the URL does not end with a slash, I will add
the slash, so that this will work, even without having to handle
HTTP/302 in curl calls. BTW I will do the same for http-fetch either.
Johannes Schindelin a écrit :
> It gives a better warning if the URL cannot be accessed, alright. But
> I hate the fact that it introduces yet another function which does a
> bunch of curl_easy_setopt()s only to start an active slot and check
> for errors.
>
> Currently, I am not familiar enough with http-push.c to suggest a
> proper alternative, but I suspect that the return values of the
> _existing_ calls to curl should know precisely why the requests
> failed, and _this_ should be reported.
Mike Hommey a écrit :
> FWIW, I have a work in progress refactoring the http code, avoiding a
> great amount of curl_easy_setopt()s and simplifying the whole thing.
> It's been sitting on my hard drive during my (quite long) vacation. I
> will probably start working again on this soonish.
4) I agree with Johannes. However I am not familiar enough with curl to
write the proper alternative. I create the new function by copy/paste of
an existing one. I'm not 100% sure that it has no resource leaks or
other bugs, but it's called only once at http-push start, and thus is
likely not to do heavy damage...
As a rationale: I've tried to make several developers use git over http,
including push, and they made all the same beginner mistakes on the
command line, all leading to that stupid error message about locking not
available, and I think that making a clearer error message is an
important improvement to make not-so-skilled developers using git when
neither ssh nor git protocols are available.
Therefore I think that applying my patch, even if it's far from being
perfect, is the lesser of two evils.
Then, for instance during 1.5.5 development cycle, I would be happy to
help Mike if I can, to clean my new code that he is likelly not to have
cleaned up on his hard disk during his vacation...
For instance I may look at his patches and take them in example to clean
up my code.
Apart from the discussion on the source code, I would like to reply to
Junio about the patch disabling http-push without USE_CURL_MULTI:
Junio C Hamano a écrit :
> Also http-push being unusable without CURL_MULTI was also a news to
> me. Is this something that came up on #git perhaps?
>
> This change means people need curl 7.10 or newer (post May 2003, that
> is). I do not think it is too new a version to require, but then it
> makes me wonder if it makes much sense for us to keep supporting non
> CURL_MULTI build these days. Perhaps we should schedule such a move
> to drop non MULTI build in the future?
I don't know if USE_CURL_MULTI works well for other git binaries than
http-push (although I've used it successfully two or three times with
clone and fetch).
If yes, I think that the release notes, or whatever information channel
you can have with the various distribution maintainers, should advice to
compile with USE_CURL_MULTI. Or we can make it the default compilation
option in a future release (> 1.5.4 I think).
If USE_CURL_MULTI is not safe for other binaries than http-push, I think
I should manage to make a new patch, let's say for git-1.5.5, that would
change the makefile to use CURL_MULTI by default on http-push (for
example without -DNEVER_USE_CURL_MULTI) and leave alone other binaries
as they are (CURL_MULTI disabled without -DUSE_CURL_MULTI).
I want to insist that the present patch for 1.5.4 (which you've already
applied to git.git), does not introduce by itself a dependence or a
regression, it only disables unwarned users to call a function that does
not work, but pretends to work and by the way corrupts the remote
repository.
I thank you very much for the time you spent reviewing my patches and
more generally for the work you do. I'll try to improve the way I submit
patches to make them take you less time to review.
--
Grégoire Barbier - gb à gbarbier.org - +33 6 21 35 73 49
^ permalink raw reply [relevance 2%]
* Re: [PATCH] RFC: git lazy clone proof-of-concept
@ 2008-02-08 20:16 4% ` Johannes Schindelin
2 siblings, 0 replies; 200+ results
From: Johannes Schindelin @ 2008-02-08 20:16 UTC (permalink / raw)
To: Jan Holesovsky; +Cc: git, gitster
Hi,
2nd part of my review:
On Fri, 8 Feb 2008, Jan Holesovsky wrote:
> +static void read_from_stdin(int *num, char ***records)
> +{
> + char buffer[4096];
> + size_t records_num, leftover;
> + ssize_t ret;
> +
> + *num = 0;
> + leftover = 0;
> +
> + records_num = 4096;
> + (*records) = xmalloc(records_num * sizeof(char *));
> +
> + do {
> + char *p, *last;
> +
> + ret = xread(0 /*stdin*/, buffer + leftover,
> + sizeof(buffer) - leftover);
> + if (ret < 0)
> + die("read error on input: %s", strerror(errno));
> +
> + last = buffer;
> + for (p = buffer; p < buffer + leftover + ret; p++)
> + if ((!*p || *p == '\n') && (p != last)) {
> + if (*num >= records_num) {
> + records_num *= 2;
> + (*records) = xrealloc(*records,
> + records_num * sizeof(char*));
> + }
> +
> + if (p - last > 0) {
> + (*records)[*num] =
> + strndup(last, p - last);
> + (*num)++;
> + }
> + last = p + 1;
> + }
> + memmove(buffer, last, leftover);
> + } while (ret > 0);
> +
> + if (leftover) {
> + if (*num >= records_num) {
> + records_num *= 2;
> + (*records) = xrealloc(*records,
> + records_num * sizeof(char*));
> + }
> +
> + (*records)[*num] = strndup(buffer, leftover);
> + (*num)++;
> + }
> +}
I thought about this function again. It seems we have something similar
in builtin-pack-objects.c, which is easier to read. The equivalent would
be:
static void read_from_stdin(int *num, char ***records)
{
char line[4096];
int alloc = 0;
*num = 0;
*records = NULL;
for (;;) {
if (!fgets(line, sizeof(line), stdin)) {
if (feof(stdin))
break;
if (!ferror(stdin))
die("fgets returned NULL, not EOF, nor error!");
if (errno != EINTR)
die("fgets: %s", strerror(errno));
clearerr(stdin);
continue;
}
if (!line[0])
continue;
ALLOC_GROW(*records, *num + 1, alloc);
(*records)[(*num)++] = xstrdup(line);
}
}
> diff --git a/git-clone.sh b/git-clone.sh
> index b4e858c..208e9fc 100755
> --- a/git-clone.sh
> +++ b/git-clone.sh
> @@ -115,7 +115,7 @@ Perhaps git-update-server-info needs to be run there?"
> quiet=
> local=no
> use_local_hardlink=yes
> -local_shared=no
> +shared=no
> unset template
> no_checkout=
> upload_pack=
> @@ -143,7 +143,7 @@ do
> --no-hardlinks)
> use_local_hardlink=no ;;
> -s|--shared)
> - local_shared=yes ;;
> + shared=yes ;;
> --template)
> shift; template="--template=$1" ;;
> -q|--quiet)
> @@ -288,7 +288,7 @@ yes)
> ( cd "$repo/objects" ) ||
> die "cannot chdir to local '$repo/objects'."
>
> - if test "$local_shared" = yes
> + if test "$shared" = yes
> then
> mkdir -p "$GIT_DIR/objects/info"
> echo "$repo/objects" >>"$GIT_DIR/objects/info/alternates"
> @@ -364,11 +364,22 @@ yes)
> fi
> ;;
> *)
> + commits_only=
> + if test "$shared" = yes
> + then
> + commits_only="--commits-only"
> + fi
> case "$upload_pack" in
> - '') git-fetch-pack --all -k $quiet $depth $no_progress "$repo";;
> - *) git-fetch-pack --all -k $quiet "$upload_pack" $depth $no_progress "$repo" ;;
> + '') git-fetch-pack --all -k $quiet $depth $no_progress $commits_only "$repo";;
> + *) git-fetch-pack --all -k $quiet "$upload_pack" $depth $no_progress $commits_only "$repo" ;;
> esac >"$GIT_DIR/CLONE_HEAD" ||
> die "fetch-pack from '$repo' failed."
> + if test "$shared" = yes
> + then
> + # Must be done after the fetch
> + mkdir -p "$GIT_DIR/objects/info"
> + echo "$repo" >> "$GIT_DIR/objects/info/remote_alternates"
> + fi
> ;;
> esac
> ;;
Please have a different option than --shared for lazy clones. Maybe
--lazy? ;-)
I can see why you reused --shared, though. But let's make this more
fool-proof: a user should explicitely ask for a lazy clone.
> diff --git a/index-pack.c b/index-pack.c
> index 9fd6982..f2e6b7a 100644
> --- a/index-pack.c
> +++ b/index-pack.c
> @@ -9,7 +9,7 @@
> #include "progress.h"
>
> static const char index_pack_usage[] =
> -"git-index-pack [-v] [-o <index-file>] [{ ---keep | --keep=<msg> }] { <pack-file> | --stdin [--fix-thin] [<pack-file>] }";
> +"git-index-pack [-v] [-o <index-file>] [{ ---keep | --keep=<msg> }] [--ignore-remote-alternates] { <pack-file> | --stdin [--fix-thin] [<pack-file>] }";
>
> struct object_entry
> {
> @@ -746,6 +746,8 @@ int main(int argc, char **argv)
> pack_idx_off32_limit = strtoul(c+1, &c, 0);
> if (*c || pack_idx_off32_limit & 0x80000000)
> die("bad %s", arg);
> + } else if (!strcmp(arg, "--ignore-remote-alternates")) {
> + disable_remote_alternates();
> } else
> usage(index_pack_usage);
> continue;
I might be missing something, but I do not believe this is necessary.
index-pack only works on packs anyway. Am I wrong?
> diff --git a/sha1_file.c b/sha1_file.c
> index 66a4e00..7d60be0 100644
> --- a/sha1_file.c
> +++ b/sha1_file.c
> @@ -14,6 +14,7 @@
> #include "tag.h"
> #include "tree.h"
> #include "refs.h"
> +#include "run-command.h"
>
> #ifndef O_NOATIME
> #if defined(__linux__) && (defined(__i386__) || defined(__PPC__))
> @@ -411,6 +412,205 @@ static char *find_sha1_file(const unsigned char *sha1, struct stat *st)
> return NULL;
> }
>
> +static char *remote_alternates = NULL;
> +static int has_remote_alt_feature = -1;
> +
> +void disable_remote_alternates(void)
> +{
> + has_remote_alt_feature = 0;
> +}
> +
> +static int has_remote_alternates(void)
> +{
> + /* FIXME: does it make sense to support more URLs inside
> + * remote_alternates? */
I think it would make sense. For example if you have a local machine
which has most, but maybe not all, of the remote objects.
> + struct stat st;
> + const char remote_alt_file_name[] = "info/remote_alternates";
<bikeshedding>maybe remote-alternates (note the dash instead
of the underscore)</bikeshedding>
> + char path[PATH_MAX + 1 + sizeof remote_alt_file_name];
> + int fd;
> + char *map, *p;
> + size_t mapsz;
> +
> + if (has_remote_alt_feature != -1)
> + return has_remote_alt_feature;
> +
> + has_remote_alt_feature = 0;
> +
> + sprintf(path, "%s/%s", get_object_directory(),
> + remote_alt_file_name);
> + fd = open(path, O_RDONLY);
> + if (fd < 0)
> + return has_remote_alt_feature;
> + else if (fstat(fd, &st) || (st.st_size == 0)) {
> + close(fd);
> + return has_remote_alt_feature;
> + }
> +
> + mapsz = xsize_t(st.st_size);
> + map = xmmap(NULL, mapsz, PROT_READ, MAP_PRIVATE, fd, 0);
> + close(fd);
> +
> + /* we support just one remote alternate for now,
> + * so read just the first entry */
> + for (p = map; (p < map + mapsz) && (*p != '\n'); p++)
> + ;
> +
> + remote_alternates = strndup(map, p - map);
Seems that you do something like the read_from_stdin() here, only from a
file. It appears to me as if the function wants to be a library function
(taking a FILE * parameter, and maybe closing it after use, or even
taking a filename parameter, which signifies stdin when NULL).
> +struct sha1_list {
> + unsigned char sha1[20];
> + struct sha1_list *next;
> +};
It'd be probably better to make this an array which uses ALLOC_GROW() in
order to avoid memory fragmentation/allocation overhead.
> + memset(&fetch_pack, 0, sizeof(fetch_pack));
> + fetch_pack.in = dump_objects.out;
> + fetch_pack.out = 1;
> + fetch_pack.err = 2;
> + fetch_pack.git_cmd = 1;
> + fetch_pack.argv = argv;
> +
> + err = run_command(&fetch_pack);
> +
> + /* TODO better error handling - is the object really missing, or
> + * was it just a temporary network error? */
> + if (err) {
> + fprintf(stderr, "error %d while calling fetch-pack\n", err);
> + return 0;
That is a
return error("Error %d while calling fetch-pack", err);
And it does not really matter what type of error it is: you must report
the error and continue without this object.
> +static int fill_remote_list(const unsigned char *sha1,
> + const char *base, int baselen,
> + const char *pathname, unsigned mode, int stage)
> +{
> + if (!has_sha1_file_locally(sha1)) {
> + struct sha1_list *item;
> +
> + item = xmalloc(sizeof(*item));
> + hashcpy(item->sha1, sha1);
> + item->next = remote_list;
> +
> + remote_list = item;
> + }
> +
> + return 0;
> +}
> +
> +static int fetch_remote_sha1s_recursive(struct sha1_list *objects)
> +{
> + struct sha1_list *list;
> + int ret = 0;
> +
> + /* first of all, fetch the missing objects */
> + if (!fetch_remote_sha1s(objects))
> + return 0;
> +
> + remote_list = NULL;
> +
> + list = objects;
> + while (list) {
> + struct tree *tree;
> +
> + tree = parse_tree_indirect(list->sha1);
> + if (tree) {
> + read_tree_recursive(tree, "", 0, 0, NULL,
> + fill_remote_list);
> + }
The curly brackets are not necessary. Plus, with fill_remote_list() as
you defined it, it will break down with submodules (see 481f0ee6(Fix
rev-list when showing objects involving submodules) for inspiration).
> +
> + list = list->next;
> + }
> +
> + list = remote_list;
> + if (!list)
> + return 1; /* hooray, we have everything */
> +
> + ret = fetch_remote_sha1s_recursive(list);
This just cries out loud for a non-recursive approach: have two arrays,
clear the second, fetch the objects in the first array, then fill the
second with the objects referred to by the first array's objects. Then
swap the arrays. Loop.
> @@ -2316,6 +2532,18 @@ int has_sha1_file(const unsigned char *sha1)
> return find_sha1_file(sha1, &st) ? 1 : 0;
> }
>
> +int has_sha1_file(const unsigned char *sha1)
> +{
> + if (has_sha1_file_locally(sha1))
> + return 1;
> +
> + /* download it if necessary */
> + if (has_remote_alternates() && download_remote_sha1(sha1))
Maybe it would be nicer to have the has_remote_alternates() check only in
download_remote_sha1()? Same applies to read_sha1_file().
> @@ -106,9 +106,15 @@ static int do_rev_list(int fd, void *create_full_pack)
> if (create_full_pack)
> use_thin_pack = 0; /* no point doing it */
> init_revisions(&revs, NULL);
> - revs.tag_objects = 1;
> - revs.tree_objects = 1;
> - revs.blob_objects = 1;
> + if (!commits_only) {
> + revs.tag_objects = 1;
> + revs.tree_objects = 1;
> + revs.blob_objects = 1;
> + } else {
> + revs.tag_objects = 0;
> + revs.tree_objects = 0;
> + revs.blob_objects = 0;
> + }
Or
revs.tag_objects = revs.tree_objects = revs.blob_objects
= !commits_only;
> @@ -498,9 +525,15 @@ static void receive_needs(void)
> * asks for something like "master~10" (symbolic)...
> * would it make sense? I don't know.
> */
> - o = lookup_object(sha1_buf);
> - if (!o || !(o->flags & OUR_REF))
> - die("git-upload-pack: not our ref %s", line+5);
> + if (!exact_objects) {
> + o = lookup_object(sha1_buf);
> + if (!o || !(o->flags & OUR_REF))
> + die("git-upload-pack: not our ref %s", line+5);
> + } else {
> + o = lookup_unknown_object(sha1_buf);
> + if (!o)
> + die("git-upload-pack: not an object %s", line+5);
> + }
Hmm... AFAICT lookup_unknown_object() does not return NULL. It creates a
"none" object if it did not find anything under that sha1.
I think you'd rather want
o = lookup_object(sha1_buf);
- if (!o || !(o->flags & OUR_REF))
+ if (!o || (!exact_objects && !(o->flags & OUR_REF)))
die("git-upload-pack: not our ref %s", line+5);
Puh. What a big patch! But as I said, it is nice to know somebody is
working on this. (I do not necessarily see possibilities to break it
down into smaller chunks, though.)
But I think that your needs can be satisfied with partial shallow clones,
too: e.g.
$ mkdir my-new-workdir
$ cd my-new-workdir
$ git init
$ git remote add -t master origin <url>
$ git fetch --depth 1 origin
$ git checkout -b master origin/master
I cannot think of a proper place to make this a one-shot command.
As you probably know, I am a strong believer in semantics, so I would hate
"git clone" being taught to not clone the whole repository, but only a
single branch.
But hey, I have been wrong before.
Ciao,
Dscho
^ permalink raw reply [relevance 4%]
* Re: [PATCH] RFC: git lazy clone proof-of-concept
@ 2008-02-11 1:20 4% ` Jakub Narebski
0 siblings, 0 replies; 200+ results
From: Jakub Narebski @ 2008-02-11 1:20 UTC (permalink / raw)
To: Jan Holesovsky; +Cc: git, Junio C Hamano
Hi, Jan!
On Sat, 9 Feb 2008, Jan Holesovsky wrote:
> On Friday 08 February 2008 20:00, Jakub Narebski wrote:
>
>> It was not implemented because it was thought to be hard; git assumes
>> in many places that if it has an object, it has all objects referenced
>> by it.
>>
>> But it is very nice of you to [try to] implement 'lazy clone'/'remote
>> alternates'.
>>
>> Could you provide some benchmarks (time, network throughtput, latency)
>> for your implementation?
>
> Unfortunately not yet :-( The only data I have that clone done on
> git://localhost/ooo.git took 10 minutes without the lazy clone, and 7.5
> minutes with it - and then I sent the patch for review here ;-) The deadline
> for our SVN vs. git comparison for OOo is the next Friday, so I'll definitely
> have some better data by then.
Here perhaps another optimization which wasn't done because git is
fast enough on moderately-sized repositories, namely that IIRC git-clone
(and git-fetch for sure) over native (smart) protocol recreates pack,
even if sometimes better and simplier would be to just copy (transfer)
existing pack.
But this would need multi-pack "extension". (it should work just now
without transport protocol extension, receiver must only be aware
of the need to split resulting pack, and index them all).
>> Both Mozilla import, and GCC import were packed below 0.5 GB. Warning:
>> you would need machine with large amount of memory to repack it
>> tightly in sensible time!
>
> As I answered elsewhere, unfortunately it goes out of memory even on 8G
> machine (x86-64), so... But still trying.
I hope that would work better...
>>> Shallow clone is not a possibility - we don't get patches through
>>> mailing lists, so we need the pull/push, and also thanks to the OOo
>>> development cycle, we have too many living heads which causes the
>>> shallow clone to download about 1.5G even with --depth 1.
>>
>> Wouldn't be easier to try to fix shallow clone implementation to allow
>> for pushing from shallow to full clone (fetching from full to shallow
>> is implemented), and perhaps also push/pull between two shallow
>> clones?
>
> I tried to look into it a bit, but unfortunately did not see a clear way how
> to do it transparently for the user - say you pull a branch that is based off
> a commit you do not have. But of course, I could have missed something ;-)
If I remember correctly fetching _into_ shallow clone works correctly,
as deepening depth of shallow clone. What is not implemented AFAIK, but
should be not too hard would be to allow to push from shallow clone
to full clone. This way the network of full clones (functioning as
centres to publish your work) and shallow + few branches repos (working
repositories).
I don't know if that would be enough.
For better support git would need to exchange graft-like information,
and use union of restrictions to get correct commits.
Perhaps it would be best to mail 'shallow clone' author...
>> As to many living heads: first, you don't need to fetch all
>> heads. Currently git-clone has no option to select subset of heads to
>> clone, but you can always use git-init + hand configuration +
>> git-remote and git-fetch for actual fetching.
>
> Right, might be interesting as well. But still the missing push/pull is
> problematic for us [or at least I see it as a problem ;-)].
You can configure separate 'remote's for the same repository
with different heads. This would work both for pull and for push.
I think the solution proposed by Marco Costalba, namely of creating
"archive" repository, and "live" repository, joining them if needed
by grafts, similarly to how linux kernel has live repo, and historical
import repo, would be good alternative to shallow or lazy clone.
There would be "archive" repo (or repos), read only, with whole history,
very tightly packed with kept packs, with all branches and all tags,
and "live" repo, with only current history (a year, or since major
API change, or from today, or something like that), with only important
branches (or repos, each containg important for a team set of branches).
There would be prepared graft file to join two histories, if you have
to examine full history. Hopefully repo would be smaller.
>> By the way, did you try to split OpenOffice.org repository at the
>> components boundary into submodules (subprojects)? This would also
>> limit amount of needed download, as you don't neeed to download and
>> checkout all subprojects.
>
> Yes, and got to much nicer repositories by that ;-) - by only moving some
> binary stuff out of the CVS to a separate tree. The problem is that the deal
> is to compare the same stuff in SVN and git - so no choice for me in fact.
Sidenote: due to (from what I have read) heavy use of topic branches
in OOo development, Subversion would have to be used with svnmerge
extension, or together with SVK, to make work with it not complete
pain.
In CVS you could have ad-hoc modules, and ad-hoc partial checkouts
(so called 'modules'), but that plays merry hell with whole tree,
atomic, recoverable state commits. In Git you have to plan carefully
boundaries between submodules / subprojects. Additional advantage
is that you would have boundaries more clear, and better modularity
usually leads to better code.
Comparing directly Subversion and Git is a bit stupid: they promote
different workflows. From what I've read Git with its ability to very
easily create branches, with easy _merging_ of branches, and ability
to easily create _private_ branches (testing branches) have much
common witch chosen OOo SCM workflow. Playing to strentghs of
Subversion because that is why you used because of limits of previously
used tools is not smart.
But if you have to, then you have to. Git would hopefully get lazy
clone support from your effort. But perhaps it would be possible
(if additional work) to prepare two repositories: first the same
as Subversion (and same as now in CVS), second one "how it should
be done with Git".
>> The problem of course is _how_ to split repository into
>> submodules. Submodules should be enough self contained so the
>> whole-tree commit is alsays (or almost always) only about submodule.
>
> I hope it will be doable _if_ the git wins & will be chosen for OOo.
I hope that ability to work with submodules (with ability to not
clone / checkout modules if not needed), i.e. "svn:externals
done right" to para[hrase SVN slogan, would be one of reasons to
chose Git over Subversion.
>>> Lazy clone sounded like the right idea to me. With this
>>> proof-of-concept implementation, just about 550M from the 2.5G is
>>> downloaded, which is still about twice as much in comparison with
>>> downloading a tarball, but bearable.
>>
>> Do you have any numbers for OOo repository like number of revisions,
>> depth of DAG of commits (maximum number of revisions in one line of
>> commits), number of files, size of checkout, average size of file,
>> etc.?
>
> I'll try to provide the data ASAP.
For example what is the size of full checkout (all version-control
managed files). Of for example it is 0.5 GB it would be hard to go
to less that 0.5GB or so with pack size, even with compression
of objects themselves in pack file.
Such large repositories, like Mozilla, GCC, or now OpenOffice.org
tests the limits of Git. Perhaps snapshot-based distributed SCMs
cannot deal sensibly with such large projects; I hope this is not
the case.
I wonder if packv4 improvements, which development stalled because
(if I understand correctly) because it didn't brough as much
improvements, and what is now was good enough for up-till-now
projects, would help with OpenOffice.org repository...
P.S. From what I have read OOo uses CVS + some branch DB; does
your importer make use of this branch info database?
--
Jakub Narebski
Poland
^ permalink raw reply [relevance 4%]
* Re: [PATCH] RFC: git lazy clone proof-of-concept
@ 2008-02-14 21:59 5% ` Jakub Narebski
2008-02-14 23:38 4% ` Johannes Schindelin
2008-02-15 9:43 1% ` Jan Holesovsky
0 siblings, 2 replies; 200+ results
From: Jakub Narebski @ 2008-02-14 21:59 UTC (permalink / raw)
To: Johannes Schindelin
Cc: Brandon Casey, Nicolas Pitre, Jan Holesovsky, git, Junio C Hamano,
Brian Downing
Johannes Schindelin wrote:
> On Thu, 14 Feb 2008, Jakub Narebski wrote:
>> Perhaps you could try running contrib/stats/packinfo.pl on this pack to
>> examine it to get to know what takes most space.
>
> $ ~/git/contrib/stats/packinfo.pl < \
> objects/pack/pack-e4dc6da0a10888ec4345490575efc587b7523b45.pack 2>&1 | \
> tee packinfo.txt
> Illegal division by zero at /home/imaging/git/contrib/stats/packinfo.pl
> line 141, <STDIN> line 6330855.
Errr... sorry, I should have been more explicit. What I meant here
is the result of
$ git verify-pack -v <packfile> | \
~/git/contrib/stats/packinfo.pl
>> What is the size of checkout, by the way?
>
> I work on a bare repository, but:
>
> $ git archive origin/master | wc -c
> 2010060800
>
> Or more precisely:
>
> $ echo $(($(git ls-tree -l -r origin/master | sed -n 's/^[^ ]* [^ ]* [^ ]*
> *\([0-9]*\).*$/\1/p' | tr '\012' +)0))
> 1947839459
>
> So yes, we still have the crown of the _whole_ repository being _smaller_
> than a single checkout.
>
> Yeah!
Brandon Casey wrote:
> Jakub Narebski wrote:
>>
>> What is the size of checkout, by the way?
>
> 2.4G
That's huuuuge tree. Compared to that 1.6G (or 1.4G) packfile doesn't
look large.
I wonder if proper subdivision into submodules (which should encourage
better code by the way, see TAOUP), and perhaps partial checkouts
wouldn't be better solution than lazy clone. But it is nice to have
long discussed about feature, even if at RFC stage, but with some code.
--
Jakub Narebski
Poland
^ permalink raw reply [relevance 5%]
* Re: [PATCH] RFC: git lazy clone proof-of-concept
2008-02-14 21:59 5% ` Jakub Narebski
@ 2008-02-14 23:38 4% ` Johannes Schindelin
2008-02-15 1:07 5% ` Jakub Narebski
2008-02-15 9:43 1% ` Jan Holesovsky
1 sibling, 1 reply; 200+ results
From: Johannes Schindelin @ 2008-02-14 23:38 UTC (permalink / raw)
To: Jakub Narebski
Cc: Brandon Casey, Nicolas Pitre, Jan Holesovsky, git, Junio C Hamano,
Brian Downing
Hi,
On Thu, 14 Feb 2008, Jakub Narebski wrote:
> Johannes Schindelin wrote:
> > On Thu, 14 Feb 2008, Jakub Narebski wrote:
>
> >> Perhaps you could try running contrib/stats/packinfo.pl on this pack
> >> to examine it to get to know what takes most space.
> >
> > $ ~/git/contrib/stats/packinfo.pl < \
> > objects/pack/pack-e4dc6da0a10888ec4345490575efc587b7523b45.pack 2>&1 | \
> > tee packinfo.txt
> > Illegal division by zero at /home/imaging/git/contrib/stats/packinfo.pl
> > line 141, <STDIN> line 6330855.
>
> Errr... sorry, I should have been more explicit. What I meant here is
> the result of
>
> $ git verify-pack -v <packfile> | \
> ~/git/contrib/stats/packinfo.pl
Heh. I was too lazy to look up the usage, so I just did what I thought
would make sense...
So here it goes:
$ git verify-pack -v
objects/pack/pack-e4dc6da0a10888ec4345490575efc587b7523b45.pack |
~/git/contrib/stats/packinfo.pl | tee packinfo.txt
all sizes: count 601473 total 2855826280 min 0 max 62173032 mean
4748.05 median 232 std_dev 221254.37
all path sizes: count 601473 total 2855826280 min 0 max 62173032 mean
4748.05 median 232 std_dev 221254.37
tree sizes: count 601473 total 2855826280 min 0 max 62173032 mean
4748.05 median 232 std_dev 221254.37
tree path sizes: count 601473 total 2855826280 min 0 max 62173032 mean
4748.05 median 232 std_dev 221254.37
depths: count 2477715 total 70336238 min 0 max 250 mean 28.39
median 4 std_dev 55.49
Something in my gut tells me that those four repetitive lines are not
meant to look like they do...
> > 2.4G
>
> That's huuuuge tree. Compared to that 1.6G (or 1.4G) packfile doesn't
> look large.
>
> I wonder if proper subdivision into submodules (which should encourage
> better code by the way, see TAOUP), and perhaps partial checkouts
> wouldn't be better solution than lazy clone. But it is nice to have long
> discussed about feature, even if at RFC stage, but with some code.
I think partial checkouts are wrong. If you can work on partial
checkouts, chances are that what you work on should be a submodule.
Having said that, I can understand if some people do not want to have the
hassle of test^H^H^H^Husing submodules...
Ciao,
Dscho
^ permalink raw reply [relevance 4%]
* Re: [PATCH] RFC: git lazy clone proof-of-concept
2008-02-14 23:38 4% ` Johannes Schindelin
@ 2008-02-15 1:07 5% ` Jakub Narebski
0 siblings, 0 replies; 200+ results
From: Jakub Narebski @ 2008-02-15 1:07 UTC (permalink / raw)
To: Johannes Schindelin
Cc: Brandon Casey, Nicolas Pitre, Jan Holesovsky, git, Junio C Hamano,
Brian Downing
Dnia piątek 15. lutego 2008 00:38, Johannes Schindelin napisał:
> Hi,
>
> On Thu, 14 Feb 2008, Jakub Narebski wrote:
>
>> I wonder if proper subdivision into submodules (which should
>> encourage better code by the way, see TAOUP), and perhaps
>> _partial checkouts_ wouldn't be better solution than _lazy clone_.
>> But it is nice to have long discussed about feature, even if at
>> RFC stage, but with some code.
>
> I think partial checkouts are wrong. If you can work on partial
> checkouts, chances are that what you work on should be a submodule.
>
> Having said that, I can understand if some people do not want to have
> the hassle of test^H^H^H^Husing submodules...
IMHO there is place for submodules, there is place for partial
checkouts, and perhaps there is even place for the combination of two.
For example while Documentation/ isn't a good candidate for a submodule,
because as you add new feature yuou want to add to documentation, if
you change some feature you want to change documentation: there are
whole-tree commits which contain changes outside Documentation/.
Nevertheless there are some people (technical writers) which are
interested only in Documentation; perhaps only in few files there.
They would want to have partial checkout, I guess.
On the other hand cgit and msysgit use submodules, and I think it is
good solution. I wonder if Sourcemage Linux distro uses submodules...
In the case of cgit I think having git.git or its clone/fork as
submodule is a good idea, but perhaps even better would be to checkout
only part of it: libgit or libgitthin
--
Jakub Narebski
Poland
^ permalink raw reply [relevance 5%]
* Re: [PATCH] RFC: git lazy clone proof-of-concept
2008-02-14 21:59 5% ` Jakub Narebski
2008-02-14 23:38 4% ` Johannes Schindelin
@ 2008-02-15 9:43 1% ` Jan Holesovsky
1 sibling, 0 replies; 200+ results
From: Jan Holesovsky @ 2008-02-15 9:43 UTC (permalink / raw)
To: Jakub Narebski
Cc: Johannes Schindelin, Brandon Casey, Nicolas Pitre, git,
Junio C Hamano, Brian Downing
Hi Jakub,
On Thursday 14 of February 2008, Jakub Narebski wrote:
> >> What is the size of checkout, by the way?
> >
> > 2.4G
>
> That's huuuuge tree. Compared to that 1.6G (or 1.4G) packfile doesn't
> look large.
>
> I wonder if proper subdivision into submodules (which should encourage
> better code by the way, see TAOUP), and perhaps partial checkouts
> wouldn't be better solution than lazy clone. But it is nice to have
> long discussed about feature, even if at RFC stage, but with some code.
Yes, I'd love to see the OOo tree split into several parts, I've already
proposed a division (http://www.nabble.com/OOo-source-split-td13096065.html),
but it'll take some more time I'm afraid :-(
Regards,
Jan
^ permalink raw reply [relevance 1%]
* What's in git.git (stable)
@ 2008-02-17 3:56 2% ` Junio C Hamano
2008-02-21 4:16 2% ` Junio C Hamano
0 siblings, 1 reply; 200+ results
From: Junio C Hamano @ 2008-02-17 3:56 UTC (permalink / raw)
To: git
I'll hopefully soon apply the RPM spec patch from Kristian
Høgsberg to 'maint' and cut 1.5.4.2. It will have bunch of
config parser related fixes among others.
On the 'master' front, a handful topics have graduated:
- Brian Downing's compat/qsort;
- Crhstian Couder's browser wrapper;
- Paolo Bonzini's prepare-commit-msg hook;
- Steffen Prohaska's safe-crlf;
- "foo/" in .gitignore matches directory "foo".
Also, updated versions of gitk and git-gui are included.
Have fun.
----------------------------------------------------------------
* The 'maint' branch has these fixes since the last announcement.
Christian Couder (8):
config: add test cases for empty value and no value config variables.
diff.c: replace a 'strdup' with 'xstrdup'.
diff.c: remove useless check for value != NULL
config: add 'git_config_string' to refactor string config variables.
Add "const" qualifier to "char *pager_program".
Add "const" qualifier to "char *editor_program".
Add "const" qualifier to "char *excludes_file".
diff.c: add "const" qualifier to "char *cmd" member of "struct
ll_diff_driver"
Daniel Barkalow (1):
Validate nicknames of remote branches to prohibit confusing ones
Gerrit Pape (1):
cvsimport: have default merge regex also match beginning of commit
message
Jay Soffian (1):
mailinfo: feed only one line to handle_filter() for QP input
Jeff King (2):
status: suggest "git rm --cached" to unstage for initial commit
commit: discard index after setting up partial commit
Johannes Schindelin (1):
bisect: use verbatim commit subject in the bisect log
Johannes Sixt (1):
upload-pack: Initialize the exec-path.
Junio C Hamano (6):
Revert "pack-objects: only throw away data during memory pressure"
Protect get_author_ident_from_commit() from filenames in work tree
diff.c: fixup garding of config parser from value=NULL
diff: Fix miscounting of --check output
filter-branch: handle filenames that need quoting
Documentation/git-reset:
Miklos Vajna (1):
git clone -s documentation: force a new paragraph for the NOTE
Pieter de Bie (2):
Documentation/git-reset: don't mention --mixed for selected-paths reset
Documentation/git-reset: Add an example of resetting selected paths
Sergei Organov (1):
git-cvsimport.txt: fix '-M' description.
Shawn O. Pearce (1):
fast-import: check return value from unpack_entry()
Stelian Pop (1):
hg-to-git: fix parent analysis
----------------------------------------------------------------
* The 'master' branch has these since the last announcement
in addition to the above.
Brian Downing (1):
compat: Add simplified merge sort implementation from glibc
Christian Couder (7):
help: make 'git-help--browse' usable outside 'git-help'.
help--browse: add '--config' option to check a config option for a
browser.
Rename 'git-help--browse.sh' to 'git-web--browse.sh'.
instaweb: use 'git-web--browse' to launch browser.
Documentation: instaweb: add 'git-web--browse' information.
web--browse: Add a few quotes in 'init_browser_path'.
Documentation: add 'git-web--browse.txt' and simplify other docs.
Christian Stimming (2):
git-gui: (i18n) Fix a bunch of still untranslated strings.
git-gui: Update German translation.
Dmitry Potapov (1):
git-web--browse: do not start the browser with nohup
Gerrit Pape (1):
gitk: properly deal with tag names containing / (slash)
Jay Soffian (3):
git-gui: support Git Gui.app under OS X 10.5
git-help--browse: improve browser support under OS X
git-web--browse: fix misplaced quote in init_browser_path()
Jeff King (2):
allow suppressing of global and system config
fix config reading in tests
Johan Herland (2):
Add testcase for 'git cvsexportcommit -w $cvsdir ...' with relative
$GIT_DIR
Fix 'git cvsexportcommit -w $cvsdir ...' when used with relative $GIT_DIR
Johannes Schindelin (1):
Adjust .gitignore for 5884f1(Rename 'git-help--browse.sh'...)
Johannes Sixt (1):
gitk: Heed the lines of context in merge commits
Junio C Hamano (7):
Documentation/SubmittingPatches: Instruct how to use [PATCH] Subject
header
Documentation/SubmittingPatches: discuss first then submit
Documentation/SubmittingPatches: What's Acked-by and Tested-by?
gitignore(5): Allow "foo/" in ignore list to match directory "foo"
gitignore: lazily find dtype
.mailmap: adjust to a recent patch application glitch.
Documentation/SubmittingPatches - a suggested patch flow
Linus Torvalds (1):
gitk: learn --show-all output
Michele Ballabio (1):
gitk: Fix "Key bindings" message
Paolo Bonzini (4):
git-commit: support variable number of hook arguments
git-commit: set GIT_EDITOR=: if editor will not be launched
git-commit: Refactor creation of log message.
git-commit: add a prepare-commit-msg hook
Shawn O. Pearce (7):
git-gui: Automatically spell check commit messages as the user types
git-gui: Paper bag fix bad string length call in spellchecker
git-gui: Correct size of dictionary name widget in options dialog
Include annotated tags in fast-import crash reports
Include the fast-import marks table in crash reports
Finish current packfile during fast-import crash handler
Update fast-import documentation to discuss crash reports
Steffen Prohaska (2):
safecrlf: Add mechanism to warn about irreversible crlf conversions
gitk: Add checkbutton to ignore space changes
^ permalink raw reply [relevance 2%]
* [ANNOUNCE] GIT 1.5.4.2
@ 2008-02-17 9:14 2% ` Junio C Hamano
0 siblings, 0 replies; 200+ results
From: Junio C Hamano @ 2008-02-17 9:14 UTC (permalink / raw)
To: git; +Cc: linux-kernel
The latest maintenance release GIT 1.5.4.2 is available at the
usual places:
http://www.kernel.org/pub/software/scm/git/
git-1.5.4.2.tar.{gz,bz2} (tarball)
git-htmldocs-1.5.4.2.tar.{gz,bz2} (preformatted docs)
git-manpages-1.5.4.2.tar.{gz,bz2} (preformatted docs)
RPMS/$arch/git-*-1.5.4.2-1.$arch.rpm (RPM)
----------------------------------------------------------------
GIT v1.5.4.2 Release Notes
==========================
Fixes since v1.5.4
------------------
* The configuration parser was not prepared to see string
valued variables misspelled as boolean and segfaulted.
* Temporary files left behind due to interrupted object
transfers were not cleaned up with "git prune".
* "git config --unset" was confused when the unset variables
were spelled with continuation lines in the config file.
* The merge message detection in "git cvsimport" did not catch
a message that began with "Merge...".
* "git status" suggests "git rm --cached" for unstaging the
earlier "git add" before the initial commit.
* "git status" output was incorrect during a partial commit.
* "git bisect" refused to start when the HEAD was detached.
* "git bisect" allowed a wildcard character in the commit
message expanded while writing its log file.
* Manual pages were not formatted correctly with docbook xsl
1.72; added a workaround.
* "git-commit -C $tag" used to work but rewrite in C done in
1.5.4 broke it. This was fixed in 1.5.4.1.
* An entry in the .gitattributes file that names a pattern in a
subdirectory of the directory it is in did not match
correctly (e.g. pattern "b/*.c" in "a/.gitattributes" should
match "a/b/foo.c" but it didn't). This was fixed in 1.5.4.1.
* Customized color specification was parsed incorrectly when
numeric color values are used. This was fixed in 1.5.4.1.
* http transport misbehaved when linked with curl-gnutls.
----------------------------------------------------------------
Changes since v1.5.4.1 are as follows:
Christian Couder (8):
config: add test cases for empty value and no value config variables.
diff.c: replace a 'strdup' with 'xstrdup'.
diff.c: remove useless check for value != NULL
config: add 'git_config_string' to refactor string config variables.
Add "const" qualifier to "char *pager_program".
Add "const" qualifier to "char *editor_program".
Add "const" qualifier to "char *excludes_file".
diff.c: add "const" qualifier to "char *cmd" member of "struct ll_diff_driver"
Daniel Barkalow (1):
Validate nicknames of remote branches to prohibit confusing ones
David Steven Tweed (1):
Make git prune remove temporary packs that look like write failures
Frank Lichtenheld (1):
config: Fix --unset for continuation lines
Gerrit Pape (2):
builtin-commit: remove .git/SQUASH_MSG upon successful commit
cvsimport: have default merge regex also match beginning of commit message
James Bowes (1):
Add a BuildRequires for gettext in the spec file.
Jay Soffian (1):
mailinfo: feed only one line to handle_filter() for QP input
Jeff King (2):
status: suggest "git rm --cached" to unstage for initial commit
commit: discard index after setting up partial commit
Johannes Schindelin (3):
bisect: allow starting with a detached HEAD
Document that the default of branch.autosetupmerge is true
bisect: use verbatim commit subject in the bisect log
Johannes Sixt (1):
upload-pack: Initialize the exec-path.
Jonas Fonseca (1):
man pages are littered with .ft C and others
Junio C Hamano (31):
git-pull documentation: fix markup
archive-tar.c: guard config parser from value=NULL
Add config_error_nonbool() helper function
builtin-apply.c: guard config parser from value=NULL
builtin-branch.c: guard config parser from value=NULL
builtin-commit.c: guard config parser from value=NULL
builtin-config.c: guard config parser from value=NULL
builtin-log.c: guard config parser from value=NULL
builtin-reflog.c: guard config parser from value=NULL
builtin-show-branch.c: guard config parser from value=NULL
builtin-tag.c: guard config parser from value=NULL
connect.c: guard config parser from value=NULL
convert.c: guard config parser from value=NULL
diff.c: guard config parser from value=NULL
git.c: guard config parser from value=NULL
help.c: guard config parser from value=NULL
http.c: guard config parser from value=NULL
merge-recursive.c: guard config parser from value=NULL
remote.c: guard config parser from value=NULL
setup.c: guard config parser from value=NULL
wt-status.c: guard config parser from value=NULL
imap-send.c: guard config parser from value=NULL
builtin-log.c: guard config parser from value=NULL
config.c: guard config parser from value=NULL
Revert "pack-objects: only throw away data during memory pressure"
Protect get_author_ident_from_commit() from filenames in work tree
diff.c: fixup garding of config parser from value=NULL
diff: Fix miscounting of --check output
filter-branch: handle filenames that need quoting
Documentation/git-reset:
GIT 1.5.4.2
Martin Koegler (1):
pack-objects: only throw away data during memory pressure
Mike Hommey (1):
Work around curl-gnutls not liking to be reinitialized
Miklos Vajna (2):
builtin-gc.c: guard config parser from value=NULL
git clone -s documentation: force a new paragraph for the NOTE
Pieter de Bie (2):
Documentation/git-reset: don't mention --mixed for selected-paths reset
Documentation/git-reset: Add an example of resetting selected paths
Sergei Organov (1):
git-cvsimport.txt: fix '-M' description.
Shawn O. Pearce (1):
fast-import: check return value from unpack_entry()
Stelian Pop (1):
hg-to-git: fix parent analysis
Uwe Kleine-K旦nig (1):
rebase -i: accept -m as advertised in the man page
^ permalink raw reply [relevance 2%]
* What's in git.git (stable)
2008-02-17 3:56 2% ` What's in git.git (stable) Junio C Hamano
@ 2008-02-21 4:16 2% ` Junio C Hamano
0 siblings, 0 replies; 200+ results
From: Junio C Hamano @ 2008-02-21 4:16 UTC (permalink / raw)
To: git
With a handful of fixes and RPM specfile updates, we would
probably want to do 1.5.4.3 in a week or so from 'maint'.
A handful of new topics are now on 'master', and the ones still
on 'next' are maturing with necessary fixes. I think we have
enough material for 1.5.5 when they graduate, and I am hoping to
do an rc1 sometime early to mid next month. We'll see.
* The 'maint' branch has these fixes since the last announcement.
Gerrit Pape (1):
git-clone.sh: properly configure remote even if remote's head is dangling
Jay Soffian (1):
send-email: squelch warning due to comparing undefined $_ to ""
Jeff King (3):
push: indicate partialness of error message
Documentation/push: clarify matching refspec behavior
push: document the status output
Junio C Hamano (1):
GIT 1.5.4.2
Kristian Høgsberg (1):
Rename git-core rpm to just git and rename the meta-pacakge to git-all.
Miklos Vajna (1):
Documentation/git-stash: document options for git stash list
Pekka Kaitaniemi (1):
Clarified the meaning of git-add -u in the documentation
* The 'master' branch has these since the last announcement
in addition to the above.
Brandon Casey (1):
Add compat/fopen.c which returns NULL on attempt to open directory
Bruno Ribas (1):
gitweb: Use the config file to set repository owner's name.
Christian Couder (1):
help.c: use 'git_config_string' to get 'help_default_format'.
Daniel Barkalow (1):
API documentation for remote.h
David Kågedal (1):
git.el: Set process-environment instead of invoking env
Jakub Narebski (3):
gitweb: Fix displaying unchopped argument in chop_and_escape_str
gitweb: Add new option -nohtml to quot_xxx subroutines
gitweb: Fix bug in href(..., -replay=>1) when using 'pathinfo' form
Jay Soffian (1):
Correct git-pull documentation
Jeff King (2):
hard-code the empty tree object
add--interactive: handle initial commit better
Johannes Schindelin (5):
http-push: avoid invalid memory accesses
http-push: do not get confused by submodules
http-push: avoid a needless goto
bisect view: check for MinGW32 and MacOSX in addition to X11
cvsexportcommit: be graceful when "cvs status" reorders the arguments
Johannes Sixt (1):
Technical documentation of the run-command API.
Junio C Hamano (5):
setup: sanitize absolute and funny paths in get_pathspec()
git-add: adjust to the get_pathspec() changes.
builtin-mv: minimum fix to avoid losing files
Sync with 1.5.4.2 and start 1.5.5 Release Notes
sending errors to stdout under $PAGER
Lars Hjemli (1):
Simplify setup of $GIT_DIR in git-sh-setup.sh
Linus Torvalds (1):
Add "--show-all" revision walker flag for debugging
Marco Costalba (1):
Avoid a useless prefix lookup in strbuf_expand()
Martin Koegler (15):
deref_tag: handle return value NULL
deref_tag: handle tag->tagged = NULL
check return code of prepare_revision_walk
read_object_with_reference: don't read beyond the buffer
get_sha1_oneline: check return value of parse_object
mark_blob/tree_uninteresting: check for NULL
reachable.c::add_one_tree: handle NULL from lookup_tree
list-objects.c::process_tree/blob: check for NULL
check results of parse_commit in merge_bases
process_tag: handle tag->tagged == NULL
reachable.c::process_tree/blob: check for NULL
revision.c: handle tag->tagged == NULL
parse_commit: don't fail, if object is NULL
check return value from parse_commit() in various functions
peel_onion: handle NULL
Matthias Kestenholz (1):
Add color.ui variable which globally enables colorization if set
Robin Rosenberg (1):
Make blame accept absolute paths
^ permalink raw reply [relevance 2%]
* Re: [PATCH 0/3] solaris test results
@ 2008-02-22 5:26 1% ` Junio C Hamano
0 siblings, 0 replies; 200+ results
From: Junio C Hamano @ 2008-02-22 5:26 UTC (permalink / raw)
To: Jeff King; +Cc: Whit Armstrong, git
Jeff King <peff@peff.net> writes:
> On Wed, Feb 20, 2008 at 04:34:25PM -0800, Junio C Hamano wrote:
>
>> > - Sun's diff doesn't understand "-u". I was able to use GNU diff.
>> > Since comparing actual and expected output is so common, we could
>> > potentially abstract this with a "test_cmp()" function and use
>> > something platform specific. It's probably not worth the trouble, as
>> > it impacts only the test suite, and only on systems with a totally
>> > broken diff.
>>
>> It is unfair to call diff without -u "totally broken". It is
>> not even in POSIX yet IIRC.
>
> Fair enough (and you are right that it is not even POSIX). Is it
> something we want to work around? We "diff -u" quite a bit in the test
> suite.
Here is a possible solution.
This is a fairly mechanical substitution (grepping for "git diff -u"
and "diff -u", and replacing them with test_compare_expect.
Some tests get the order of comparison wrong (should always be
"diff expect current" to make the error stand out in -v output),
but I did not update them. That would be for later rounds,
perhaps, if we decide to do this.
-- >8 --
Subject: [PATCH] tests: test_compare_expect helper function
We tend to use "diff -u" for comparing expected output from
actual, but diff on some platforms lack "-u" (it is not in POSIX
yet).
This mechanically replaces "diff -u expected actual" with
test_compare_expect helper function.
Test scripts can be run with --no-diff-u option, to use "git
diff -u --no-index" for comparison instead.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
t/t0003-attributes.sh | 2 +-
t/t0022-crlf-rename.sh | 2 +-
t/t1300-repo-config.sh | 2 +-
t/t2200-add-update.sh | 2 +-
t/t3001-ls-files-others-exclude.sh | 2 +-
t/t3030-merge-recursive.sh | 42 ++++++++++++++++++------------------
t/t3050-subprojects-fetch.sh | 4 +-
t/t3060-ls-files-with-tree.sh | 2 +-
t/t3201-branch-contains.sh | 6 ++--
t/t3404-rebase-interactive.sh | 4 +-
t/t3405-rebase-malformed.sh | 4 +-
t/t3406-rebase-message.sh | 2 +-
t/t3701-add-interactive.sh | 4 +-
t/t3902-quoted.sh | 16 ++++++------
t/t3903-stash.sh | 2 +-
t/t4023-diff-rename-typechange.sh | 6 ++--
t/t4024-diff-optimize-common.sh | 2 +-
| 2 +-
t/t4201-shortlog.sh | 2 +-
t/t5505-remote.sh | 6 ++--
t/t5510-fetch.sh | 2 +-
t/t5512-ls-remote.sh | 8 +++---
t/t5515-fetch-merge-logic.sh | 2 +-
t/t6004-rev-list-path-optim.sh | 2 +-
t/t6009-rev-list-parent.sh | 2 +-
t/t6027-merge-binary.sh | 4 +-
t/t7010-setup.sh | 18 +++++++-------
t/t7501-commit.sh | 14 ++++++------
t/t7502-commit.sh | 14 ++++++------
t/t7502-status.sh | 2 +-
t/t7600-merge.sh | 2 +-
t/t8003-blame.sh | 4 +-
t/t9001-send-email.sh | 2 +-
t/t9116-git-svn-log.sh | 24 ++++++++++----------
t/t9200-git-cvsexportcommit.sh | 14 ++++++------
t/t9300-fast-import.sh | 2 +-
t/test-lib.sh | 27 +++++++++++++++++++++++
37 files changed, 142 insertions(+), 115 deletions(-)
diff --git a/t/t0003-attributes.sh b/t/t0003-attributes.sh
index 47f08a4..8d85acb 100755
--- a/t/t0003-attributes.sh
+++ b/t/t0003-attributes.sh
@@ -11,7 +11,7 @@ attr_check () {
git check-attr test -- "$path" >actual &&
echo "$path: test: $2" >expect &&
- diff -u expect actual
+ test_compare_expect expect actual
}
diff --git a/t/t0022-crlf-rename.sh b/t/t0022-crlf-rename.sh
index 430a1d1..651ce2f 100755
--- a/t/t0022-crlf-rename.sh
+++ b/t/t0022-crlf-rename.sh
@@ -26,7 +26,7 @@ test_expect_success 'diff -M' '
git diff-tree -M -r --name-status HEAD^ HEAD |
sed -e "s/R[0-9]*/RNUM/" >actual &&
echo "RNUM sample elpmas" >expect &&
- diff -u expect actual
+ test_compare_expect expect actual
'
diff --git a/t/t1300-repo-config.sh b/t/t1300-repo-config.sh
index 4928a57..e0e95ce 100755
--- a/t/t1300-repo-config.sh
+++ b/t/t1300-repo-config.sh
@@ -465,7 +465,7 @@ weird
EOF
test_expect_success "section was removed properly" \
- "git diff -u expect .git/config"
+ "test_compare_expect expect .git/config"
rm .git/config
diff --git a/t/t2200-add-update.sh b/t/t2200-add-update.sh
index 24f892f..75abda1 100755
--- a/t/t2200-add-update.sh
+++ b/t/t2200-add-update.sh
@@ -62,7 +62,7 @@ test_expect_success 'cache tree has not been corrupted' '
sed -e "s/ 0 / /" >expect &&
git ls-tree -r $(git write-tree) |
sed -e "s/ blob / /" >current &&
- diff -u expect current
+ test_compare_expect expect current
'
diff --git a/t/t3001-ls-files-others-exclude.sh b/t/t3001-ls-files-others-exclude.sh
index b4297ba..0b9d2ea 100755
--- a/t/t3001-ls-files-others-exclude.sh
+++ b/t/t3001-ls-files-others-exclude.sh
@@ -97,7 +97,7 @@ cat > expect << EOF
EOF
test_expect_success 'git-status honours core.excludesfile' \
- 'diff -u expect output'
+ 'test_compare_expect expect output'
test_expect_success 'trailing slash in exclude allows directory match(1)' '
diff --git a/t/t3030-merge-recursive.sh b/t/t3030-merge-recursive.sh
index 607f57f..edfdbfd 100755
--- a/t/t3030-merge-recursive.sh
+++ b/t/t3030-merge-recursive.sh
@@ -43,7 +43,7 @@ test_expect_success 'setup 1' '
echo "100644 $o0 0 c"
echo "100644 $o1 0 d/e"
) >expected &&
- git diff -u expected actual
+ test_compare_expect expected actual
'
test_expect_success 'setup 2' '
@@ -61,7 +61,7 @@ test_expect_success 'setup 2' '
echo "100644 $o0 0 c"
echo "100644 $o0 0 d/e"
) >expected &&
- git diff -u expected actual &&
+ test_compare_expect expected actual &&
echo goodbye >>a &&
o2=$(git hash-object a) &&
@@ -82,7 +82,7 @@ test_expect_success 'setup 2' '
echo "100644 $o0 0 c"
echo "100644 $o0 0 d/e"
) >expected &&
- git diff -u expected actual
+ test_compare_expect expected actual
'
test_expect_success 'setup 3' '
@@ -100,7 +100,7 @@ test_expect_success 'setup 3' '
echo "100644 $o0 0 c"
echo "100644 $o0 0 d/e"
) >expected &&
- git diff -u expected actual &&
+ test_compare_expect expected actual &&
rm -f b && mkdir b && echo df-1 >b/c && git add b/c &&
o3=$(git hash-object b/c) &&
@@ -119,7 +119,7 @@ test_expect_success 'setup 3' '
echo "100644 $o0 0 c"
echo "100644 $o0 0 d/e"
) >expected &&
- git diff -u expected actual
+ test_compare_expect expected actual
'
test_expect_success 'setup 4' '
@@ -137,7 +137,7 @@ test_expect_success 'setup 4' '
echo "100644 $o0 0 c"
echo "100644 $o0 0 d/e"
) >expected &&
- git diff -u expected actual &&
+ test_compare_expect expected actual &&
rm -f a && mkdir a && echo df-2 >a/c && git add a/c &&
o4=$(git hash-object a/c) &&
@@ -156,7 +156,7 @@ test_expect_success 'setup 4' '
echo "100644 $o0 0 c"
echo "100644 $o0 0 d/e"
) >expected &&
- git diff -u expected actual
+ test_compare_expect expected actual
'
test_expect_success 'setup 5' '
@@ -174,7 +174,7 @@ test_expect_success 'setup 5' '
echo "100644 $o0 0 c"
echo "100644 $o0 0 d/e"
) >expected &&
- git diff -u expected actual &&
+ test_compare_expect expected actual &&
rm -f b &&
echo remove-conflict >a &&
@@ -195,7 +195,7 @@ test_expect_success 'setup 5' '
echo "100644 $o0 0 c"
echo "100644 $o0 0 d/e"
) >expected &&
- git diff -u expected actual
+ test_compare_expect expected actual
'
@@ -214,7 +214,7 @@ test_expect_success 'setup 6' '
echo "100644 $o0 0 c"
echo "100644 $o0 0 d/e"
) >expected &&
- git diff -u expected actual &&
+ test_compare_expect expected actual &&
rm -fr d && echo df-3 >d && git add d &&
o6=$(git hash-object d) &&
@@ -233,7 +233,7 @@ test_expect_success 'setup 6' '
echo "100644 $o0 0 c"
echo "100644 $o6 0 d"
) >expected &&
- git diff -u expected actual
+ test_compare_expect expected actual
'
test_expect_success 'merge-recursive simple' '
@@ -265,7 +265,7 @@ test_expect_success 'merge-recursive result' '
echo "100644 $o0 0 c"
echo "100644 $o1 0 d/e"
) >expected &&
- git diff -u expected actual
+ test_compare_expect expected actual
'
@@ -297,7 +297,7 @@ test_expect_success 'merge-recursive remove conflict' '
echo "100644 $o0 0 c"
echo "100644 $o1 0 d/e"
) >expected &&
- git diff -u expected actual
+ test_compare_expect expected actual
'
@@ -318,7 +318,7 @@ test_expect_success 'merge-recursive result' '
echo "100644 $o0 0 c"
echo "100644 $o1 0 d/e"
) >expected &&
- git diff -u expected actual
+ test_compare_expect expected actual
'
@@ -352,7 +352,7 @@ test_expect_success 'merge-recursive d/f conflict result' '
echo "100644 $o0 0 c"
echo "100644 $o1 0 d/e"
) >expected &&
- git diff -u expected actual
+ test_compare_expect expected actual
'
@@ -386,7 +386,7 @@ test_expect_success 'merge-recursive d/f conflict result the other way' '
echo "100644 $o0 0 c"
echo "100644 $o1 0 d/e"
) >expected &&
- git diff -u expected actual
+ test_compare_expect expected actual
'
@@ -420,7 +420,7 @@ test_expect_success 'merge-recursive d/f conflict result' '
echo "100644 $o0 1 d/e"
echo "100644 $o1 2 d/e"
) >expected &&
- git diff -u expected actual
+ test_compare_expect expected actual
'
@@ -454,7 +454,7 @@ test_expect_success 'merge-recursive d/f conflict result' '
echo "100644 $o0 1 d/e"
echo "100644 $o1 3 d/e"
) >expected &&
- git diff -u expected actual
+ test_compare_expect expected actual
'
@@ -480,7 +480,7 @@ test_expect_success 'reset and bind merge' '
echo "100644 $o0 0 c"
echo "100644 $o1 0 d/e"
) >expected &&
- git diff -u expected actual &&
+ test_compare_expect expected actual &&
git read-tree --prefix=a1/ master &&
git ls-files -s >actual &&
@@ -498,7 +498,7 @@ test_expect_success 'reset and bind merge' '
echo "100644 $o0 0 c"
echo "100644 $o1 0 d/e"
) >expected &&
- git diff -u expected actual
+ test_compare_expect expected actual
git read-tree --prefix=z/ master &&
git ls-files -s >actual &&
@@ -520,7 +520,7 @@ test_expect_success 'reset and bind merge' '
echo "100644 $o0 0 z/c"
echo "100644 $o1 0 z/d/e"
) >expected &&
- git diff -u expected actual
+ test_compare_expect expected actual
'
diff --git a/t/t3050-subprojects-fetch.sh b/t/t3050-subprojects-fetch.sh
index 34f26a8..15fbdf3 100755
--- a/t/t3050-subprojects-fetch.sh
+++ b/t/t3050-subprojects-fetch.sh
@@ -26,7 +26,7 @@ test_expect_success clone '
cd cloned &&
(git rev-parse HEAD; git ls-files -s) >../actual
) &&
- diff -u expected actual
+ test_compare_expect expected actual
'
test_expect_success advance '
@@ -46,7 +46,7 @@ test_expect_success fetch '
git pull &&
(git rev-parse HEAD; git ls-files -s) >../actual
) &&
- diff -u expected actual
+ test_compare_expect expected actual
'
test_done
diff --git a/t/t3060-ls-files-with-tree.sh b/t/t3060-ls-files-with-tree.sh
index 68eb266..ece38d0 100755
--- a/t/t3060-ls-files-with-tree.sh
+++ b/t/t3060-ls-files-with-tree.sh
@@ -66,6 +66,6 @@ test_expect_success 'git -ls-files --with-tree should succeed from subdir' '
cd ..
test_expect_success \
'git -ls-files --with-tree should add entries from named tree.' \
- 'diff -u expected output'
+ 'test_compare_expect expected output'
test_done
diff --git a/t/t3201-branch-contains.sh b/t/t3201-branch-contains.sh
index 9ef593f..a711f54 100755
--- a/t/t3201-branch-contains.sh
+++ b/t/t3201-branch-contains.sh
@@ -31,7 +31,7 @@ test_expect_success 'branch --contains=master' '
{
echo " master" && echo "* side"
} >expect &&
- diff -u expect actual
+ test_compare_expect expect actual
'
@@ -41,7 +41,7 @@ test_expect_success 'branch --contains master' '
{
echo " master" && echo "* side"
} >expect &&
- diff -u expect actual
+ test_compare_expect expect actual
'
@@ -51,7 +51,7 @@ test_expect_success 'branch --contains=side' '
{
echo "* side"
} >expect &&
- diff -u expect actual
+ test_compare_expect expect actual
'
diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh
index 62e65d7..76927f8 100755
--- a/t/t3404-rebase-interactive.sh
+++ b/t/t3404-rebase-interactive.sh
@@ -146,8 +146,8 @@ EOF
test_expect_success 'stop on conflicting pick' '
git tag new-branch1 &&
! git rebase -i master &&
- diff -u expect .git/.dotest-merge/patch &&
- diff -u expect2 file1 &&
+ test_compare_expect expect .git/.dotest-merge/patch &&
+ test_compare_expect expect2 file1 &&
test 4 = $(grep -v "^#" < .git/.dotest-merge/done | wc -l) &&
test 0 = $(grep -ve "^#" -e "^$" < .git/.dotest-merge/git-rebase-todo |
wc -l)
diff --git a/t/t3405-rebase-malformed.sh b/t/t3405-rebase-malformed.sh
index e4e2e64..8bb412e 100755
--- a/t/t3405-rebase-malformed.sh
+++ b/t/t3405-rebase-malformed.sh
@@ -41,8 +41,8 @@ test_expect_success rebase '
git rebase master side &&
git cat-file commit HEAD | sed -e "1,/^\$/d" >F1 &&
- diff -u F0 F1 &&
- diff -u F F0
+ test_compare_expect F0 F1 &&
+ test_compare_expect F F0
'
test_done
diff --git a/t/t3406-rebase-message.sh b/t/t3406-rebase-message.sh
index 332b2b2..9753939 100755
--- a/t/t3406-rebase-message.sh
+++ b/t/t3406-rebase-message.sh
@@ -37,7 +37,7 @@ test_expect_success 'rebase -m' '
git rebase -m master >report &&
sed -n -e "/^Already applied: /p" \
-e "/^Committed: /p" report >actual &&
- diff -u expect actual
+ test_compare_expect expect actual
'
diff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh
index c8dc1ac..1bb2aae 100755
--- a/t/t3701-add-interactive.sh
+++ b/t/t3701-add-interactive.sh
@@ -24,7 +24,7 @@ EOF
test_expect_success 'diff works (initial)' '
(echo d; echo 1) | git add -i >output &&
sed -ne "/new file/,/content/p" <output >diff &&
- diff -u expected diff
+ test_compare_expect expected diff
'
test_expect_success 'revert works (initial)' '
git add file &&
@@ -57,7 +57,7 @@ EOF
test_expect_success 'diff works (commit)' '
(echo d; echo 1) | git add -i >output &&
sed -ne "/^index/,/content/p" <output >diff &&
- diff -u expected diff
+ test_compare_expect expected diff
'
test_expect_success 'revert works (commit)' '
git add file &&
diff --git a/t/t3902-quoted.sh b/t/t3902-quoted.sh
index 73da45f..02eb9ff 100755
--- a/t/t3902-quoted.sh
+++ b/t/t3902-quoted.sh
@@ -78,28 +78,28 @@ EOF
test_expect_success 'check fully quoted output from ls-files' '
- git ls-files >current && diff -u expect.quoted current
+ git ls-files >current && test_compare_expect expect.quoted current
'
test_expect_success 'check fully quoted output from diff-files' '
git diff --name-only >current &&
- diff -u expect.quoted current
+ test_compare_expect expect.quoted current
'
test_expect_success 'check fully quoted output from diff-index' '
git diff --name-only HEAD >current &&
- diff -u expect.quoted current
+ test_compare_expect expect.quoted current
'
test_expect_success 'check fully quoted output from diff-tree' '
git diff --name-only HEAD^ HEAD >current &&
- diff -u expect.quoted current
+ test_compare_expect expect.quoted current
'
@@ -111,28 +111,28 @@ test_expect_success 'setting core.quotepath' '
test_expect_success 'check fully quoted output from ls-files' '
- git ls-files >current && diff -u expect.raw current
+ git ls-files >current && test_compare_expect expect.raw current
'
test_expect_success 'check fully quoted output from diff-files' '
git diff --name-only >current &&
- diff -u expect.raw current
+ test_compare_expect expect.raw current
'
test_expect_success 'check fully quoted output from diff-index' '
git diff --name-only HEAD >current &&
- diff -u expect.raw current
+ test_compare_expect expect.raw current
'
test_expect_success 'check fully quoted output from diff-tree' '
git diff --name-only HEAD^ HEAD >current &&
- diff -u expect.raw current
+ test_compare_expect expect.raw current
'
diff --git a/t/t3903-stash.sh b/t/t3903-stash.sh
index 9a9a250..4f5e579 100755
--- a/t/t3903-stash.sh
+++ b/t/t3903-stash.sh
@@ -34,7 +34,7 @@ EOF
test_expect_success 'parents of stash' '
test $(git rev-parse stash^) = $(git rev-parse HEAD) &&
git diff stash^2..stash > output &&
- diff -u output expect
+ test_compare_expect output expect
'
test_expect_success 'apply needs clean working directory' '
diff --git a/t/t4023-diff-rename-typechange.sh b/t/t4023-diff-rename-typechange.sh
index 255604e..177e78a 100755
--- a/t/t4023-diff-rename-typechange.sh
+++ b/t/t4023-diff-rename-typechange.sh
@@ -57,7 +57,7 @@ test_expect_success 'cross renames to be detected for regular files' '
echo "R100 foo bar"
echo "R100 bar foo"
} | sort >expect &&
- diff -u expect actual
+ test_compare_expect expect actual
'
@@ -68,7 +68,7 @@ test_expect_success 'cross renames to be detected for typechange' '
echo "R100 foo bar"
echo "R100 bar foo"
} | sort >expect &&
- diff -u expect actual
+ test_compare_expect expect actual
'
@@ -79,7 +79,7 @@ test_expect_success 'moves and renames' '
echo "R100 foo bar"
echo "T100 foo"
} | sort >expect &&
- diff -u expect actual
+ test_compare_expect expect actual
'
diff --git a/t/t4024-diff-optimize-common.sh b/t/t4024-diff-optimize-common.sh
index 3c66102..318ce54 100755
--- a/t/t4024-diff-optimize-common.sh
+++ b/t/t4024-diff-optimize-common.sh
@@ -150,7 +150,7 @@ test_expect_success 'diff -U0' '
do
git diff -U0 file-?$n
done | zc >actual &&
- diff -u expect actual
+ test_compare_expect expect actual
'
--git a/t/t4025-hunk-header.sh b/t/t4025-hunk-header.sh
index 9ba06b7..542bf30 100755
--- a/t/t4025-hunk-header.sh
+++ b/t/t4025-hunk-header.sh
@@ -37,7 +37,7 @@ test_expect_success 'hunk header truncation with an overly long line' '
echo " A $N$N$N$N$N$N$N$N$N2"
echo " L $N$N$N$N$N$N$N$N$N1"
) >expected &&
- diff -u actual expected
+ test_compare_expect actual expected
'
diff --git a/t/t4201-shortlog.sh b/t/t4201-shortlog.sh
index 6d12efb..f9859bc 100755
--- a/t/t4201-shortlog.sh
+++ b/t/t4201-shortlog.sh
@@ -45,6 +45,6 @@ A U Thor (5):
EOF
-test_expect_success 'shortlog wrapping' 'diff -u expect out'
+test_expect_success 'shortlog wrapping' 'test_compare_expect expect out'
test_done
diff --git a/t/t5505-remote.sh b/t/t5505-remote.sh
index 636aec2..cf20ec4 100755
--- a/t/t5505-remote.sh
+++ b/t/t5505-remote.sh
@@ -25,7 +25,7 @@ setup_repository () {
tokens_match () {
echo "$1" | tr ' ' '\012' | sort | sed -e '/^$/d' >expect &&
echo "$2" | tr ' ' '\012' | sort | sed -e '/^$/d' >actual &&
- diff -u expect actual
+ test_compare_expect expect actual
}
check_remote_track () {
@@ -74,7 +74,7 @@ test_expect_success 'add another remote' '
sed -e "/^refs\/remotes\/origin\//d" \
-e "/^refs\/remotes\/second\//d" >actual &&
>expect &&
- diff -u expect actual
+ test_compare_expect expect actual
)
'
@@ -93,7 +93,7 @@ test_expect_success 'remove remote' '
git for-each-ref "--format=%(refname)" refs/remotes |
sed -e "/^refs\/remotes\/origin\//d" >actual &&
>expect &&
- diff -u expect actual
+ test_compare_expect expect actual
)
'
diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh
index 9b948c1..17add89 100755
--- a/t/t5510-fetch.sh
+++ b/t/t5510-fetch.sh
@@ -249,7 +249,7 @@ test_expect_success 'bundle should record HEAD correctly' '
do
echo "$(git rev-parse --verify $h) $h"
done >expect &&
- diff -u expect actual
+ test_compare_expect expect actual
'
diff --git a/t/t5512-ls-remote.sh b/t/t5512-ls-remote.sh
index 6ec5f7c..60def72 100755
--- a/t/t5512-ls-remote.sh
+++ b/t/t5512-ls-remote.sh
@@ -24,28 +24,28 @@ test_expect_success setup '
test_expect_success 'ls-remote --tags .git' '
git ls-remote --tags .git >actual &&
- diff -u expected.tag actual
+ test_compare_expect expected.tag actual
'
test_expect_success 'ls-remote .git' '
git ls-remote .git >actual &&
- diff -u expected.all actual
+ test_compare_expect expected.all actual
'
test_expect_success 'ls-remote --tags self' '
git ls-remote --tags self >actual &&
- diff -u expected.tag actual
+ test_compare_expect expected.tag actual
'
test_expect_success 'ls-remote self' '
git ls-remote self >actual &&
- diff -u expected.all actual
+ test_compare_expect expected.all actual
'
diff --git a/t/t5515-fetch-merge-logic.sh b/t/t5515-fetch-merge-logic.sh
index 31c1081..85ff226 100755
--- a/t/t5515-fetch-merge-logic.sh
+++ b/t/t5515-fetch-merge-logic.sh
@@ -148,7 +148,7 @@ do
} >"$actual" &&
if test -f "$expect"
then
- git diff -u "$expect" "$actual" &&
+ test_compare_expect "$expect" "$actual" &&
rm -f "$actual"
else
# this is to help developing new tests.
diff --git a/t/t6004-rev-list-path-optim.sh b/t/t6004-rev-list-path-optim.sh
index 80d7198..0624cc4 100755
--- a/t/t6004-rev-list-path-optim.sh
+++ b/t/t6004-rev-list-path-optim.sh
@@ -45,7 +45,7 @@ test_expect_success 'further setup' '
test_expect_success 'path optimization 2' '
( echo "$side"; echo "$initial" ) >expected &&
git rev-list HEAD -- a >actual &&
- diff -u expected actual
+ test_compare_expect expected actual
'
test_done
diff --git a/t/t6009-rev-list-parent.sh b/t/t6009-rev-list-parent.sh
index be3d238..763934a 100755
--- a/t/t6009-rev-list-parent.sh
+++ b/t/t6009-rev-list-parent.sh
@@ -31,7 +31,7 @@ test_expect_failure 'one is ancestor of others and should not be shown' '
git rev-list one --not four >result &&
>expect &&
- diff -u expect result
+ test_compare_expect expect result
'
diff --git a/t/t6027-merge-binary.sh b/t/t6027-merge-binary.sh
index a7358f7..0731022 100755
--- a/t/t6027-merge-binary.sh
+++ b/t/t6027-merge-binary.sh
@@ -45,7 +45,7 @@ test_expect_success resolve '
false
else
git ls-files -s >current
- diff -u current expect
+ test_compare_expect current expect
fi
'
@@ -60,7 +60,7 @@ test_expect_success recursive '
false
else
git ls-files -s >current
- diff -u current expect
+ test_compare_expect current expect
fi
'
diff --git a/t/t7010-setup.sh b/t/t7010-setup.sh
index e809e0e..8351841 100755
--- a/t/t7010-setup.sh
+++ b/t/t7010-setup.sh
@@ -18,7 +18,7 @@ test_expect_success 'git add (absolute)' '
git add "$D/a/b/c/d" &&
git ls-files >current &&
echo a/b/c/d >expect &&
- diff -u expect current
+ test_compare_expect expect current
'
@@ -32,7 +32,7 @@ test_expect_success 'git add (funny relative)' '
) &&
git ls-files >current &&
echo a/e/f >expect &&
- diff -u expect current
+ test_compare_expect expect current
'
@@ -43,7 +43,7 @@ test_expect_success 'git rm (absolute)' '
git rm -f --cached "$D/a/b/c/d" &&
git ls-files >current &&
echo a/e/f >expect &&
- diff -u expect current
+ test_compare_expect expect current
'
@@ -57,7 +57,7 @@ test_expect_success 'git rm (funny relative)' '
) &&
git ls-files >current &&
echo a/b/c/d >expect &&
- diff -u expect current
+ test_compare_expect expect current
'
@@ -67,7 +67,7 @@ test_expect_success 'git ls-files (absolute)' '
git add a &&
git ls-files "$D/a/e/../b" >current &&
echo a/b/c/d >expect &&
- diff -u expect current
+ test_compare_expect expect current
'
@@ -80,7 +80,7 @@ test_expect_success 'git ls-files (relative #1)' '
git ls-files "../b/c"
) >current &&
echo c/d >expect &&
- diff -u expect current
+ test_compare_expect expect current
'
@@ -93,7 +93,7 @@ test_expect_success 'git ls-files (relative #2)' '
git ls-files --full-name "../e/f"
) >current &&
echo a/e/f >expect &&
- diff -u expect current
+ test_compare_expect expect current
'
@@ -126,13 +126,13 @@ test_expect_success 'log using absolute path names' '
git log a/b/c/d >f1.txt &&
git log "$(pwd)/a/b/c/d" >f2.txt &&
- diff -u f1.txt f2.txt
+ test_compare_expect f1.txt f2.txt
'
test_expect_success 'blame using absolute path names' '
git blame a/b/c/d >f1.txt &&
git blame "$(pwd)/a/b/c/d" >f2.txt &&
- diff -u f1.txt f2.txt
+ test_compare_expect f1.txt f2.txt
'
test_expect_success 'setup deeper work tree' '
diff --git a/t/t7501-commit.sh b/t/t7501-commit.sh
index 361886c..f2d89c0 100755
--- a/t/t7501-commit.sh
+++ b/t/t7501-commit.sh
@@ -203,7 +203,7 @@ test_expect_success 'sign off (1)' '
git var GIT_COMMITTER_IDENT |
sed -e "s/>.*/>/" -e "s/^/Signed-off-by: /"
) >expected &&
- diff -u expected actual
+ test_compare_expect expected actual
'
@@ -223,7 +223,7 @@ $existing" &&
git var GIT_COMMITTER_IDENT |
sed -e "s/>.*/>/" -e "s/^/Signed-off-by: /"
) >expected &&
- diff -u expected actual
+ test_compare_expect expected actual
'
@@ -240,7 +240,7 @@ test_expect_success 'multiple -m' '
echo
echo three
) >expected &&
- diff -u expected actual
+ test_compare_expect expected actual
'
@@ -301,12 +301,12 @@ test_expect_success 'same tree (merge and amend merge)' '
git merge -s ours side -m "empty ok" &&
git diff HEAD^ HEAD >actual &&
: >expected &&
- diff -u expected actual &&
+ test_compare_expect expected actual &&
git commit --amend -m "empty really ok" &&
git diff HEAD^ HEAD >actual &&
: >expected &&
- diff -u expected actual
+ test_compare_expect expected actual
'
@@ -323,7 +323,7 @@ test_expect_success 'amend using the message from another commit' '
git commit --allow-empty --amend -C "$old" &&
git show --pretty="format:%ad %s" "$old" >expected &&
git show --pretty="format:%ad %s" HEAD >actual &&
- diff -u expected actual
+ test_compare_expect expected actual
'
@@ -341,7 +341,7 @@ test_expect_success 'amend using the message from a commit named with tag' '
git commit --allow-empty --amend -C tagged-old &&
git show --pretty="format:%ad %s" "$old" >expected &&
git show --pretty="format:%ad %s" HEAD >actual &&
- diff -u expected actual
+ test_compare_expect expected actual
'
diff --git a/t/t7502-commit.sh b/t/t7502-commit.sh
index b780fdd..f9616bf 100755
--- a/t/t7502-commit.sh
+++ b/t/t7502-commit.sh
@@ -85,7 +85,7 @@ test_expect_success 'verbose' '
git add negative &&
git status -v | sed -ne "/^diff --git /p" >actual &&
echo "diff --git a/negative b/negative" >expect &&
- diff -u expect actual
+ test_compare_expect expect actual
'
@@ -95,7 +95,7 @@ test_expect_success 'cleanup commit messages (verbatim,-t)' '
{ echo;echo "# text";echo; } >expect &&
git commit --cleanup=verbatim -t expect -a &&
git cat-file -p HEAD |sed -e "1,/^\$/d" |head -n 3 >actual &&
- diff -u expect actual
+ test_compare_expect expect actual
'
@@ -104,7 +104,7 @@ test_expect_success 'cleanup commit messages (verbatim,-F)' '
echo >>negative &&
git commit --cleanup=verbatim -F expect -a &&
git cat-file -p HEAD |sed -e "1,/^\$/d">actual &&
- diff -u expect actual
+ test_compare_expect expect actual
'
@@ -113,7 +113,7 @@ test_expect_success 'cleanup commit messages (verbatim,-m)' '
echo >>negative &&
git commit --cleanup=verbatim -m "$(cat expect)" -a &&
git cat-file -p HEAD |sed -e "1,/^\$/d">actual &&
- diff -u expect actual
+ test_compare_expect expect actual
'
@@ -124,7 +124,7 @@ test_expect_success 'cleanup commit messages (whitespace,-F)' '
echo "# text" >expect &&
git commit --cleanup=whitespace -F text -a &&
git cat-file -p HEAD |sed -e "1,/^\$/d">actual &&
- diff -u expect actual
+ test_compare_expect expect actual
'
@@ -135,7 +135,7 @@ test_expect_success 'cleanup commit messages (strip,-F)' '
echo sample >expect &&
git commit --cleanup=strip -F text -a &&
git cat-file -p HEAD |sed -e "1,/^\$/d">actual &&
- diff -u expect actual
+ test_compare_expect expect actual
'
@@ -150,7 +150,7 @@ test_expect_success 'cleanup commit messages (strip,-F,-e)' '
{ echo;echo sample;echo; } >text &&
git commit -e -F text -a &&
head -n 4 .git/COMMIT_EDITMSG >actual &&
- diff -u expect actual
+ test_compare_expect expect actual
'
diff --git a/t/t7502-status.sh b/t/t7502-status.sh
index e006074..9b9c7a7 100755
--- a/t/t7502-status.sh
+++ b/t/t7502-status.sh
@@ -146,7 +146,7 @@ cat <<EOF >expect
EOF
test_expect_success 'status of partial commit excluding new file in index' '
git status dir1/modified >output &&
- diff -u expect output
+ test_compare_expect expect output
'
test_done
diff --git a/t/t7600-merge.sh b/t/t7600-merge.sh
index 50c51c8..15efd65 100755
--- a/t/t7600-merge.sh
+++ b/t/t7600-merge.sh
@@ -108,7 +108,7 @@ create_merge_msgs() {
}
verify_diff() {
- if ! diff -u "$1" "$2"
+ if ! test_compare_expect "$1" "$2"
then
echo "$3"
false
diff --git a/t/t8003-blame.sh b/t/t8003-blame.sh
index db51b3a..153f3e2 100755
--- a/t/t8003-blame.sh
+++ b/t/t8003-blame.sh
@@ -112,7 +112,7 @@ test_expect_success 'blame wholesale copy' '
echo mouse-Second
echo mouse-Third
} >expected &&
- diff -u expected current
+ test_compare_expect expected current
'
@@ -125,7 +125,7 @@ test_expect_success 'blame wholesale copy and more' '
echo cow-Fifth
echo mouse-Third
} >expected &&
- diff -u expected current
+ test_compare_expect expected current
'
diff --git a/t/t9001-send-email.sh b/t/t9001-send-email.sh
index 2efaed4..7342780 100755
--- a/t/t9001-send-email.sh
+++ b/t/t9001-send-email.sh
@@ -75,7 +75,7 @@ test_expect_success 'Show all headers' '
-e "s/^\(Message-Id:\).*/\1 MESSAGE-ID-STRING/" \
-e "s/^\(X-Mailer:\).*/\1 X-MAILER-STRING/" \
>actual-show-all-headers &&
- diff -u expected-show-all-headers actual-show-all-headers
+ test_compare_expect expected-show-all-headers actual-show-all-headers
'
z8=zzzzzzzz
diff --git a/t/t9116-git-svn-log.sh b/t/t9116-git-svn-log.sh
index 902ed41..80f3b39 100755
--- a/t/t9116-git-svn-log.sh
+++ b/t/t9116-git-svn-log.sh
@@ -55,74 +55,74 @@ printf 'r1 \nr2 \nr4 \n' > expected-range-r1-r2-r4
test_expect_success 'test ascending revision range' "
git reset --hard trunk &&
- git svn log -r 1:4 | grep '^r[0-9]' | cut -d'|' -f1 | diff -u expected-range-r1-r2-r4 -
+ git svn log -r 1:4 | grep '^r[0-9]' | cut -d'|' -f1 | test_compare_expect expected-range-r1-r2-r4 -
"
printf 'r4 \nr2 \nr1 \n' > expected-range-r4-r2-r1
test_expect_success 'test descending revision range' "
git reset --hard trunk &&
- git svn log -r 4:1 | grep '^r[0-9]' | cut -d'|' -f1 | diff -u expected-range-r4-r2-r1 -
+ git svn log -r 4:1 | grep '^r[0-9]' | cut -d'|' -f1 | test_compare_expect expected-range-r4-r2-r1 -
"
printf 'r1 \nr2 \n' > expected-range-r1-r2
test_expect_success 'test ascending revision range with unreachable revision' "
git reset --hard trunk &&
- git svn log -r 1:3 | grep '^r[0-9]' | cut -d'|' -f1 | diff -u expected-range-r1-r2 -
+ git svn log -r 1:3 | grep '^r[0-9]' | cut -d'|' -f1 | test_compare_expect expected-range-r1-r2 -
"
printf 'r2 \nr1 \n' > expected-range-r2-r1
test_expect_success 'test descending revision range with unreachable revision' "
git reset --hard trunk &&
- git svn log -r 3:1 | grep '^r[0-9]' | cut -d'|' -f1 | diff -u expected-range-r2-r1 -
+ git svn log -r 3:1 | grep '^r[0-9]' | cut -d'|' -f1 | test_compare_expect expected-range-r2-r1 -
"
printf 'r2 \n' > expected-range-r2
test_expect_success 'test ascending revision range with unreachable upper boundary revision and 1 commit' "
git reset --hard trunk &&
- git svn log -r 2:3 | grep '^r[0-9]' | cut -d'|' -f1 | diff -u expected-range-r2 -
+ git svn log -r 2:3 | grep '^r[0-9]' | cut -d'|' -f1 | test_compare_expect expected-range-r2 -
"
test_expect_success 'test descending revision range with unreachable upper boundary revision and 1 commit' "
git reset --hard trunk &&
- git svn log -r 3:2 | grep '^r[0-9]' | cut -d'|' -f1 | diff -u expected-range-r2 -
+ git svn log -r 3:2 | grep '^r[0-9]' | cut -d'|' -f1 | test_compare_expect expected-range-r2 -
"
printf 'r4 \n' > expected-range-r4
test_expect_success 'test ascending revision range with unreachable lower boundary revision and 1 commit' "
git reset --hard trunk &&
- git svn log -r 3:4 | grep '^r[0-9]' | cut -d'|' -f1 | diff -u expected-range-r4 -
+ git svn log -r 3:4 | grep '^r[0-9]' | cut -d'|' -f1 | test_compare_expect expected-range-r4 -
"
test_expect_success 'test descending revision range with unreachable lower boundary revision and 1 commit' "
git reset --hard trunk &&
- git svn log -r 4:3 | grep '^r[0-9]' | cut -d'|' -f1 | diff -u expected-range-r4 -
+ git svn log -r 4:3 | grep '^r[0-9]' | cut -d'|' -f1 | test_compare_expect expected-range-r4 -
"
printf -- '------------------------------------------------------------------------\n' > expected-separator
test_expect_success 'test ascending revision range with unreachable boundary revisions and no commits' "
git reset --hard trunk &&
- git svn log -r 5:6 | diff -u expected-separator -
+ git svn log -r 5:6 | test_compare_expect expected-separator -
"
test_expect_success 'test descending revision range with unreachable boundary revisions and no commits' "
git reset --hard trunk &&
- git svn log -r 6:5 | diff -u expected-separator -
+ git svn log -r 6:5 | test_compare_expect expected-separator -
"
test_expect_success 'test ascending revision range with unreachable boundary revisions and 1 commit' "
git reset --hard trunk &&
- git svn log -r 3:5 | grep '^r[0-9]' | cut -d'|' -f1 | diff -u expected-range-r4 -
+ git svn log -r 3:5 | grep '^r[0-9]' | cut -d'|' -f1 | test_compare_expect expected-range-r4 -
"
test_expect_success 'test descending revision range with unreachable boundary revisions and 1 commit' "
git reset --hard trunk &&
- git svn log -r 5:3 | grep '^r[0-9]' | cut -d'|' -f1 | diff -u expected-range-r4 -
+ git svn log -r 5:3 | grep '^r[0-9]' | cut -d'|' -f1 | test_compare_expect expected-range-r4 -
"
test_done
diff --git a/t/t9200-git-cvsexportcommit.sh b/t/t9200-git-cvsexportcommit.sh
index 58c59ed..2677799 100755
--- a/t/t9200-git-cvsexportcommit.sh
+++ b/t/t9200-git-cvsexportcommit.sh
@@ -37,7 +37,7 @@ check_entries () {
else
printf '%s\n' "$2" | tr '|' '\012' >expected
fi
- diff -u expected actual
+ test_compare_expect expected actual
}
test_expect_success \
@@ -257,8 +257,8 @@ test_expect_success '-w option should work with relative GIT_DIR' '
(cd "$GIT_DIR" &&
GIT_DIR=. git cvsexportcommit -w "$CVSWORK" -c $id &&
check_entries "$CVSWORK/W" "file1.txt/1.1/|file2.txt/1.1/" &&
- diff -u "$CVSWORK/W/file1.txt" ../W/file1.txt &&
- diff -u "$CVSWORK/W/file2.txt" ../W/file2.txt
+ test_compare_expect "$CVSWORK/W/file1.txt" ../W/file1.txt &&
+ test_compare_expect "$CVSWORK/W/file2.txt" ../W/file2.txt
)
'
@@ -279,9 +279,9 @@ test_expect_success 'check files before directories' '
git cvsexportcommit -w "$CVSWORK" -c $id &&
check_entries "$CVSWORK/E" "DS/1.1/|newfile5.txt/1.1/" &&
check_entries "$CVSWORK" "DS/1.1/|release-notes/1.2/" &&
- diff -u "$CVSWORK/DS" DS &&
- diff -u "$CVSWORK/E/DS" E/DS &&
- diff -u "$CVSWORK/release-notes" release-notes
+ test_compare_expect "$CVSWORK/DS" DS &&
+ test_compare_expect "$CVSWORK/E/DS" E/DS &&
+ test_compare_expect "$CVSWORK/release-notes" release-notes
'
@@ -293,7 +293,7 @@ test_expect_success 'commit a file with leading spaces in the name' '
id=$(git rev-parse HEAD) &&
git cvsexportcommit -w "$CVSWORK" -c $id &&
check_entries "$CVSWORK" " space/1.1/|DS/1.1/|release-notes/1.2/" &&
- diff -u "$CVSWORK/ space" " space"
+ test_compare_expect "$CVSWORK/ space" " space"
'
diff --git a/t/t9300-fast-import.sh b/t/t9300-fast-import.sh
index cceedbb..5b5ef19 100755
--- a/t/t9300-fast-import.sh
+++ b/t/t9300-fast-import.sh
@@ -117,7 +117,7 @@ test_expect_success \
--import-marks=marks.out \
--export-marks=marks.new \
</dev/null &&
- git diff -u expect marks.new'
+ test_compare_expect expect marks.new'
test_tick
cat >input <<INPUT_END
diff --git a/t/test-lib.sh b/t/test-lib.sh
index 83889c4..73cc867 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -52,6 +52,9 @@ case $(echo $GIT_TRACE |tr "[A-Z]" "[a-z]") in
;;
esac
+test_use_diff_u=t
+test_compare_stdin_file_=
+
# Each test should start with something like this, after copyright notices:
#
# test_description='Description of this test...
@@ -79,6 +82,8 @@ do
verbose=t; shift ;;
-q|--q|--qu|--qui|--quie|--quiet)
quiet=t; shift ;;
+ --no-diff-u)
+ test_use_diff_u=; shift ;;
--no-color)
color=; shift ;;
--no-python)
@@ -270,6 +275,24 @@ test_expect_code () {
echo >&3 ""
}
+# Compare expected output and actual one. The latter can be
+# '-' to compare the expected with the standard input
+test_compare_expect () {
+ case "$test_use_diff_u" in
+ t)
+ diff -u "$1" "$2" ;;
+ *)
+ case "$test_compare_stdin_file_" in
+ '')
+ test_compare_stdin_file_=/tmp/gittest.$$
+ esac
+ cat "$1" >"$test_compare_stdin_file_.1"
+ cat "$2" >"$test_compare_stdin_file_.2"
+ git diff -u --no-index \
+ "$test_compare_stdin_file_.1" "$test_compare_stdin_file_.2" ;;
+ esac
+}
+
# Most tests can use the created repository, but some may need to create more.
# Usage: test_create_repo <directory>
test_create_repo () {
@@ -288,6 +311,10 @@ test_create_repo () {
test_done () {
trap - exit
+ if test -n "$test_compare_stdin_file_"
+ then
+ rm -f "$test_compare_stdin_file_.[12]"
+ fi
if test "$test_fixed" != 0
then
say_color pass "fixed $test_fixed known breakage(s)"
--
1.5.4.2.261.g851a5
^ permalink raw reply related [relevance 1%]
* [ANNOUNCE] GIT 1.5.4.3
@ 2008-02-23 21:07 3% Junio C Hamano
0 siblings, 0 replies; 200+ results
From: Junio C Hamano @ 2008-02-23 21:07 UTC (permalink / raw)
To: git; +Cc: linux-kernel
The latest maintenance release GIT 1.5.4.3 is available at the
usual places:
http://www.kernel.org/pub/software/scm/git/
git-1.5.4.3.tar.{gz,bz2} (tarball)
git-htmldocs-1.5.4.3.tar.{gz,bz2} (preformatted docs)
git-manpages-1.5.4.3.tar.{gz,bz2} (preformatted docs)
RPMS/$arch/git-*-1.5.4.3-1.$arch.rpm (RPM)
Largest user visible change in this is RPM packaging updates by
Kristian Høgsberg. 'git-core' will only be pure git without
pulling foreign SCM packages in as its dependencies anymore when
you do "yum install git-core".
----------------------------------------------------------------
GIT v1.5.4.3 Release Notes
==========================
Fixes since v1.5.4.2
--------------------
* RPM spec used to pull in everything with 'git'. This has been
changed so that 'git' package contains just the core parts,
and we now supply 'git-all' metapackage to slurp in everything.
This should match end user's expectation better.
* When some refs failed to update, git-push reported "failure"
which was unclear if some other refs were updated or all of
them failed atomically (the answer is the former). Reworded
the message to clarify this.
* "git clone" from a repository whose HEAD was misconfigured
did not set up the remote properly. Now it tries to do
better.
* Updated git-push documentation to clarify what "matching"
means, in order to reduce user confusion.
* Updated git-add documentation to clarify "add -u" operates in
the current subdirectory you are in, just like other commands.
* git-gui updates to work on OSX and Windows better.
----------------------------------------------------------------
Changes since v1.5.4.2 are as follows:
Gerrit Pape (1):
git-clone.sh: properly configure remote even if remote's head is dangling
Jay Soffian (2):
git-gui: support Git Gui.app under OS X 10.5
send-email: squelch warning due to comparing undefined $_ to ""
Jeff King (4):
push: indicate partialness of error message
Documentation/push: clarify matching refspec behavior
push: document the status output
hash: fix lookup_hash semantics
Junio C Hamano (1):
GIT 1.5.4.3
Kristian H淡gsberg (1):
Rename git-core rpm to just git and rename the meta-pacakge to git-all.
Miklos Vajna (1):
Documentation/git-stash: document options for git stash list
Pekka Kaitaniemi (1):
Clarified the meaning of git-add -u in the documentation
Shawn O. Pearce (5):
git-gui: Ensure error dialogs always appear over all other windows
git-gui: Paper bag fix error dialogs opening over the main window
git-gui: Default TCL_PATH to same location as TCLTK_PATH
git-gui: Avoid hardcoded Windows paths in Cygwin package files
git-gui: Focus insertion point at end of strings in repository chooser
Wincent Colaiuta (1):
git-gui: relax "dirty" version detection
^ permalink raw reply [relevance 3%]
* Re: on subtree checkout
@ 2008-02-24 15:59 5% ` Matthieu Moy
2008-02-24 17:22 2% ` Robin Rosenberg
0 siblings, 1 reply; 200+ results
From: Matthieu Moy @ 2008-02-24 15:59 UTC (permalink / raw)
To: Jakub Narebski; +Cc: Nguyen Thai Ngoc Duy, git mailing list
Jakub Narebski <jnareb@gmail.com> writes:
> Nguyen Thai Ngoc Duy wrote:
>> On Sun, Feb 24, 2008 at 5:03 PM, Jakub Narebski <jnareb@gmail.com> wrote:
>>>
>>> "Nguyen Thai Ngoc Duy" <pclouds@gmail.com> writes:
>>>
>>>> I'm going to implement subtree checkout. [...]
>>>
>>> As far as I can see the problem lies in merging...
>>
>> Can you elaborate? I'm really noob at merging.
>
> What to do if when merging, or rebasing, there is conflict _outside_
> checked out subtree?
I suppose you have to forbid merges where anything non-trivial happens
outside the tree (i.e. allow it only if the set of renamed or changed
files is disjoint outside the tree, or only if only one of the
branches to merge have changes outside the tree).
That's probably not such a big limitation in practice for the user,
since by definition the user won't modify the files outside its tree,
so he can at least still merge with the branch he branched from.
I can see another problem: partial checkout is really interesting only
if you can do a partial clone ("partial" here in the sense "subtree").
Otherwise, your .git/ still eats your disk space and "clone" still
needs your bandwidth for something you won't use.
--
Matthieu
^ permalink raw reply [relevance 5%]
* Re: on subtree checkout
2008-02-24 15:59 5% ` Matthieu Moy
@ 2008-02-24 17:22 2% ` Robin Rosenberg
0 siblings, 0 replies; 200+ results
From: Robin Rosenberg @ 2008-02-24 17:22 UTC (permalink / raw)
To: Matthieu Moy; +Cc: Jakub Narebski, Nguyen Thai Ngoc Duy, git mailing list
söndagen den 24 februari 2008 skrev Matthieu Moy:
> I suppose you have to forbid merges where anything non-trivial happens
> outside the tree (i.e. allow it only if the set of renamed or changed
> files is disjoint outside the tree, or only if only one of the
> branches to merge have changes outside the tree).
One still has to allow it, maybe forcing a bigger checkout in those
cases.
> That's probably not such a big limitation in practice for the user,
> since by definition the user won't modify the files outside its tree,
> so he can at least still merge with the branch he branched from.
Partial checkout is for convenience and speed of worktree operations as
I see it. Other people could have other reasons for it. Branch switching takes a lot of time with big repos, same thing with git status, add -u etc. Restricting the worktree scan for uninteresting parts speeds things up.
> I can see another problem: partial checkout is really interesting only
> if you can do a partial clone ("partial" here in the sense "subtree").
> Otherwise, your .git/ still eats your disk space and "clone" still
> needs your bandwidth for something you won't use.
Better and more of "global" operations on repos with submodules might make them more bearable, and maybe even convenient, for example doing a git diff
over a set of submodules detecting renames between submodules.
-- robin
^ permalink raw reply [relevance 2%]
* Re: on subtree checkout
@ 2008-02-26 2:30 3% ` David Symonds
2008-02-26 11:23 2% ` Johannes Schindelin
0 siblings, 1 reply; 200+ results
From: David Symonds @ 2008-02-26 2:30 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: Nguyen Thai Ngoc Duy, git mailing list
On Mon, Feb 25, 2008 at 5:59 PM, Johannes Schindelin
<Johannes.Schindelin@gmx.de> wrote:
> Hi,
>
>
> On Sun, 24 Feb 2008, Nguyen Thai Ngoc Duy wrote:
>
> > I'm going to implement subtree checkout. The plan is to save "index
> > prefix" in GIT_DIR/prefix and update git commands to use index prefix
> > when accessing the index. If I'm heading a wrong way, stop me now.
>
> As I wrote a long time ago already, I think the correct approach would be
> to reuse the code for the core.ignoreStat feature.
>
> But I agree with others that you should think about sane implementations
> of rebase/merge with partial checkouts.
I, too, was shortly going to attempt a partial checkout/clone
implementation. The intended context of my implementation was similar
to the KDE scenario in that you might only care about /pkgA and /pkgB,
so changes to /pkgC are usually irrelevant and independent to your
work-flow, so I was planning to assume a simplistic "theirs" merge
strategy for /pkgC, etc.
Dave.
^ permalink raw reply [relevance 3%]
* Re: on subtree checkout
2008-02-26 2:30 3% ` David Symonds
@ 2008-02-26 11:23 2% ` Johannes Schindelin
0 siblings, 0 replies; 200+ results
From: Johannes Schindelin @ 2008-02-26 11:23 UTC (permalink / raw)
To: David Symonds; +Cc: Nguyen Thai Ngoc Duy, git mailing list
Hi,
On Mon, 25 Feb 2008, David Symonds wrote:
> On Mon, Feb 25, 2008 at 5:59 PM, Johannes Schindelin
> <Johannes.Schindelin@gmx.de> wrote:
> >
> > But I agree with others that you should think about sane
> > implementations of rebase/merge with partial checkouts.
>
> I, too, was shortly going to attempt a partial checkout/clone
> implementation. The intended context of my implementation was similar to
> the KDE scenario in that you might only care about /pkgA and /pkgB, so
> changes to /pkgC are usually irrelevant and independent to your
> work-flow, so I was planning to assume a simplistic "theirs" merge
> strategy for /pkgC, etc.
That might work for the people who have partial checkouts. But I see a
lot of problems looming there: just imagine a documenter rebased on top of
'master', and _then_ on top of a branch by another documenter, which is
newer with respect to documentation, but older with respect to the code.
It is _really_ easy to break code if you have no intention to test the
result of a merge, _especially_ so when it is a "theirs" strategy.
Ciao,
Dscho
^ permalink raw reply [relevance 2%]
* Re: Google Summer of Code 2008
@ 2008-02-29 12:04 4% ` Jakub Narebski
0 siblings, 0 replies; 200+ results
From: Jakub Narebski @ 2008-02-29 12:04 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: Shawn O. Pearce, Robin Rosenberg, git, John Hawley
On Thu, 28 Feb 2008, Johannes Schindelin wrote:
> Do go ahead! I started the page
>
> http://git.or.cz/gitwiki/SoC2008Ideas
>
> which is utterly incomplete. I just took the ideas of 2007 that I am
> still interested in,
By the way, when looking at 2007 GSoC ideas one can see that some of
them got implemented already outside of GSoC, and are no longer valid;
well, perhaps as "improve <sth>" ideas.
Subproject/submodule support got implemented, Mozilla has decided to use
Mecurial instead of Git (but there are other large-scale imports:
OpenOffice.org, GCC) and cvs2svn supports fast-import output which
means export to git, gitattributes support got much extended.
> and removed other people from the Mentor list,
> because I do not want to force them. So please, if you are interested
> in mentoring one of the existing projects, just add yourself.
>
> And of course add all those cool projects you have in mind.
I have some interesting ideas for GSoC, but unfortunately none (with
perhaps single exception) that I could mentor. So I think I'd list them
here for now, and later I'd add it to SoC2008Ideas page.
Here they are.
First, a few ideas which got partially implemented already, or are
implemented and need improvements. I don't know if current contributors
would want to be mentors, or would they want to submit their work under
GSoC as participants.
* Lazy clone / remote alternates
The idea here is to be able to remotely access objects from a network
based object server, as neededm rather than having them all local.
Goal: A working lazy clone prototype implementation that could be
considered for inclusion, in a nice series of commits (separate
branch/fork)
Language: C
Suggested mentor: Jan Holesovsky, who submitted proof-of-concept
patch for lazy clone
* Partial (subtree) checkout, or its generalization: sparse checkout
The idea is to checkout for example only Documentation subdirectory,
work on it, but commit full tree. Some workflows may be better suited
to this type of usage than using submodules. Optionally should include
partial clone (not needed objects not in repository).
Goal: A working partial checkout prototype implementation, with
technical documentation.
Language: C
Suggested mentors:
gitzilla (sent proposal),
Nguyen Thai Ngoc Duy (pclouds), proposed to implements it
* Gitweb caching
Implementing very smart caching in gitweb, to avoid the thundering
herd problem on kernel.org whenever a repository gets updated, or at
least support for caching engines in the form of generating proper
Last-Modified: and ETag: headers, and responding to If-Modified-Since:
and If-None-Match: requests, cheaply.
Perhaps becoming the gitweb maintainer could come of it, or at least
the gitweb admin for kernel.org (sorely needed).
Goal: At minimum, port kernel.org's caching to mainline (git's) gitweb
Language: Perl, HTML, perhaps JavaScript
Suggested mentors:
John 'Warthog9' Hawley (wrote caching for kernel.org's gitweb)
Petr Baudis (repo.or.cz admin)
Lars Hjemli (cgit author, git web interface in C, with caching)
Jakub Narebski (gitweb contributor)
Then, a few ideas which were proposed for GSoC 2007, but never
implemented, and wasn't mentioned in this thread or on wiki for
GSoC 2008 yet
* Git / Subversion Interoperability
The idea here is implement something in Git that speaks the Subversion
protocol on the wire, but uses Git as the backend storage. (This would
be like the existing git-cvsserver.)
There are two potential approaches:
1. git-svnserver
2. write a backend for Subversion
Goal: To be able to access git repository, at minimum read-only, from
a Subversion client, at least svn CLI.
Language: Open for proposal.
Suggested mentors:
Eric Wong (git-svn author)
Matthias Urlichs (git-svnimport author)
Notes: I don't think we could pass it as Subversion SoC project, but
I guess that we could ask for co-mentor for the Subversion protocol,
or Subversion backend part of this task.
I'd send other ideas (including new ones, like translating svn:externals
into git submodules in git-svn; or making git mode for Emacs have all
features of tig, git-gui and gitk; or improving shallow clone support)
in a later post.
> Shawn, do we have to do the same again, as on this page?
>
> http://git.or.cz/gitwiki/Soc2007Application
A few things changes for us: we have participated in GSoC 2007; we need
to find backup organization administrator (was: Martin Langhoff for
GSoC2007), list of mentors would change most probably.
As far as I've checked the application form for organizations didn't
change...
--
Jakub Narebski
Poland
^ permalink raw reply [relevance 4%]
* Re: [QUESTION] Selective fetch possible?
@ 2008-03-10 23:34 2% ` Jakub Narebski
2008-03-11 7:26 0% ` Rogan Dawes
0 siblings, 1 reply; 200+ results
From: Jakub Narebski @ 2008-03-10 23:34 UTC (permalink / raw)
To: Shawn O. Pearce; +Cc: Filippo Zangheri, git
"Shawn O. Pearce" <spearce@spearce.org> writes:
> Filippo Zangheri <filippo.zangheri@yahoo.it> wrote:
> >
> > Is it possible to git-fetch only a portion of the tree
> > of the specified repository, say, fetch only one directory or a
> > subset of files matching some regular expression? This is currently
> > - to my knowledge - only possible via wget iff the GIT repository
> > has gitweb enabled. But that's just a workaround.
>
> No.
>
> You can use a shallow clone to fetch only X commits back into
> history on any branch, and you can also manually configure the
> fetch specification in .git/config to only fetch specific branches,
> but you must fetch the entire tree to get any of the files in it.
>
> If the repository is available by git:// protocol you may be able
> to use git-archive to obtain a tarfile for just the directory you
> want (service has to be enabled on the remote side) but that is
> just a raw UNIX tar; there is no Git repository and no ability to
> commit/fetch/push/diff/apply/log/etc.
Note that what you wanted is, I guess, something called partial
checkout or subtree checkout. This feature appears now and then in
feature requests; lately Nguyen Thai Ngoc Duy (pclouds) offered to do
this in "on subtree checkout" thread:
http://thread.gmane.org/gmane.comp.version-control.git/74915
The problem is twofold, as far as I understand it. First, what to do
if there is merge conflicts outside checked out (selected) directory?
Second, how to make repository contain only relevant objects: git in
many places assumes full connectivity, and that if it has an object it
hass all objects depending on it.
--
Jakub Narebski
Poland
ShadeHawk on #git
^ permalink raw reply [relevance 2%]
* Re: [QUESTION] Selective fetch possible?
2008-03-10 23:34 2% ` Jakub Narebski
@ 2008-03-11 7:26 0% ` Rogan Dawes
0 siblings, 1 reply; 200+ results
From: Rogan Dawes @ 2008-03-11 7:26 UTC (permalink / raw)
To: Jakub Narebski; +Cc: Shawn O. Pearce, Filippo Zangheri, git
Jakub Narebski wrote:
> "Shawn O. Pearce" <spearce@spearce.org> writes:
>
>> Filippo Zangheri <filippo.zangheri@yahoo.it> wrote:
>>> Is it possible to git-fetch only a portion of the tree
>>> of the specified repository, say, fetch only one directory or a
>>> subset of files matching some regular expression? This is currently
>>> - to my knowledge - only possible via wget iff the GIT repository
>>> has gitweb enabled. But that's just a workaround.
>> No.
>>
>> You can use a shallow clone to fetch only X commits back into
>> history on any branch, and you can also manually configure the
>> fetch specification in .git/config to only fetch specific branches,
>> but you must fetch the entire tree to get any of the files in it.
>>
>> If the repository is available by git:// protocol you may be able
>> to use git-archive to obtain a tarfile for just the directory you
>> want (service has to be enabled on the remote side) but that is
>> just a raw UNIX tar; there is no Git repository and no ability to
>> commit/fetch/push/diff/apply/log/etc.
>
> Note that what you wanted is, I guess, something called partial
> checkout or subtree checkout. This feature appears now and then in
> feature requests; lately Nguyen Thai Ngoc Duy (pclouds) offered to do
> this in "on subtree checkout" thread:
> http://thread.gmane.org/gmane.comp.version-control.git/74915
I still believe that it could be done fairly easily by simply recording
the SHA1's of the files and directories that are *not* checked out
somewhere in the .git directory, and just reusing those when checking
the working tree. i.e. rather than stat-ing a tree that was never
checked out, get the known SHA1 for that tree from where it was recorded
on checkout.
> The problem is twofold, as far as I understand it. First, what to do
> if there is merge conflicts outside checked out (selected) directory?
This is something that has been repeated many times, and I fail to see
how it can be an issue. How can there be a conflict in a directory that
is not, and never has been, checked out, and therefore cannot have been
modified?
The only possibility that I can see is if the directory has been renamed
elsewhere, but in that case, it *is* effectively checked out (just with
a different directory name).
> Second, how to make repository contain only relevant objects: git in
> many places assumes full connectivity, and that if it has an object it
> hass all objects depending on it.
>
Yes, this is the big problem as I see it.
Rogan
^ permalink raw reply [relevance 0%]
* Re: [QUESTION] Selective fetch possible?
@ 2008-03-11 9:07 3% ` Rogan Dawes
0 siblings, 0 replies; 200+ results
From: Rogan Dawes @ 2008-03-11 9:07 UTC (permalink / raw)
To: Shawn O. Pearce; +Cc: Jakub Narebski, Filippo Zangheri, git
Shawn O. Pearce wrote:
> Rogan Dawes <lists@dawes.za.net> wrote:
>> Jakub Narebski wrote:
>>> "Shawn O. Pearce" <spearce@spearce.org> writes:
>>>
>>>> Filippo Zangheri <filippo.zangheri@yahoo.it> wrote:
>>>>> Is it possible to git-fetch only a portion of the tree
>>>>> of the specified repository, say, fetch only one directory or a
>>>>> subset of files matching some regular expression?
>>> The problem is twofold, as far as I understand it. First, what to do
>>> if there is merge conflicts outside checked out (selected) directory?
>> This is something that has been repeated many times, and I fail to see
>> how it can be an issue. How can there be a conflict in a directory that
>> is not, and never has been, checked out, and therefore cannot have been
>> modified?
>
> Given two branches:
>
> code
> docs
>
> and the code people checkout the "src/" subdirectory and the docs
> people checkout the "Documentation/" subdirectory, and they *only*
> every work in that subdirectory, things are fine.
>
> Until one day some developer also checks out "Documentation/" and
> fixes something in the documentation as part of the same commit
> that makes a code change. The push this to the code branch.
>
> Someday in the future a documentation writer merges the code branch
> over to the docs branch, "just keeping it current".
>
> Now there arises a possiblity of a merge conflict in a part of the
> tree that you do not have checked out.
>
>
> If you want to say "don't ever modify stuff outside of your branch's
> purpose" then why aren't you just using submodules (one for docs and
> one for code) and using a supermodule to tie everything together into
> a "release package"?
Ok, fair enough. Thanks for the example.
I think that one should not *expect* to be able to complete merges with
only a partial checkout, though. It *may* work in cases where there are
no conflicts, but I think it would be a perfectly valid error path to
fail if there is a conflicting merge in a part of the tree that has not
been checked out.
So, for a user working on partial trees, they would be able to modify
their partial tree, and check in their changes, but merges would have to
be done by someone with a complete checkout. For the given examples
where partial trees make sense (documentation workers), this seems like
a reasonable compromise.
>>> Second, how to make repository contain only relevant objects: git in
>>> many places assumes full connectivity, and that if it has an object it
>>> hass all objects depending on it.
>>>
>> Yes, this is the big problem as I see it.
>
> This is easy enough that if the above problem could be resolved
> sufficiently to the git gurus' satisfaction you would be able
> to get some advice on how to solve it. Its not difficult, just
> damn annoying. We already do it (to some extent) with grafts and
> shallow clones.
How's my suggestion above?
Rogan
^ permalink raw reply [relevance 3%]
* [PATCH 06/16] add test_cmp function for test scripts
[not found] <cover.1205356737.git.peff@peff.net>
@ 2008-03-12 21:36 1% ` Jeff King
0 siblings, 0 replies; 200+ results
From: Jeff King @ 2008-03-12 21:36 UTC (permalink / raw)
To: Whit Armstrong; +Cc: Junio C Hamano, git
Many scripts compare actual and expected output using
"diff -u". This is nicer than "cmp" because the output shows
how the two differ. However, not all versions of diff
understand -u, leading to unnecessary test failure.
This adds a test_cmp function to the test scripts and
switches all "diff -u" invocations to use it. The function
uses the contents of "$GIT_TEST_CMP" to compare its
arguments; the default is "diff -u".
On systems with a less-capable diff, you can do:
GIT_TEST_CMP=cmp make test
Signed-off-by: Jeff King <peff@peff.net>
---
The replacements were done mechanically with:
perl -pi -e 's/(?<!git.)diff -u/test_cmp/' t/*.sh
Perhaps this should be a command-line option instead of an environment
variable? Maybe it should be auto-detected or set up in the Makefile?
t/t0003-attributes.sh | 2 +-
t/t0022-crlf-rename.sh | 2 +-
t/t1005-read-tree-reset.sh | 2 +-
t/t2200-add-update.sh | 2 +-
t/t3001-ls-files-others-exclude.sh | 2 +-
t/t3050-subprojects-fetch.sh | 4 ++--
t/t3060-ls-files-with-tree.sh | 2 +-
t/t3201-branch-contains.sh | 6 +++---
t/t3404-rebase-interactive.sh | 4 ++--
t/t3405-rebase-malformed.sh | 4 ++--
t/t3406-rebase-message.sh | 2 +-
t/t3701-add-interactive.sh | 4 ++--
t/t3902-quoted.sh | 16 ++++++++--------
t/t3903-stash.sh | 2 +-
t/t4023-diff-rename-typechange.sh | 6 +++---
t/t4024-diff-optimize-common.sh | 2 +-
| 2 +-
t/t4027-diff-submodule.sh | 6 +++---
t/t4105-apply-fuzz.sh | 2 +-
t/t4125-apply-ws-fuzz.sh | 8 ++++----
t/t4150-am-subdir.sh | 10 +++++-----
t/t4201-shortlog.sh | 2 +-
t/t5505-remote.sh | 6 +++---
t/t5510-fetch.sh | 2 +-
t/t5512-ls-remote.sh | 8 ++++----
t/t6004-rev-list-path-optim.sh | 2 +-
t/t6009-rev-list-parent.sh | 2 +-
t/t6027-merge-binary.sh | 4 ++--
t/t6029-merge-subtree.sh | 2 +-
t/t7010-setup.sh | 18 +++++++++---------
t/t7201-co.sh | 18 +++++++++---------
t/t7501-commit.sh | 14 +++++++-------
t/t7502-commit.sh | 14 +++++++-------
t/t7502-status.sh | 2 +-
t/t7600-merge.sh | 2 +-
t/t8003-blame.sh | 4 ++--
t/t9001-send-email.sh | 2 +-
t/t9116-git-svn-log.sh | 24 ++++++++++++------------
t/t9200-git-cvsexportcommit.sh | 14 +++++++-------
t/test-lib.sh | 18 ++++++++++++++++++
40 files changed, 133 insertions(+), 115 deletions(-)
diff --git a/t/t0003-attributes.sh b/t/t0003-attributes.sh
index 47f08a4..3faf135 100755
--- a/t/t0003-attributes.sh
+++ b/t/t0003-attributes.sh
@@ -11,7 +11,7 @@ attr_check () {
git check-attr test -- "$path" >actual &&
echo "$path: test: $2" >expect &&
- diff -u expect actual
+ test_cmp expect actual
}
diff --git a/t/t0022-crlf-rename.sh b/t/t0022-crlf-rename.sh
index 430a1d1..7d1ce2d 100755
--- a/t/t0022-crlf-rename.sh
+++ b/t/t0022-crlf-rename.sh
@@ -26,7 +26,7 @@ test_expect_success 'diff -M' '
git diff-tree -M -r --name-status HEAD^ HEAD |
sed -e "s/R[0-9]*/RNUM/" >actual &&
echo "RNUM sample elpmas" >expect &&
- diff -u expect actual
+ test_cmp expect actual
'
diff --git a/t/t1005-read-tree-reset.sh b/t/t1005-read-tree-reset.sh
index 8c45564..b0d31f5 100755
--- a/t/t1005-read-tree-reset.sh
+++ b/t/t1005-read-tree-reset.sh
@@ -24,7 +24,7 @@ test_expect_success 'setup' '
test_expect_success 'reset should work' '
git read-tree -u --reset HEAD^ &&
git ls-files >actual &&
- diff -u expect actual
+ test_cmp expect actual
'
test_done
diff --git a/t/t2200-add-update.sh b/t/t2200-add-update.sh
index 24f892f..b664341 100755
--- a/t/t2200-add-update.sh
+++ b/t/t2200-add-update.sh
@@ -62,7 +62,7 @@ test_expect_success 'cache tree has not been corrupted' '
sed -e "s/ 0 / /" >expect &&
git ls-tree -r $(git write-tree) |
sed -e "s/ blob / /" >current &&
- diff -u expect current
+ test_cmp expect current
'
diff --git a/t/t3001-ls-files-others-exclude.sh b/t/t3001-ls-files-others-exclude.sh
index b4297ba..55f057c 100755
--- a/t/t3001-ls-files-others-exclude.sh
+++ b/t/t3001-ls-files-others-exclude.sh
@@ -97,7 +97,7 @@ cat > expect << EOF
EOF
test_expect_success 'git-status honours core.excludesfile' \
- 'diff -u expect output'
+ 'test_cmp expect output'
test_expect_success 'trailing slash in exclude allows directory match(1)' '
diff --git a/t/t3050-subprojects-fetch.sh b/t/t3050-subprojects-fetch.sh
index 34f26a8..2b21b10 100755
--- a/t/t3050-subprojects-fetch.sh
+++ b/t/t3050-subprojects-fetch.sh
@@ -26,7 +26,7 @@ test_expect_success clone '
cd cloned &&
(git rev-parse HEAD; git ls-files -s) >../actual
) &&
- diff -u expected actual
+ test_cmp expected actual
'
test_expect_success advance '
@@ -46,7 +46,7 @@ test_expect_success fetch '
git pull &&
(git rev-parse HEAD; git ls-files -s) >../actual
) &&
- diff -u expected actual
+ test_cmp expected actual
'
test_done
diff --git a/t/t3060-ls-files-with-tree.sh b/t/t3060-ls-files-with-tree.sh
index 68eb266..3ce501b 100755
--- a/t/t3060-ls-files-with-tree.sh
+++ b/t/t3060-ls-files-with-tree.sh
@@ -66,6 +66,6 @@ test_expect_success 'git -ls-files --with-tree should succeed from subdir' '
cd ..
test_expect_success \
'git -ls-files --with-tree should add entries from named tree.' \
- 'diff -u expected output'
+ 'test_cmp expected output'
test_done
diff --git a/t/t3201-branch-contains.sh b/t/t3201-branch-contains.sh
index 9ef593f..b4cf628 100755
--- a/t/t3201-branch-contains.sh
+++ b/t/t3201-branch-contains.sh
@@ -31,7 +31,7 @@ test_expect_success 'branch --contains=master' '
{
echo " master" && echo "* side"
} >expect &&
- diff -u expect actual
+ test_cmp expect actual
'
@@ -41,7 +41,7 @@ test_expect_success 'branch --contains master' '
{
echo " master" && echo "* side"
} >expect &&
- diff -u expect actual
+ test_cmp expect actual
'
@@ -51,7 +51,7 @@ test_expect_success 'branch --contains=side' '
{
echo "* side"
} >expect &&
- diff -u expect actual
+ test_cmp expect actual
'
diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh
index 9c0acc5..9cf873f 100755
--- a/t/t3404-rebase-interactive.sh
+++ b/t/t3404-rebase-interactive.sh
@@ -146,8 +146,8 @@ EOF
test_expect_success 'stop on conflicting pick' '
git tag new-branch1 &&
! git rebase -i master &&
- diff -u expect .git/.dotest-merge/patch &&
- diff -u expect2 file1 &&
+ test_cmp expect .git/.dotest-merge/patch &&
+ test_cmp expect2 file1 &&
test 4 = $(grep -v "^#" < .git/.dotest-merge/done | wc -l) &&
test 0 = $(grep -c "^[^#]" < .git/.dotest-merge/git-rebase-todo)
'
diff --git a/t/t3405-rebase-malformed.sh b/t/t3405-rebase-malformed.sh
index e4e2e64..e5ad67c 100755
--- a/t/t3405-rebase-malformed.sh
+++ b/t/t3405-rebase-malformed.sh
@@ -41,8 +41,8 @@ test_expect_success rebase '
git rebase master side &&
git cat-file commit HEAD | sed -e "1,/^\$/d" >F1 &&
- diff -u F0 F1 &&
- diff -u F F0
+ test_cmp F0 F1 &&
+ test_cmp F F0
'
test_done
diff --git a/t/t3406-rebase-message.sh b/t/t3406-rebase-message.sh
index 332b2b2..5391080 100755
--- a/t/t3406-rebase-message.sh
+++ b/t/t3406-rebase-message.sh
@@ -37,7 +37,7 @@ test_expect_success 'rebase -m' '
git rebase -m master >report &&
sed -n -e "/^Already applied: /p" \
-e "/^Committed: /p" report >actual &&
- diff -u expect actual
+ test_cmp expect actual
'
diff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh
index c8dc1ac..77c90f6 100755
--- a/t/t3701-add-interactive.sh
+++ b/t/t3701-add-interactive.sh
@@ -24,7 +24,7 @@ EOF
test_expect_success 'diff works (initial)' '
(echo d; echo 1) | git add -i >output &&
sed -ne "/new file/,/content/p" <output >diff &&
- diff -u expected diff
+ test_cmp expected diff
'
test_expect_success 'revert works (initial)' '
git add file &&
@@ -57,7 +57,7 @@ EOF
test_expect_success 'diff works (commit)' '
(echo d; echo 1) | git add -i >output &&
sed -ne "/^index/,/content/p" <output >diff &&
- diff -u expected diff
+ test_cmp expected diff
'
test_expect_success 'revert works (commit)' '
git add file &&
diff --git a/t/t3902-quoted.sh b/t/t3902-quoted.sh
index 73da45f..fe4fb51 100755
--- a/t/t3902-quoted.sh
+++ b/t/t3902-quoted.sh
@@ -78,28 +78,28 @@ EOF
test_expect_success 'check fully quoted output from ls-files' '
- git ls-files >current && diff -u expect.quoted current
+ git ls-files >current && test_cmp expect.quoted current
'
test_expect_success 'check fully quoted output from diff-files' '
git diff --name-only >current &&
- diff -u expect.quoted current
+ test_cmp expect.quoted current
'
test_expect_success 'check fully quoted output from diff-index' '
git diff --name-only HEAD >current &&
- diff -u expect.quoted current
+ test_cmp expect.quoted current
'
test_expect_success 'check fully quoted output from diff-tree' '
git diff --name-only HEAD^ HEAD >current &&
- diff -u expect.quoted current
+ test_cmp expect.quoted current
'
@@ -111,28 +111,28 @@ test_expect_success 'setting core.quotepath' '
test_expect_success 'check fully quoted output from ls-files' '
- git ls-files >current && diff -u expect.raw current
+ git ls-files >current && test_cmp expect.raw current
'
test_expect_success 'check fully quoted output from diff-files' '
git diff --name-only >current &&
- diff -u expect.raw current
+ test_cmp expect.raw current
'
test_expect_success 'check fully quoted output from diff-index' '
git diff --name-only HEAD >current &&
- diff -u expect.raw current
+ test_cmp expect.raw current
'
test_expect_success 'check fully quoted output from diff-tree' '
git diff --name-only HEAD^ HEAD >current &&
- diff -u expect.raw current
+ test_cmp expect.raw current
'
diff --git a/t/t3903-stash.sh b/t/t3903-stash.sh
index aa282e1..2d3ee3b 100755
--- a/t/t3903-stash.sh
+++ b/t/t3903-stash.sh
@@ -34,7 +34,7 @@ EOF
test_expect_success 'parents of stash' '
test $(git rev-parse stash^) = $(git rev-parse HEAD) &&
git diff stash^2..stash > output &&
- diff -u output expect
+ test_cmp output expect
'
test_expect_success 'apply needs clean working directory' '
diff --git a/t/t4023-diff-rename-typechange.sh b/t/t4023-diff-rename-typechange.sh
index 255604e..4dbfc6e 100755
--- a/t/t4023-diff-rename-typechange.sh
+++ b/t/t4023-diff-rename-typechange.sh
@@ -57,7 +57,7 @@ test_expect_success 'cross renames to be detected for regular files' '
echo "R100 foo bar"
echo "R100 bar foo"
} | sort >expect &&
- diff -u expect actual
+ test_cmp expect actual
'
@@ -68,7 +68,7 @@ test_expect_success 'cross renames to be detected for typechange' '
echo "R100 foo bar"
echo "R100 bar foo"
} | sort >expect &&
- diff -u expect actual
+ test_cmp expect actual
'
@@ -79,7 +79,7 @@ test_expect_success 'moves and renames' '
echo "R100 foo bar"
echo "T100 foo"
} | sort >expect &&
- diff -u expect actual
+ test_cmp expect actual
'
diff --git a/t/t4024-diff-optimize-common.sh b/t/t4024-diff-optimize-common.sh
index 3c66102..c4d733f 100755
--- a/t/t4024-diff-optimize-common.sh
+++ b/t/t4024-diff-optimize-common.sh
@@ -150,7 +150,7 @@ test_expect_success 'diff -U0' '
do
git diff -U0 file-?$n
done | zc >actual &&
- diff -u expect actual
+ test_cmp expect actual
'
--git a/t/t4025-hunk-header.sh b/t/t4025-hunk-header.sh
index 9ba06b7..7a3dbc1 100755
--- a/t/t4025-hunk-header.sh
+++ b/t/t4025-hunk-header.sh
@@ -37,7 +37,7 @@ test_expect_success 'hunk header truncation with an overly long line' '
echo " A $N$N$N$N$N$N$N$N$N2"
echo " L $N$N$N$N$N$N$N$N$N1"
) >expected &&
- diff -u actual expected
+ test_cmp actual expected
'
diff --git a/t/t4027-diff-submodule.sh b/t/t4027-diff-submodule.sh
index 3d2d081..1fd3fb7 100755
--- a/t/t4027-diff-submodule.sh
+++ b/t/t4027-diff-submodule.sh
@@ -37,17 +37,17 @@ test_expect_success setup '
test_expect_success 'git diff --raw HEAD' '
git diff --raw --abbrev=40 HEAD >actual &&
- diff -u expect actual
+ test_cmp expect actual
'
test_expect_success 'git diff-index --raw HEAD' '
git diff-index --raw HEAD >actual.index &&
- diff -u expect actual.index
+ test_cmp expect actual.index
'
test_expect_success 'git diff-files --raw' '
git diff-files --raw >actual.files &&
- diff -u expect actual.files
+ test_cmp expect actual.files
'
test_done
diff --git a/t/t4105-apply-fuzz.sh b/t/t4105-apply-fuzz.sh
index 0e8d25f..3266e39 100755
--- a/t/t4105-apply-fuzz.sh
+++ b/t/t4105-apply-fuzz.sh
@@ -9,7 +9,7 @@ dotest () {
test_expect_success "$name" "
git checkout-index -f -q -u file &&
git apply $* &&
- diff -u expect file
+ test_cmp expect file
"
}
diff --git a/t/t4125-apply-ws-fuzz.sh b/t/t4125-apply-ws-fuzz.sh
index d6f15be..3b471b6 100755
--- a/t/t4125-apply-ws-fuzz.sh
+++ b/t/t4125-apply-ws-fuzz.sh
@@ -56,7 +56,7 @@ test_expect_success nofix '
git apply --whitespace=nowarn patch-1 &&
# The result should obviously match.
- diff -u file-1 file
+ test_cmp file-1 file
'
test_expect_success 'withfix (forward)' '
@@ -70,7 +70,7 @@ test_expect_success 'withfix (forward)' '
git apply --whitespace=fix patch-0 &&
git apply --whitespace=fix patch-1 &&
- diff -u file-fixed file
+ test_cmp file-fixed file
'
test_expect_success 'withfix (backward)' '
@@ -91,12 +91,12 @@ test_expect_success 'withfix (backward)' '
sed -e /h/d file-fixed >fixed-head &&
sed -e /h/d file >file-head &&
- diff -u fixed-head file-head &&
+ test_cmp fixed-head file-head &&
sed -n -e /h/p file-fixed >fixed-tail &&
sed -n -e /h/p file >file-tail &&
- ! diff -u fixed-tail file-tail
+ ! test_cmp fixed-tail file-tail
'
diff --git a/t/t4150-am-subdir.sh b/t/t4150-am-subdir.sh
index 929d2cb..52069b4 100755
--- a/t/t4150-am-subdir.sh
+++ b/t/t4150-am-subdir.sh
@@ -22,14 +22,14 @@ test_expect_success 'am regularly from stdin' '
git checkout initial &&
git am <patchfile &&
git diff master >actual &&
- diff -u expect actual
+ test_cmp expect actual
'
test_expect_success 'am regularly from file' '
git checkout initial &&
git am patchfile &&
git diff master >actual &&
- diff -u expect actual
+ test_cmp expect actual
'
test_expect_success 'am regularly from stdin in subdirectory' '
@@ -41,7 +41,7 @@ test_expect_success 'am regularly from stdin in subdirectory' '
git am <../patchfile
) &&
git diff master>actual &&
- diff -u expect actual
+ test_cmp expect actual
'
test_expect_success 'am regularly from file in subdirectory' '
@@ -53,7 +53,7 @@ test_expect_success 'am regularly from file in subdirectory' '
git am ../patchfile
) &&
git diff master >actual &&
- diff -u expect actual
+ test_cmp expect actual
'
test_expect_success 'am regularly from file in subdirectory with full path' '
@@ -66,7 +66,7 @@ test_expect_success 'am regularly from file in subdirectory with full path' '
git am "$P/patchfile"
) &&
git diff master >actual &&
- diff -u expect actual
+ test_cmp expect actual
'
test_done
diff --git a/t/t4201-shortlog.sh b/t/t4201-shortlog.sh
index 6d12efb..91ea696 100755
--- a/t/t4201-shortlog.sh
+++ b/t/t4201-shortlog.sh
@@ -45,6 +45,6 @@ A U Thor (5):
EOF
-test_expect_success 'shortlog wrapping' 'diff -u expect out'
+test_expect_success 'shortlog wrapping' 'test_cmp expect out'
test_done
diff --git a/t/t5505-remote.sh b/t/t5505-remote.sh
index 2822a65..ecfc999 100755
--- a/t/t5505-remote.sh
+++ b/t/t5505-remote.sh
@@ -24,7 +24,7 @@ setup_repository () {
tokens_match () {
echo "$1" | tr ' ' '\012' | sort | sed -e '/^$/d' >expect &&
echo "$2" | tr ' ' '\012' | sort | sed -e '/^$/d' >actual &&
- diff -u expect actual
+ test_cmp expect actual
}
check_remote_track () {
@@ -73,7 +73,7 @@ test_expect_success 'add another remote' '
sed -e "/^refs\/remotes\/origin\//d" \
-e "/^refs\/remotes\/second\//d" >actual &&
>expect &&
- diff -u expect actual
+ test_cmp expect actual
)
'
@@ -93,7 +93,7 @@ test_expect_success 'remove remote' '
git for-each-ref "--format=%(refname)" refs/remotes |
sed -e "/^refs\/remotes\/origin\//d" >actual &&
>expect &&
- diff -u expect actual
+ test_cmp expect actual
)
'
diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh
index 9b948c1..6946557 100755
--- a/t/t5510-fetch.sh
+++ b/t/t5510-fetch.sh
@@ -249,7 +249,7 @@ test_expect_success 'bundle should record HEAD correctly' '
do
echo "$(git rev-parse --verify $h) $h"
done >expect &&
- diff -u expect actual
+ test_cmp expect actual
'
diff --git a/t/t5512-ls-remote.sh b/t/t5512-ls-remote.sh
index 6ec5f7c..c0dc949 100755
--- a/t/t5512-ls-remote.sh
+++ b/t/t5512-ls-remote.sh
@@ -24,28 +24,28 @@ test_expect_success setup '
test_expect_success 'ls-remote --tags .git' '
git ls-remote --tags .git >actual &&
- diff -u expected.tag actual
+ test_cmp expected.tag actual
'
test_expect_success 'ls-remote .git' '
git ls-remote .git >actual &&
- diff -u expected.all actual
+ test_cmp expected.all actual
'
test_expect_success 'ls-remote --tags self' '
git ls-remote --tags self >actual &&
- diff -u expected.tag actual
+ test_cmp expected.tag actual
'
test_expect_success 'ls-remote self' '
git ls-remote self >actual &&
- diff -u expected.all actual
+ test_cmp expected.all actual
'
diff --git a/t/t6004-rev-list-path-optim.sh b/t/t6004-rev-list-path-optim.sh
index 80d7198..5dabf1c 100755
--- a/t/t6004-rev-list-path-optim.sh
+++ b/t/t6004-rev-list-path-optim.sh
@@ -45,7 +45,7 @@ test_expect_success 'further setup' '
test_expect_success 'path optimization 2' '
( echo "$side"; echo "$initial" ) >expected &&
git rev-list HEAD -- a >actual &&
- diff -u expected actual
+ test_cmp expected actual
'
test_done
diff --git a/t/t6009-rev-list-parent.sh b/t/t6009-rev-list-parent.sh
index be3d238..f248a32 100755
--- a/t/t6009-rev-list-parent.sh
+++ b/t/t6009-rev-list-parent.sh
@@ -31,7 +31,7 @@ test_expect_failure 'one is ancestor of others and should not be shown' '
git rev-list one --not four >result &&
>expect &&
- diff -u expect result
+ test_cmp expect result
'
diff --git a/t/t6027-merge-binary.sh b/t/t6027-merge-binary.sh
index a7358f7..92ca1f0 100755
--- a/t/t6027-merge-binary.sh
+++ b/t/t6027-merge-binary.sh
@@ -45,7 +45,7 @@ test_expect_success resolve '
false
else
git ls-files -s >current
- diff -u current expect
+ test_cmp current expect
fi
'
@@ -60,7 +60,7 @@ test_expect_success recursive '
false
else
git ls-files -s >current
- diff -u current expect
+ test_cmp current expect
fi
'
diff --git a/t/t6029-merge-subtree.sh b/t/t6029-merge-subtree.sh
index 35d66e8..43f5459 100755
--- a/t/t6029-merge-subtree.sh
+++ b/t/t6029-merge-subtree.sh
@@ -25,7 +25,7 @@ test_expect_success 'subtree available and works like recursive' '
git merge -s subtree side &&
for i in mundo $s world; do echo $i; done >expect &&
- diff -u expect hello
+ test_cmp expect hello
'
diff --git a/t/t7010-setup.sh b/t/t7010-setup.sh
index bc8ab6a..02cf7c5 100755
--- a/t/t7010-setup.sh
+++ b/t/t7010-setup.sh
@@ -18,7 +18,7 @@ test_expect_success 'git add (absolute)' '
git add "$D/a/b/c/d" &&
git ls-files >current &&
echo a/b/c/d >expect &&
- diff -u expect current
+ test_cmp expect current
'
@@ -32,7 +32,7 @@ test_expect_success 'git add (funny relative)' '
) &&
git ls-files >current &&
echo a/e/f >expect &&
- diff -u expect current
+ test_cmp expect current
'
@@ -43,7 +43,7 @@ test_expect_success 'git rm (absolute)' '
git rm -f --cached "$D/a/b/c/d" &&
git ls-files >current &&
echo a/e/f >expect &&
- diff -u expect current
+ test_cmp expect current
'
@@ -57,7 +57,7 @@ test_expect_success 'git rm (funny relative)' '
) &&
git ls-files >current &&
echo a/b/c/d >expect &&
- diff -u expect current
+ test_cmp expect current
'
@@ -67,7 +67,7 @@ test_expect_success 'git ls-files (absolute)' '
git add a &&
git ls-files "$D/a/e/../b" >current &&
echo a/b/c/d >expect &&
- diff -u expect current
+ test_cmp expect current
'
@@ -80,7 +80,7 @@ test_expect_success 'git ls-files (relative #1)' '
git ls-files "../b/c"
) >current &&
echo c/d >expect &&
- diff -u expect current
+ test_cmp expect current
'
@@ -93,7 +93,7 @@ test_expect_success 'git ls-files (relative #2)' '
git ls-files --full-name "../e/f"
) >current &&
echo a/e/f >expect &&
- diff -u expect current
+ test_cmp expect current
'
@@ -126,13 +126,13 @@ test_expect_success 'log using absolute path names' '
git log a/b/c/d >f1.txt &&
git log "$(pwd)/a/b/c/d" >f2.txt &&
- diff -u f1.txt f2.txt
+ test_cmp f1.txt f2.txt
'
test_expect_success 'blame using absolute path names' '
git blame a/b/c/d >f1.txt &&
git blame "$(pwd)/a/b/c/d" >f2.txt &&
- diff -u f1.txt f2.txt
+ test_cmp f1.txt f2.txt
'
test_expect_success 'setup deeper work tree' '
diff --git a/t/t7201-co.sh b/t/t7201-co.sh
index 63915cd..3111baa 100755
--- a/t/t7201-co.sh
+++ b/t/t7201-co.sh
@@ -83,13 +83,13 @@ test_expect_success "checkout with unrelated dirty tree without -m" '
fill 0 1 2 3 4 5 6 7 8 >same &&
cp same kept
git checkout side >messages &&
- diff -u same kept
+ test_cmp same kept
(cat > messages.expect <<EOF
M same
EOF
) &&
touch messages.expect &&
- diff -u messages.expect messages
+ test_cmp messages.expect messages
'
test_expect_success "checkout -m with dirty tree" '
@@ -106,19 +106,19 @@ test_expect_success "checkout -m with dirty tree" '
M one
EOF
) &&
- diff -u expect.messages messages &&
+ test_cmp expect.messages messages &&
fill "M one" "A three" "D two" >expect.master &&
git diff --name-status master >current.master &&
- diff -u expect.master current.master &&
+ test_cmp expect.master current.master &&
fill "M one" >expect.side &&
git diff --name-status side >current.side &&
- diff -u expect.side current.side &&
+ test_cmp expect.side current.side &&
: >expect.index &&
git diff --cached >current.index &&
- diff -u expect.index current.index
+ test_cmp expect.index current.index
'
test_expect_success "checkout -m with dirty tree, renamed" '
@@ -136,7 +136,7 @@ test_expect_success "checkout -m with dirty tree, renamed" '
git checkout -m renamer &&
fill 1 3 4 5 7 8 >expect &&
- diff -u expect uno &&
+ test_cmp expect uno &&
! test -f one &&
git diff --cached >current &&
! test -s current
@@ -161,7 +161,7 @@ test_expect_success 'checkout -m with merge conflict' '
git diff master:one :3:uno |
sed -e "1,/^@@/d" -e "/^ /d" -e "s/^-/d/" -e "s/^+/a/" >current &&
fill d2 aT d7 aS >expect &&
- diff -u current expect &&
+ test_cmp current expect &&
git diff --cached two >current &&
! test -s current
'
@@ -178,7 +178,7 @@ If you want to create a new branch from this checkout, you may do so
HEAD is now at 7329388... Initial A one, A two
EOF
) &&
- diff -u messages.expect messages &&
+ test_cmp messages.expect messages &&
H=$(git rev-parse --verify HEAD) &&
M=$(git show-ref -s --verify refs/heads/master) &&
test "z$H" = "z$M" &&
diff --git a/t/t7501-commit.sh b/t/t7501-commit.sh
index 361886c..c0288f3 100755
--- a/t/t7501-commit.sh
+++ b/t/t7501-commit.sh
@@ -203,7 +203,7 @@ test_expect_success 'sign off (1)' '
git var GIT_COMMITTER_IDENT |
sed -e "s/>.*/>/" -e "s/^/Signed-off-by: /"
) >expected &&
- diff -u expected actual
+ test_cmp expected actual
'
@@ -223,7 +223,7 @@ $existing" &&
git var GIT_COMMITTER_IDENT |
sed -e "s/>.*/>/" -e "s/^/Signed-off-by: /"
) >expected &&
- diff -u expected actual
+ test_cmp expected actual
'
@@ -240,7 +240,7 @@ test_expect_success 'multiple -m' '
echo
echo three
) >expected &&
- diff -u expected actual
+ test_cmp expected actual
'
@@ -301,12 +301,12 @@ test_expect_success 'same tree (merge and amend merge)' '
git merge -s ours side -m "empty ok" &&
git diff HEAD^ HEAD >actual &&
: >expected &&
- diff -u expected actual &&
+ test_cmp expected actual &&
git commit --amend -m "empty really ok" &&
git diff HEAD^ HEAD >actual &&
: >expected &&
- diff -u expected actual
+ test_cmp expected actual
'
@@ -323,7 +323,7 @@ test_expect_success 'amend using the message from another commit' '
git commit --allow-empty --amend -C "$old" &&
git show --pretty="format:%ad %s" "$old" >expected &&
git show --pretty="format:%ad %s" HEAD >actual &&
- diff -u expected actual
+ test_cmp expected actual
'
@@ -341,7 +341,7 @@ test_expect_success 'amend using the message from a commit named with tag' '
git commit --allow-empty --amend -C tagged-old &&
git show --pretty="format:%ad %s" "$old" >expected &&
git show --pretty="format:%ad %s" HEAD >actual &&
- diff -u expected actual
+ test_cmp expected actual
'
diff --git a/t/t7502-commit.sh b/t/t7502-commit.sh
index b780fdd..284c941 100755
--- a/t/t7502-commit.sh
+++ b/t/t7502-commit.sh
@@ -85,7 +85,7 @@ test_expect_success 'verbose' '
git add negative &&
git status -v | sed -ne "/^diff --git /p" >actual &&
echo "diff --git a/negative b/negative" >expect &&
- diff -u expect actual
+ test_cmp expect actual
'
@@ -95,7 +95,7 @@ test_expect_success 'cleanup commit messages (verbatim,-t)' '
{ echo;echo "# text";echo; } >expect &&
git commit --cleanup=verbatim -t expect -a &&
git cat-file -p HEAD |sed -e "1,/^\$/d" |head -n 3 >actual &&
- diff -u expect actual
+ test_cmp expect actual
'
@@ -104,7 +104,7 @@ test_expect_success 'cleanup commit messages (verbatim,-F)' '
echo >>negative &&
git commit --cleanup=verbatim -F expect -a &&
git cat-file -p HEAD |sed -e "1,/^\$/d">actual &&
- diff -u expect actual
+ test_cmp expect actual
'
@@ -113,7 +113,7 @@ test_expect_success 'cleanup commit messages (verbatim,-m)' '
echo >>negative &&
git commit --cleanup=verbatim -m "$(cat expect)" -a &&
git cat-file -p HEAD |sed -e "1,/^\$/d">actual &&
- diff -u expect actual
+ test_cmp expect actual
'
@@ -124,7 +124,7 @@ test_expect_success 'cleanup commit messages (whitespace,-F)' '
echo "# text" >expect &&
git commit --cleanup=whitespace -F text -a &&
git cat-file -p HEAD |sed -e "1,/^\$/d">actual &&
- diff -u expect actual
+ test_cmp expect actual
'
@@ -135,7 +135,7 @@ test_expect_success 'cleanup commit messages (strip,-F)' '
echo sample >expect &&
git commit --cleanup=strip -F text -a &&
git cat-file -p HEAD |sed -e "1,/^\$/d">actual &&
- diff -u expect actual
+ test_cmp expect actual
'
@@ -150,7 +150,7 @@ test_expect_success 'cleanup commit messages (strip,-F,-e)' '
{ echo;echo sample;echo; } >text &&
git commit -e -F text -a &&
head -n 4 .git/COMMIT_EDITMSG >actual &&
- diff -u expect actual
+ test_cmp expect actual
'
diff --git a/t/t7502-status.sh b/t/t7502-status.sh
index 70b802b..cd08516 100755
--- a/t/t7502-status.sh
+++ b/t/t7502-status.sh
@@ -146,7 +146,7 @@ cat <<EOF >expect
EOF
test_expect_success 'status of partial commit excluding new file in index' '
git status dir1/modified >output &&
- diff -u expect output
+ test_cmp expect output
'
test_done
diff --git a/t/t7600-merge.sh b/t/t7600-merge.sh
index 219411f..56869ac 100755
--- a/t/t7600-merge.sh
+++ b/t/t7600-merge.sh
@@ -108,7 +108,7 @@ create_merge_msgs() {
}
verify_diff() {
- if ! diff -u "$1" "$2"
+ if ! test_cmp "$1" "$2"
then
echo "$3"
false
diff --git a/t/t8003-blame.sh b/t/t8003-blame.sh
index db51b3a..966bb0a 100755
--- a/t/t8003-blame.sh
+++ b/t/t8003-blame.sh
@@ -112,7 +112,7 @@ test_expect_success 'blame wholesale copy' '
echo mouse-Second
echo mouse-Third
} >expected &&
- diff -u expected current
+ test_cmp expected current
'
@@ -125,7 +125,7 @@ test_expect_success 'blame wholesale copy and more' '
echo cow-Fifth
echo mouse-Third
} >expected &&
- diff -u expected current
+ test_cmp expected current
'
diff --git a/t/t9001-send-email.sh b/t/t9001-send-email.sh
index cbbfa9c..c0973b4 100755
--- a/t/t9001-send-email.sh
+++ b/t/t9001-send-email.sh
@@ -81,7 +81,7 @@ test_expect_success 'Show all headers' '
-e "s/^\(Message-Id:\).*/\1 MESSAGE-ID-STRING/" \
-e "s/^\(X-Mailer:\).*/\1 X-MAILER-STRING/" \
>actual-show-all-headers &&
- diff -u expected-show-all-headers actual-show-all-headers
+ test_cmp expected-show-all-headers actual-show-all-headers
'
z8=zzzzzzzz
diff --git a/t/t9116-git-svn-log.sh b/t/t9116-git-svn-log.sh
index 902ed41..e1e8bdf 100755
--- a/t/t9116-git-svn-log.sh
+++ b/t/t9116-git-svn-log.sh
@@ -55,74 +55,74 @@ printf 'r1 \nr2 \nr4 \n' > expected-range-r1-r2-r4
test_expect_success 'test ascending revision range' "
git reset --hard trunk &&
- git svn log -r 1:4 | grep '^r[0-9]' | cut -d'|' -f1 | diff -u expected-range-r1-r2-r4 -
+ git svn log -r 1:4 | grep '^r[0-9]' | cut -d'|' -f1 | test_cmp expected-range-r1-r2-r4 -
"
printf 'r4 \nr2 \nr1 \n' > expected-range-r4-r2-r1
test_expect_success 'test descending revision range' "
git reset --hard trunk &&
- git svn log -r 4:1 | grep '^r[0-9]' | cut -d'|' -f1 | diff -u expected-range-r4-r2-r1 -
+ git svn log -r 4:1 | grep '^r[0-9]' | cut -d'|' -f1 | test_cmp expected-range-r4-r2-r1 -
"
printf 'r1 \nr2 \n' > expected-range-r1-r2
test_expect_success 'test ascending revision range with unreachable revision' "
git reset --hard trunk &&
- git svn log -r 1:3 | grep '^r[0-9]' | cut -d'|' -f1 | diff -u expected-range-r1-r2 -
+ git svn log -r 1:3 | grep '^r[0-9]' | cut -d'|' -f1 | test_cmp expected-range-r1-r2 -
"
printf 'r2 \nr1 \n' > expected-range-r2-r1
test_expect_success 'test descending revision range with unreachable revision' "
git reset --hard trunk &&
- git svn log -r 3:1 | grep '^r[0-9]' | cut -d'|' -f1 | diff -u expected-range-r2-r1 -
+ git svn log -r 3:1 | grep '^r[0-9]' | cut -d'|' -f1 | test_cmp expected-range-r2-r1 -
"
printf 'r2 \n' > expected-range-r2
test_expect_success 'test ascending revision range with unreachable upper boundary revision and 1 commit' "
git reset --hard trunk &&
- git svn log -r 2:3 | grep '^r[0-9]' | cut -d'|' -f1 | diff -u expected-range-r2 -
+ git svn log -r 2:3 | grep '^r[0-9]' | cut -d'|' -f1 | test_cmp expected-range-r2 -
"
test_expect_success 'test descending revision range with unreachable upper boundary revision and 1 commit' "
git reset --hard trunk &&
- git svn log -r 3:2 | grep '^r[0-9]' | cut -d'|' -f1 | diff -u expected-range-r2 -
+ git svn log -r 3:2 | grep '^r[0-9]' | cut -d'|' -f1 | test_cmp expected-range-r2 -
"
printf 'r4 \n' > expected-range-r4
test_expect_success 'test ascending revision range with unreachable lower boundary revision and 1 commit' "
git reset --hard trunk &&
- git svn log -r 3:4 | grep '^r[0-9]' | cut -d'|' -f1 | diff -u expected-range-r4 -
+ git svn log -r 3:4 | grep '^r[0-9]' | cut -d'|' -f1 | test_cmp expected-range-r4 -
"
test_expect_success 'test descending revision range with unreachable lower boundary revision and 1 commit' "
git reset --hard trunk &&
- git svn log -r 4:3 | grep '^r[0-9]' | cut -d'|' -f1 | diff -u expected-range-r4 -
+ git svn log -r 4:3 | grep '^r[0-9]' | cut -d'|' -f1 | test_cmp expected-range-r4 -
"
printf -- '------------------------------------------------------------------------\n' > expected-separator
test_expect_success 'test ascending revision range with unreachable boundary revisions and no commits' "
git reset --hard trunk &&
- git svn log -r 5:6 | diff -u expected-separator -
+ git svn log -r 5:6 | test_cmp expected-separator -
"
test_expect_success 'test descending revision range with unreachable boundary revisions and no commits' "
git reset --hard trunk &&
- git svn log -r 6:5 | diff -u expected-separator -
+ git svn log -r 6:5 | test_cmp expected-separator -
"
test_expect_success 'test ascending revision range with unreachable boundary revisions and 1 commit' "
git reset --hard trunk &&
- git svn log -r 3:5 | grep '^r[0-9]' | cut -d'|' -f1 | diff -u expected-range-r4 -
+ git svn log -r 3:5 | grep '^r[0-9]' | cut -d'|' -f1 | test_cmp expected-range-r4 -
"
test_expect_success 'test descending revision range with unreachable boundary revisions and 1 commit' "
git reset --hard trunk &&
- git svn log -r 5:3 | grep '^r[0-9]' | cut -d'|' -f1 | diff -u expected-range-r4 -
+ git svn log -r 5:3 | grep '^r[0-9]' | cut -d'|' -f1 | test_cmp expected-range-r4 -
"
test_done
diff --git a/t/t9200-git-cvsexportcommit.sh b/t/t9200-git-cvsexportcommit.sh
index 58c59ed..42b144b 100755
--- a/t/t9200-git-cvsexportcommit.sh
+++ b/t/t9200-git-cvsexportcommit.sh
@@ -37,7 +37,7 @@ check_entries () {
else
printf '%s\n' "$2" | tr '|' '\012' >expected
fi
- diff -u expected actual
+ test_cmp expected actual
}
test_expect_success \
@@ -257,8 +257,8 @@ test_expect_success '-w option should work with relative GIT_DIR' '
(cd "$GIT_DIR" &&
GIT_DIR=. git cvsexportcommit -w "$CVSWORK" -c $id &&
check_entries "$CVSWORK/W" "file1.txt/1.1/|file2.txt/1.1/" &&
- diff -u "$CVSWORK/W/file1.txt" ../W/file1.txt &&
- diff -u "$CVSWORK/W/file2.txt" ../W/file2.txt
+ test_cmp "$CVSWORK/W/file1.txt" ../W/file1.txt &&
+ test_cmp "$CVSWORK/W/file2.txt" ../W/file2.txt
)
'
@@ -279,9 +279,9 @@ test_expect_success 'check files before directories' '
git cvsexportcommit -w "$CVSWORK" -c $id &&
check_entries "$CVSWORK/E" "DS/1.1/|newfile5.txt/1.1/" &&
check_entries "$CVSWORK" "DS/1.1/|release-notes/1.2/" &&
- diff -u "$CVSWORK/DS" DS &&
- diff -u "$CVSWORK/E/DS" E/DS &&
- diff -u "$CVSWORK/release-notes" release-notes
+ test_cmp "$CVSWORK/DS" DS &&
+ test_cmp "$CVSWORK/E/DS" E/DS &&
+ test_cmp "$CVSWORK/release-notes" release-notes
'
@@ -293,7 +293,7 @@ test_expect_success 'commit a file with leading spaces in the name' '
id=$(git rev-parse HEAD) &&
git cvsexportcommit -w "$CVSWORK" -c $id &&
check_entries "$CVSWORK" " space/1.1/|DS/1.1/|release-notes/1.2/" &&
- diff -u "$CVSWORK/ space" " space"
+ test_cmp "$CVSWORK/ space" " space"
'
diff --git a/t/test-lib.sh b/t/test-lib.sh
index 6aea0ea..268b26c 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -42,6 +42,7 @@ export GIT_MERGE_VERBOSITY
export GIT_AUTHOR_EMAIL GIT_AUTHOR_NAME
export GIT_COMMITTER_EMAIL GIT_COMMITTER_NAME
export EDITOR VISUAL
+GIT_TEST_CMP=${GIT_TEST_CMP:-diff -u}
# Protect ourselves from common misconfiguration to export
# CDPATH into the environment
@@ -302,6 +303,23 @@ test_must_fail () {
test $? -gt 0 -a $? -le 128
}
+# test_cmp is a helper function to compare actual and expected output.
+# You can use it like:
+#
+# test_expect_success 'foo works' '
+# echo expected >expected &&
+# foo >actual &&
+# test_cmp expected actual
+# '
+#
+# This could be written as either "cmp" or "diff -u", but:
+# - cmp's output is not nearly as easy to read as diff -u
+# - not all diff versions understand "-u"
+
+test_cmp() {
+ $GIT_TEST_CMP "$@"
+}
+
# Most tests can use the created repository, but some may need to create more.
# Usage: test_create_repo <directory>
test_create_repo () {
--
1.5.4.4.543.g30fdd.dirty
^ permalink raw reply related [relevance 1%]
* Re: git-submodule getting submodules from the parent repository
@ 2008-04-01 23:10 3% ` Sam Vilain
0 siblings, 0 replies; 200+ results
From: Sam Vilain @ 2008-04-01 23:10 UTC (permalink / raw)
To: Avery Pennarun; +Cc: git
Avery Pennarun wrote:
>> Well, that would create a lot of unnecessary work when cloning.
>> Partitioning by project is a natural way to divide the projects up.
>
> What unnecessary work do you mean?
A full clone takes a few shortcuts, especially over dumb transports like
HTTP. I think there might be shortcuts in the git-daemon code as well.
Forcing these to be partial might make these full fetches involve more
time.
>> However, what you are suggesting should IMHO be allowed to work. In
>> particular, if the submodule path is ".", then I think there's a good
>> case that they should come from within the same project. If it's a
>> relative URL, it should initialize based on the remote URL that was used
>> for the original fetch (or, rather, the remote URL for the current branch).
> I agree, there's no reason to take away the existing functionality of
> allowing split repos. I was more suggesting a new functionality so
> that splitting isn't *required*.
Yes - I look forward to a patch.
>> This push failure thing is regrettable; however it's not clear which
>> branch name the submodules should get. A given commit might exist on
>> several branches, which one do you choose to name it?
> One option is to make a simple "git push origin" operation fail if
> you're not on any branch; iirc, if you try that now, it just silently
> *succeeds* without uploading anything at all, which is one reason I so
> frequently screw it up.
Sounds workable.
> Alternatively, is there a reason I can't
> upload an object *without* giving it a branch name? I guess that
> would cause problems with garbage collection.
You've answered your own question there.
>> There is also a Google Summer of Code project for this - see
>> http://git.or.cz/gitwiki/SoC2008Ideas#head-9215572f23513542a23d3555aa72775bc4b91038
>
> ok. I was hoping it wouldn't be so hard as to require an entire SoC
> project, since using --alternate when checking out the child repo
> shouldn't be too hard.
If you think it is simpler, then I'm sure that submodules users would
appreciate you sharing your ideas as a patch. Sorry if I am starting to
sound like a parrot ;-).
Sam.
^ permalink raw reply [relevance 3%]
* Re: Achieving efficient storage of weirdly structured repos
@ 2008-04-03 21:11 3% ` Linus Torvalds
2008-04-04 23:30 1% ` Roman Shaposhnik
0 siblings, 1 reply; 200+ results
From: Linus Torvalds @ 2008-04-03 21:11 UTC (permalink / raw)
To: Roman Shaposhnik; +Cc: git
On Thu, 3 Apr 2008, Roman Shaposhnik wrote:
>
> The repository was created using hg2git (the one based on git-fast-import)
> and it was GC'ed and REPACK'ed just in case.
Before going any further - exactly _how_ was it repacked?
In particular, when using importers that do partial packing on their own
(and any "git-fastimport" user is that by definition - and I think
hg2git does that), at the end of it all you have to make sure to repack in
a way where the repacking will totally discard the import-time packfiles.
IOW, that's one of the very few times you should use "-f" to git repack.
It's usually also a good place to make sure that since you ignore the old
packing information, it's best to also make sure that the new packing info
is good by using a bigger window (and perhaps a bigger depth). That makes
the packing much slower, of course, but this is meant to be a one-time
event.
So try something like
git repack -a -d -f --depth=100 --window=100
if you have a good CPU and plenty of memory.
> The last item (trees) also seem to take the most space and the most
> reasonable explanation that I can offer is that NetBeans repository has
> a really weird structure where they have approximately 700 (yes, seven
> hundred!) top-level subdirectories there. They are clearly
> Submodules-shy, but that's another issue that I will need to address
> with them.
Trees taking the biggest amount of space is not unheard of, and it may
also be that the name heuristics (for finding good packing partners) could
be failign, which would result in a much bigger pack than necessary.
So if you already did an aggressive repack like the above, I'd happily
take a look at whether maybe it's bad heuristics for finding tree objects
to pair up for delta-compression. Do you have a place where you can put
that repo for people to clone and look at?
Linus
^ permalink raw reply [relevance 3%]
* Re: Achieving efficient storage of weirdly structured repos
2008-04-03 21:11 3% ` Linus Torvalds
@ 2008-04-04 23:30 1% ` Roman Shaposhnik
0 siblings, 0 replies; 200+ results
From: Roman Shaposhnik @ 2008-04-04 23:30 UTC (permalink / raw)
To: Linus Torvalds; +Cc: git
Hi Linus!
On Thu, 2008-04-03 at 14:11 -0700, Linus Torvalds wrote:
>
> On Thu, 3 Apr 2008, Roman Shaposhnik wrote:
> >
> > The repository was created using hg2git (the one based on git-fast-import)
> > and it was GC'ed and REPACK'ed just in case.
>
> Before going any further - exactly _how_ was it repacked?
I believe it was the following two steps:
$ git gc --aggressive
$ git repack
> In particular, when using importers that do partial packing on their own
> (and any "git-fastimport" user is that by definition - and I think
> hg2git does that), at the end of it all you have to make sure to repack in
> a way where the repacking will totally discard the import-time packfiles.
Good point. Speaking of which: do you have an FAQ for importers? The
entries in the official FAQ (http://git.or.cz/gitwiki/GitFaq#head-929a8825d04dde226c2530f5337d3b3ed8dcc7ce)
seem a bit stale for such an important issue. After all, importing from
an existing SCM is what usually forms a first time impression of Git's
effectiveness.
> IOW, that's one of the very few times you should use "-f" to git repack.
Got it!
> It's usually also a good place to make sure that since you ignore the old
> packing information, it's best to also make sure that the new packing info
> is good by using a bigger window (and perhaps a bigger depth). That makes
> the packing much slower, of course, but this is meant to be a one-time
> event.
>
> So try something like
>
> git repack -a -d -f --depth=100 --window=100
>
> if you have a good CPU and plenty of memory.
That turned out to be a perfect suggestion. Thank you. I'm now the
happiest camper ever. And I'm also also pretty dumbfounded ;-)
Here's what happened.
I started with a a repository filled with "loose" (one object per file)
objects (the reason I needed it was for the ease of sleuthing through
individual objects and it was created by git-unpack-objects from that
initial 1.1Gb pack). And I tried to pack it exactly like you
suggested:
$ git-pack-objects --depth=100 --window=100 --delta-base-offset --progress pack < objects
Generating pack...
Counting objects: 1096305
Done counting 1159628 objects.
Deltifying 1159628 objects...
100% (1159628/1159628) done
Writing 1159628 objects...
dd134c407324dc55b0cd2aa3a9e1b3420c2bba3f
Total 1159628 (delta 386980), reused 0 (delta 0)
and it payed off reasonably well:
$ du -s NB-clone
670M NB-clone
It still was bigger than the Mercurial repository but at least it got
2 times smaller than the original result of hg2git. Now, if it wasn't
for a friend of mine, I probably would've stopped there. But he
showed up and saved the day ;-) His comments made me try something
that I didn't consider to be of any use -- repacking a freshly packed
pack with the *same* --depth=100 --window=100:
$ git repack -a -f --window=100 --depth=100
Generating pack...
Counting objects: 1056829
Done counting 1159628 objects.
Deltifying 1159628 objects...
100% (1159628/1159628) done
Writing 1159628 objects...
100% (1159628/1159628) done
Total 1159628 (delta 614516), reused 0 (delta 0)
Pack pack-dd134c407324dc55b0cd2aa3a9e1b3420c2bba3f created.
And then, a miracle occurred:
$ du -sh NB-small
268M NB-small
Now, don't get me wrong: I'm as happy as a clam. The repository is now
*smaller* than the Mercurial's and because the structure of the
tree is so weird Git gets major points here. The only question that
is still bothering me is: how did it happen? Why did repacking
a repository with exactly the same set of objects and the only
difference being where these objects resided (former case filesystem,
the later case an intermediate pack) made so huge a difference?
Please help!
> > The last item (trees) also seem to take the most space and the most
> > reasonable explanation that I can offer is that NetBeans repository has
> > a really weird structure where they have approximately 700 (yes, seven
> > hundred!) top-level subdirectories there. They are clearly
> > Submodules-shy, but that's another issue that I will need to address
> > with them.
>
> Trees taking the biggest amount of space is not unheard of, and it may
> also be that the name heuristics (for finding good packing partners) could
> be failign, which would result in a much bigger pack than necessary.
Is there any documentation that describes the heuristics involved in
creating a pack?
> So if you already did an aggressive repack like the above, I'd happily
> take a look at whether maybe it's bad heuristics for finding tree objects
> to pair up for delta-compression. Do you have a place where you can put
> that repo for people to clone and look at?
Unfortunately I don't. The only thing I can do is I can always create
a *.tar.bz2 and put and on Sun's ftp server. Actually, that makes me
wonder: is there any public Git hosting available such that publishing
a hefty repository for the forensic purposes only wouldn't violate their
terms of use?
Thanks,
Roman.
P.S. Oh, and here's one extra tiny question that I also have: what
does the output:
Total 1159628 (delta 614516), reused 0 (delta 0)
really mean?
^ permalink raw reply [relevance 1%]
* [PATCH 8/8] Fix tests breaking when checkout path contains shell metacharacters
@ 2008-04-09 1:30 10% ` Bryan Donlan
0 siblings, 0 replies; 200+ results
From: Bryan Donlan @ 2008-04-09 1:30 UTC (permalink / raw)
To: git; +Cc: Johannes Sixt, Adam Roben, gitster, Bryan Donlan
This fixes the remainder of the issues where the test script itself is at
fault for failing when the git checkout path contains whitespace or other
shell metacharacters.
Signed-off-by: Bryan Donlan <bdonlan@fushizen.net>
---
t/t0000-basic.sh | 4 +-
t/t0001-init.sh | 2 +-
t/t1020-subdirectory.sh | 24 +++++-----
t/t1501-worktree.sh | 14 +++---
t/t3050-subprojects-fetch.sh | 2 +-
t/t3404-rebase-interactive.sh | 3 +-
t/t5500-fetch-pack.sh | 2 +-
t/t5512-ls-remote.sh | 2 +-
t/t5516-fetch-push.sh | 8 ++--
t/t5700-clone-reference.sh | 4 +-
t/t5710-info-alternate.sh | 4 +-
t/t7003-filter-branch.sh | 4 +-
t/t7010-setup.sh | 2 +-
t/t7300-clean.sh | 2 +-
t/t7501-commit.sh | 8 ++--
t/t7504-commit-msg-hook.sh | 20 +++++-----
t/t7505-prepare-commit-msg-hook.sh | 14 +++---
t/t9100-git-svn-basic.sh | 54 ++++++++++++------------
t/t9101-git-svn-props.sh | 6 +-
t/t9102-git-svn-deep-rmdir.sh | 6 +-
t/t9103-git-svn-tracked-directory-removed.sh | 30 +++++++-------
t/t9104-git-svn-follow-parent.sh | 50 +++++++++++-----------
t/t9105-git-svn-commit-diff.sh | 12 +++---
t/t9106-git-svn-commit-diff-clobber.sh | 14 +++---
t/t9106-git-svn-dcommit-clobber-series.sh | 6 +-
t/t9107-git-svn-migrate.sh | 48 +++++++++++-----------
t/t9108-git-svn-glob.sh | 8 ++--
t/t9110-git-svn-use-svm-props.sh | 8 ++--
t/t9111-git-svn-use-svnsync-props.sh | 8 ++--
t/t9112-git-svn-md5less-file.sh | 4 +-
t/t9113-git-svn-dcommit-new-file.sh | 6 +-
t/t9114-git-svn-dcommit-merge.sh | 4 +-
t/t9115-git-svn-dcommit-funky-renames.sh | 4 +-
t/t9116-git-svn-log.sh | 4 +-
t/t9117-git-svn-init-clone.sh | 10 ++--
t/t9118-git-svn-funky-branch-names.sh | 12 +++---
t/t9120-git-svn-clone-with-percent-escapes.sh | 2 +-
t/t9500-gitweb-standalone-no-errors.sh | 13 +++---
38 files changed, 214 insertions(+), 214 deletions(-)
diff --git a/t/t0000-basic.sh b/t/t0000-basic.sh
index 27b54cb..690f80a 100755
--- a/t/t0000-basic.sh
+++ b/t/t0000-basic.sh
@@ -305,10 +305,10 @@ test_expect_success 'absolute path works as expected' '
file="$dir"/index &&
test "$file" = "$(test-absolute-path $dir2/index)" &&
basename=blub &&
- test "$dir/$basename" = $(cd .git && test-absolute-path $basename) &&
+ test "$dir/$basename" = "$(cd .git && test-absolute-path "$basename")" &&
ln -s ../first/file .git/syml &&
sym="$(cd first; pwd -P)"/file &&
- test "$sym" = "$(test-absolute-path $dir2/syml)"
+ test "$sym" = "$(test-absolute-path "$dir2/syml")"
'
test_expect_success 'very long name in the index handled sanely' '
diff --git a/t/t0001-init.sh b/t/t0001-init.sh
index b0289e3..22eb735 100755
--- a/t/t0001-init.sh
+++ b/t/t0001-init.sh
@@ -95,7 +95,7 @@ test_expect_success 'GIT_DIR & GIT_WORK_TREE (1)' '
(
unset GIT_CONFIG
mkdir git-dir-wt-1.git &&
- GIT_WORK_TREE=$(pwd) GIT_DIR=git-dir-wt-1.git git init
+ GIT_WORK_TREE="$(pwd)" GIT_DIR=git-dir-wt-1.git git init
) &&
check_config git-dir-wt-1.git false "$(pwd)"
'
diff --git a/t/t1020-subdirectory.sh b/t/t1020-subdirectory.sh
index b9cef34..20a1e82 100755
--- a/t/t1020-subdirectory.sh
+++ b/t/t1020-subdirectory.sh
@@ -16,12 +16,12 @@ test_expect_success setup '
cp one original.one &&
cp dir/two original.two
'
-HERE=`pwd`
+HERE="$(pwd)"
LF='
'
test_expect_success 'update-index and ls-files' '
- cd $HERE &&
+ cd "$HERE" &&
git update-index --add one &&
case "`git ls-files`" in
one) echo ok one ;;
@@ -41,7 +41,7 @@ test_expect_success 'update-index and ls-files' '
'
test_expect_success 'cat-file' '
- cd $HERE &&
+ cd "$HERE" &&
two=`git ls-files -s dir/two` &&
two=`expr "$two" : "[0-7]* \\([0-9a-f]*\\)"` &&
echo "$two" &&
@@ -54,7 +54,7 @@ test_expect_success 'cat-file' '
rm -f actual dir/actual
test_expect_success 'diff-files' '
- cd $HERE &&
+ cd "$HERE" &&
echo a >>one &&
echo d >>dir/two &&
case "`git diff-files --name-only`" in
@@ -74,7 +74,7 @@ test_expect_success 'diff-files' '
'
test_expect_success 'write-tree' '
- cd $HERE &&
+ cd "$HERE" &&
top=`git write-tree` &&
echo $top &&
cd dir &&
@@ -84,7 +84,7 @@ test_expect_success 'write-tree' '
'
test_expect_success 'checkout-index' '
- cd $HERE &&
+ cd "$HERE" &&
git checkout-index -f -u one &&
cmp one original.one &&
cd dir &&
@@ -93,7 +93,7 @@ test_expect_success 'checkout-index' '
'
test_expect_success 'read-tree' '
- cd $HERE &&
+ cd "$HERE" &&
rm -f one dir/two &&
tree=`git write-tree` &&
git read-tree --reset -u "$tree" &&
@@ -107,27 +107,27 @@ test_expect_success 'read-tree' '
'
test_expect_success 'no file/rev ambiguity check inside .git' '
- cd $HERE &&
+ cd "$HERE" &&
git commit -a -m 1 &&
- cd $HERE/.git &&
+ cd "$HERE"/.git &&
git show -s HEAD
'
test_expect_success 'no file/rev ambiguity check inside a bare repo' '
- cd $HERE &&
+ cd "$HERE" &&
git clone -s --bare .git foo.git &&
cd foo.git && GIT_DIR=. git show -s HEAD
'
# This still does not work as it should...
: test_expect_success 'no file/rev ambiguity check inside a bare repo' '
- cd $HERE &&
+ cd "$HERE" &&
git clone -s --bare .git foo.git &&
cd foo.git && git show -s HEAD
'
test_expect_success 'detection should not be fooled by a symlink' '
- cd $HERE &&
+ cd "$HERE" &&
rm -fr foo.git &&
git clone -s .git another &&
ln -s another yetanother &&
diff --git a/t/t1501-worktree.sh b/t/t1501-worktree.sh
index 7ee3820..ffb77b6 100755
--- a/t/t1501-worktree.sh
+++ b/t/t1501-worktree.sh
@@ -48,8 +48,8 @@ test_rev_parse 'subdirectory' false false true sub/dir/
cd ../../.. || exit 1
say "core.worktree = absolute path"
-export GIT_DIR=$(pwd)/repo.git
-export GIT_CONFIG=$GIT_DIR/config
+export GIT_DIR="$(pwd)/repo.git"
+export GIT_CONFIG="$GIT_DIR/config"
git config core.worktree "$(pwd)/work"
test_rev_parse 'outside' false false false
cd work || exit 1
@@ -59,8 +59,8 @@ test_rev_parse 'subdirectory' false false true sub/dir/
cd ../../.. || exit 1
say "GIT_WORK_TREE=relative path (override core.worktree)"
-export GIT_DIR=$(pwd)/repo.git
-export GIT_CONFIG=$GIT_DIR/config
+export GIT_DIR="$(pwd)/repo.git"
+export GIT_CONFIG="$GIT_DIR/config"
git config core.worktree non-existent
export GIT_WORK_TREE=work
test_rev_parse 'outside' false false false
@@ -75,9 +75,9 @@ cd ../../.. || exit 1
mv work repo.git/work
say "GIT_WORK_TREE=absolute path, work tree below git dir"
-export GIT_DIR=$(pwd)/repo.git
-export GIT_CONFIG=$GIT_DIR/config
-export GIT_WORK_TREE=$(pwd)/repo.git/work
+export GIT_DIR="$(pwd)/repo.git"
+export GIT_CONFIG="$GIT_DIR/config"
+export GIT_WORK_TREE="$(pwd)/repo.git/work"
test_rev_parse 'outside' false false false
cd repo.git || exit 1
test_rev_parse 'in repo.git' false true false
diff --git a/t/t3050-subprojects-fetch.sh b/t/t3050-subprojects-fetch.sh
index 2b21b10..4261e96 100755
--- a/t/t3050-subprojects-fetch.sh
+++ b/t/t3050-subprojects-fetch.sh
@@ -20,7 +20,7 @@ test_expect_success setup '
'
test_expect_success clone '
- git clone file://`pwd`/.git cloned &&
+ git clone "file://$(pwd)/.git" cloned &&
(git rev-parse HEAD; git ls-files -s) >expected &&
(
cd cloned &&
diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh
index 9cf873f..b9e3dbd 100755
--- a/t/t3404-rebase-interactive.sh
+++ b/t/t3404-rebase-interactive.sh
@@ -91,9 +91,8 @@ for line in $FAKE_LINES; do
done
EOF
+test_set_editor "$(pwd)/fake-editor.sh"
chmod a+x fake-editor.sh
-VISUAL="$(pwd)/fake-editor.sh"
-export VISUAL
test_expect_success 'no changes are a nop' '
git rebase -i F &&
diff --git a/t/t5500-fetch-pack.sh b/t/t5500-fetch-pack.sh
index 788b4a5..c52707b 100755
--- a/t/t5500-fetch-pack.sh
+++ b/t/t5500-fetch-pack.sh
@@ -129,7 +129,7 @@ pull_to_client 2nd "B" $((64*3))
pull_to_client 3rd "A" $((1*3)) # old fails
-test_expect_success "clone shallow" "git-clone --depth 2 file://`pwd`/. shallow"
+test_expect_success "clone shallow" 'git-clone --depth 2 "file://$(pwd)/." shallow'
(cd shallow; git count-objects -v) > count.shallow
diff --git a/t/t5512-ls-remote.sh b/t/t5512-ls-remote.sh
index c0dc949..1dd8eed 100755
--- a/t/t5512-ls-remote.sh
+++ b/t/t5512-ls-remote.sh
@@ -17,7 +17,7 @@ test_expect_success setup '
git show-ref -d | sed -e "s/ / /"
) >expected.all &&
- git remote add self $(pwd)/.git
+ git remote add self "$(pwd)/.git"
'
diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh
index 793ffc6..6e8cb9e 100755
--- a/t/t5516-fetch-push.sh
+++ b/t/t5516-fetch-push.sh
@@ -103,9 +103,9 @@ test_expect_success 'fetch with wildcard' '
test_expect_success 'fetch with insteadOf' '
mk_empty &&
(
- TRASH=$(pwd) &&
+ TRASH="$(pwd)" &&
cd testrepo &&
- git config url./$TRASH/.insteadOf trash/
+ git config "url./$TRASH/.insteadOf" trash/ &&
git config remote.up.url trash/. &&
git config remote.up.fetch "refs/heads/*:refs/remotes/origin/*" &&
git fetch up &&
@@ -145,8 +145,8 @@ test_expect_success 'push with wildcard' '
test_expect_success 'push with insteadOf' '
mk_empty &&
- TRASH=$(pwd) &&
- git config url./$TRASH/.insteadOf trash/ &&
+ TRASH="$(pwd)" &&
+ git config "url./$TRASH/.insteadOf" trash/ &&
git push trash/testrepo refs/heads/master:refs/remotes/origin/master &&
(
cd testrepo &&
diff --git a/t/t5700-clone-reference.sh b/t/t5700-clone-reference.sh
index b6a5486..82ef023 100755
--- a/t/t5700-clone-reference.sh
+++ b/t/t5700-clone-reference.sh
@@ -6,7 +6,7 @@
test_description='test clone --reference'
. ./test-lib.sh
-base_dir=`pwd`
+base_dir="$(pwd)"
test_expect_success 'preparing first repository' \
'test_create_repo A && cd A &&
@@ -51,7 +51,7 @@ diff expected current'
cd "$base_dir"
test_expect_success 'cloning with reference (no -l -s)' \
-'git clone --reference B file://`pwd`/A D'
+'git clone --reference B "file://$(pwd)/A" D'
cd "$base_dir"
diff --git a/t/t5710-info-alternate.sh b/t/t5710-info-alternate.sh
index 910ccb4..8f26999 100755
--- a/t/t5710-info-alternate.sh
+++ b/t/t5710-info-alternate.sh
@@ -21,7 +21,7 @@ test_valid_repo() {
test `wc -l < fsck.log` = 0
}
-base_dir=`pwd`
+base_dir="$(pwd)"
test_expect_success 'preparing first repository' \
'test_create_repo A && cd A &&
@@ -81,7 +81,7 @@ test_valid_repo'
cd "$base_dir"
test_expect_success 'breaking of loops' \
-"echo '$base_dir/B/.git/objects' >> '$base_dir'/A/.git/objects/info/alternates&&
+"echo \"\$base_dir\"/B/.git/objects >> \"\$base_dir\"/A/.git/objects/info/alternates&&
cd C &&
test_valid_repo"
diff --git a/t/t7003-filter-branch.sh b/t/t7003-filter-branch.sh
index efd658a..abe3d83 100755
--- a/t/t7003-filter-branch.sh
+++ b/t/t7003-filter-branch.sh
@@ -123,9 +123,9 @@ test_expect_success 'use index-filter to move into a subdirectory' '
git branch directorymoved &&
git-filter-branch -f --index-filter \
"git ls-files -s | sed \"s-\\t-&newsubdir/-\" |
- GIT_INDEX_FILE=\$GIT_INDEX_FILE.new \
+ GIT_INDEX_FILE=\"\$GIT_INDEX_FILE.new\" \
git update-index --index-info &&
- mv \$GIT_INDEX_FILE.new \$GIT_INDEX_FILE" directorymoved &&
+ mv \"\$GIT_INDEX_FILE.new\" \"\$GIT_INDEX_FILE\"" directorymoved &&
test -z "$(git diff HEAD directorymoved:newsubdir)"'
test_expect_success 'stops when msg filter fails' '
diff --git a/t/t7010-setup.sh b/t/t7010-setup.sh
index 02cf7c5..d8a7c79 100755
--- a/t/t7010-setup.sh
+++ b/t/t7010-setup.sh
@@ -122,7 +122,7 @@ test_expect_success 'commit using absolute path names' '
test_expect_success 'log using absolute path names' '
echo bb >>a/b/c/d &&
- git commit -m "bb" $(pwd)/a/b/c/d &&
+ git commit -m "bb" "$(pwd)/a/b/c/d" &&
git log a/b/c/d >f1.txt &&
git log "$(pwd)/a/b/c/d" >f2.txt &&
diff --git a/t/t7300-clean.sh b/t/t7300-clean.sh
index afccfc9..54b1352 100755
--- a/t/t7300-clean.sh
+++ b/t/t7300-clean.sh
@@ -111,7 +111,7 @@ test_expect_success 'git-clean with absolute path' '
touch a.out src/part3.c docs/manual.txt obj.o build/lib.so &&
would_clean=$(
cd docs &&
- git clean -n $(pwd)/../src |
+ git clean -n "$(pwd)/../src" |
sed -n -e "s|^Would remove ||p"
) &&
test "$would_clean" = ../src/part3.c || {
diff --git a/t/t7501-commit.sh b/t/t7501-commit.sh
index c0288f3..e5fdb63 100755
--- a/t/t7501-commit.sh
+++ b/t/t7501-commit.sh
@@ -79,8 +79,8 @@ test_expect_success \
cat >editor <<\EOF
#!/bin/sh
-sed -e "s/a file/an amend commit/g" < $1 > $1-
-mv $1- $1
+sed -e "s/a file/an amend commit/g" < "$1" > "$1-"
+mv "$1-" "$1"
EOF
chmod 755 editor
@@ -99,8 +99,8 @@ test_expect_success \
cat >editor <<\EOF
#!/bin/sh
-sed -e "s/amend/older/g" < $1 > $1-
-mv $1- $1
+sed -e "s/amend/older/g" < "$1" > "$1-"
+mv "$1-" "$1"
EOF
chmod 755 editor
diff --git a/t/t7504-commit-msg-hook.sh b/t/t7504-commit-msg-hook.sh
index eff36aa..24f6b2e 100755
--- a/t/t7504-commit-msg-hook.sh
+++ b/t/t7504-commit-msg-hook.sh
@@ -27,7 +27,7 @@ test_expect_success 'with no hook (editor)' '
echo "more foo" >> file &&
git add file &&
echo "more foo" > FAKE_MSG &&
- GIT_EDITOR="$FAKE_EDITOR" git commit
+ GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit
'
@@ -44,7 +44,7 @@ test_expect_success '--no-verify with no hook (editor)' '
echo "more bar" > file &&
git add file &&
echo "more bar" > FAKE_MSG &&
- GIT_EDITOR="$FAKE_EDITOR" git commit --no-verify
+ GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit --no-verify
'
@@ -71,7 +71,7 @@ test_expect_success 'with succeeding hook (editor)' '
echo "more more" >> file &&
git add file &&
echo "more more" > FAKE_MSG &&
- GIT_EDITOR="$FAKE_EDITOR" git commit
+ GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit
'
@@ -88,7 +88,7 @@ test_expect_success '--no-verify with succeeding hook (editor)' '
echo "even more more" >> file &&
git add file &&
echo "even more more" > FAKE_MSG &&
- GIT_EDITOR="$FAKE_EDITOR" git commit --no-verify
+ GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit --no-verify
'
@@ -111,7 +111,7 @@ test_expect_success 'with failing hook (editor)' '
echo "more another" >> file &&
git add file &&
echo "more another" > FAKE_MSG &&
- ! (GIT_EDITOR="$FAKE_EDITOR" git commit)
+ ! (GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit)
'
@@ -128,7 +128,7 @@ test_expect_success '--no-verify with failing hook (editor)' '
echo "more stuff" >> file &&
git add file &&
echo "more stuff" > FAKE_MSG &&
- GIT_EDITOR="$FAKE_EDITOR" git commit --no-verify
+ GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit --no-verify
'
@@ -146,7 +146,7 @@ test_expect_success 'with non-executable hook (editor)' '
echo "content again" >> file &&
git add file &&
echo "content again" > FAKE_MSG &&
- GIT_EDITOR="$FAKE_EDITOR" git commit -m "content again"
+ GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit -m "content again"
'
@@ -163,7 +163,7 @@ test_expect_success '--no-verify with non-executable hook (editor)' '
echo "even more content" >> file &&
git add file &&
echo "even more content" > FAKE_MSG &&
- GIT_EDITOR="$FAKE_EDITOR" git commit --no-verify
+ GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit --no-verify
'
@@ -193,7 +193,7 @@ test_expect_success 'hook edits commit message (editor)' '
echo "additional content" >> file &&
git add file &&
echo "additional content" > FAKE_MSG &&
- GIT_EDITOR="$FAKE_EDITOR" git commit &&
+ GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit &&
commit_msg_is "new message"
'
@@ -212,7 +212,7 @@ test_expect_success "hook doesn't edit commit message (editor)" '
echo "more plus" >> file &&
git add file &&
echo "more plus" > FAKE_MSG &&
- GIT_EDITOR="$FAKE_EDITOR" git commit --no-verify &&
+ GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit --no-verify &&
commit_msg_is "more plus"
'
diff --git a/t/t7505-prepare-commit-msg-hook.sh b/t/t7505-prepare-commit-msg-hook.sh
index 802aa62..bc2bad9 100755
--- a/t/t7505-prepare-commit-msg-hook.sh
+++ b/t/t7505-prepare-commit-msg-hook.sh
@@ -58,7 +58,7 @@ test_expect_success 'with hook (-m editor)' '
echo "more" >> file &&
git add file &&
- GIT_EDITOR="$FAKE_EDITOR" git commit -e -m "more more" &&
+ GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit -e -m "more more" &&
test "`git log -1 --pretty=format:%s`" = message
'
@@ -85,7 +85,7 @@ test_expect_success 'with hook (-F editor)' '
echo "more" >> file &&
git add file &&
- (echo more more | GIT_EDITOR="$FAKE_EDITOR" git commit -e -F -) &&
+ (echo more more | GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit -e -F -) &&
test "`git log -1 --pretty=format:%s`" = message
'
@@ -104,7 +104,7 @@ test_expect_success 'with hook (editor)' '
echo "more more" >> file &&
git add file &&
- GIT_EDITOR="$FAKE_EDITOR" git commit &&
+ GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit &&
test "`git log -1 --pretty=format:%s`" = default
'
@@ -114,7 +114,7 @@ test_expect_success 'with hook (--amend)' '
head=`git rev-parse HEAD` &&
echo "more" >> file &&
git add file &&
- GIT_EDITOR="$FAKE_EDITOR" git commit --amend &&
+ GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit --amend &&
test "`git log -1 --pretty=format:%s`" = "$head"
'
@@ -124,7 +124,7 @@ test_expect_success 'with hook (-c)' '
head=`git rev-parse HEAD` &&
echo "more" >> file &&
git add file &&
- GIT_EDITOR="$FAKE_EDITOR" git commit -c $head &&
+ GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit -c $head &&
test "`git log -1 --pretty=format:%s`" = "$head"
'
@@ -139,7 +139,7 @@ test_expect_success 'with failing hook' '
head=`git rev-parse HEAD` &&
echo "more" >> file &&
git add file &&
- ! GIT_EDITOR="$FAKE_EDITOR" git commit -c $head
+ ! GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit -c $head
'
@@ -148,7 +148,7 @@ test_expect_success 'with failing hook (--no-verify)' '
head=`git rev-parse HEAD` &&
echo "more" >> file &&
git add file &&
- ! GIT_EDITOR="$FAKE_EDITOR" git commit --no-verify -c $head
+ ! GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit --no-verify -c $head
'
diff --git a/t/t9100-git-svn-basic.sh b/t/t9100-git-svn-basic.sh
index 4e24ab3..528c0a9 100755
--- a/t/t9100-git-svn-basic.sh
+++ b/t/t9100-git-svn-basic.sh
@@ -31,16 +31,16 @@ test_expect_success \
echo 'zzz' > bar/zzz &&
echo '#!/bin/sh' > exec.sh &&
chmod +x exec.sh &&
- svn import -m 'import for git-svn' . $svnrepo >/dev/null &&
+ svn import -m 'import for git-svn' . \"\$svnrepo\" >/dev/null &&
cd .. &&
rm -rf import &&
- git-svn init $svnrepo"
+ git-svn init \"\$svnrepo\""
test_expect_success \
'import an SVN revision into git' \
'git-svn fetch'
-test_expect_success "checkout from svn" "svn co $svnrepo '$SVN_TREE'"
+test_expect_success "checkout from svn" "svn co \"\$svnrepo\" \"\$SVN_TREE\""
name='try a deep --rmdir with a commit'
test_expect_success "$name" "
@@ -51,8 +51,8 @@ test_expect_success "$name" "
git commit -m '$name' &&
git-svn set-tree --find-copies-harder --rmdir \
remotes/git-svn..mybranch &&
- svn up '$SVN_TREE' &&
- test -d '$SVN_TREE'/dir && test ! -d '$SVN_TREE'/dir/a"
+ svn up \"\$SVN_TREE\" &&
+ test -d \"\$SVN_TREE\"/dir && test ! -d \"\$SVN_TREE\"/dir/a"
name='detect node change from file to directory #1'
@@ -69,7 +69,7 @@ test_expect_success "$name" "
name='detect node change from directory to file #1'
test_expect_success "$name" "
- rm -rf dir '$GIT_DIR'/index &&
+ rm -rf dir \"\$GIT_DIR\"/index &&
git checkout -f -b mybranch2 remotes/git-svn &&
mv bar/zzz zzz &&
rm -rf bar &&
@@ -83,7 +83,7 @@ test_expect_success "$name" "
name='detect node change from file to directory #2'
test_expect_success "$name" "
- rm -f '$GIT_DIR'/index &&
+ rm -f \"\$GIT_DIR\"/index &&
git checkout -f -b mybranch3 remotes/git-svn &&
rm bar/zzz &&
git update-index --remove bar/zzz &&
@@ -97,7 +97,7 @@ test_expect_success "$name" "
name='detect node change from directory to file #2'
test_expect_success "$name" "
- rm -f '$GIT_DIR'/index &&
+ rm -f \"\$GIT_DIR\"/index &&
git checkout -f -b mybranch4 remotes/git-svn &&
rm -rf dir &&
git update-index --remove -- dir/file &&
@@ -111,15 +111,15 @@ test_expect_success "$name" "
name='remove executable bit from a file'
test_expect_success "$name" "
- rm -f '$GIT_DIR'/index &&
+ rm -f \"\$GIT_DIR\"/index &&
git checkout -f -b mybranch5 remotes/git-svn &&
chmod -x exec.sh &&
git update-index exec.sh &&
git commit -m '$name' &&
git-svn set-tree --find-copies-harder --rmdir \
remotes/git-svn..mybranch5 &&
- svn up '$SVN_TREE' &&
- test ! -x '$SVN_TREE'/exec.sh"
+ svn up \"\$SVN_TREE\" &&
+ test ! -x \"\$SVN_TREE\"/exec.sh"
name='add executable bit back file'
@@ -129,8 +129,8 @@ test_expect_success "$name" "
git commit -m '$name' &&
git-svn set-tree --find-copies-harder --rmdir \
remotes/git-svn..mybranch5 &&
- svn up '$SVN_TREE' &&
- test -x '$SVN_TREE'/exec.sh"
+ svn up \"\$SVN_TREE\" &&
+ test -x \"\$SVN_TREE\"/exec.sh"
name='executable file becomes a symlink to bar/zzz (file)'
@@ -141,8 +141,8 @@ test_expect_success "$name" "
git commit -m '$name' &&
git-svn set-tree --find-copies-harder --rmdir \
remotes/git-svn..mybranch5 &&
- svn up '$SVN_TREE' &&
- test -L '$SVN_TREE'/exec.sh"
+ svn up \"\$SVN_TREE\" &&
+ test -L \"\$SVN_TREE\"/exec.sh"
name='new symlink is added to a file that was also just made executable'
@@ -153,9 +153,9 @@ test_expect_success "$name" "
git commit -m '$name' &&
git-svn set-tree --find-copies-harder --rmdir \
remotes/git-svn..mybranch5 &&
- svn up '$SVN_TREE' &&
- test -x '$SVN_TREE'/bar/zzz &&
- test -L '$SVN_TREE'/exec-2.sh"
+ svn up \"\$SVN_TREE\" &&
+ test -x \"\$SVN_TREE\"/bar/zzz &&
+ test -L \"\$SVN_TREE\"/exec-2.sh"
name='modify a symlink to become a file'
test_expect_success "$name" "
@@ -166,10 +166,10 @@ test_expect_success "$name" "
git commit -m '$name' &&
git-svn set-tree --find-copies-harder --rmdir \
remotes/git-svn..mybranch5 &&
- svn up '$SVN_TREE' &&
- test -f '$SVN_TREE'/exec-2.sh &&
- test ! -L '$SVN_TREE'/exec-2.sh &&
- git diff help $SVN_TREE/exec-2.sh"
+ svn up \"\$SVN_TREE\" &&
+ test -f \"\$SVN_TREE\"/exec-2.sh &&
+ test ! -L \"\$SVN_TREE\"/exec-2.sh &&
+ git diff help \"\$SVN_TREE\"/exec-2.sh"
if test "$have_utf8" = t
then
@@ -190,7 +190,7 @@ name='test fetch functionality (svn => git) with alternate GIT_SVN_ID'
GIT_SVN_ID=alt
export GIT_SVN_ID
test_expect_success "$name" \
- "git-svn init $svnrepo && git-svn fetch &&
+ "git-svn init \"\$svnrepo\" && git-svn fetch &&
git rev-list --pretty=raw remotes/git-svn | grep ^tree | uniq > a &&
git rev-list --pretty=raw remotes/alt | grep ^tree | uniq > b &&
git diff a b"
@@ -220,16 +220,16 @@ test_expect_success 'exit if remote refs are ambigious' "
"
test_expect_success 'exit if init-ing a would clobber a URL' "
- svnadmin create ${PWD}/svnrepo2 &&
- svn mkdir -m 'mkdir bar' ${svnrepo}2/bar &&
+ svnadmin create \"\${PWD}/svnrepo2\" &&
+ svn mkdir -m 'mkdir bar' \"\${svnrepo}2/bar\" &&
git config --unset svn-remote.svn.fetch \
'^bar:refs/remotes/git-svn$' &&
- ! git-svn init ${svnrepo}2/bar
+ ! git-svn init \"\${svnrepo}2/bar\"
"
test_expect_success \
'init allows us to connect to another directory in the same repo' "
- git-svn init --minimize-url -i bar $svnrepo/bar &&
+ git-svn init --minimize-url -i bar \"\$svnrepo/bar\" &&
git config --get svn-remote.svn.fetch \
'^bar:refs/remotes/bar$' &&
git config --get svn-remote.svn.fetch \
diff --git a/t/t9101-git-svn-props.sh b/t/t9101-git-svn-props.sh
index d7a7047..fa8b7ee 100755
--- a/t/t9101-git-svn-props.sh
+++ b/t/t9101-git-svn-props.sh
@@ -52,7 +52,7 @@ EOF
cd ..
rm -rf import
-test_expect_success 'checkout working copy from svn' "svn co $svnrepo test_wc"
+test_expect_success 'checkout working copy from svn' "svn co \"\$svnrepo\" test_wc"
test_expect_success 'setup some commits to svn' \
'cd test_wc &&
echo Greetings >> kw.c &&
@@ -66,7 +66,7 @@ test_expect_success 'setup some commits to svn' \
svn commit -m "Propset Id" &&
cd ..'
-test_expect_success 'initialize git-svn' "git-svn init $svnrepo"
+test_expect_success 'initialize git-svn' "git-svn init \"\$svnrepo\""
test_expect_success 'fetch revisions from svn' 'git-svn fetch'
name='test svn:keywords ignoring'
@@ -92,7 +92,7 @@ test_expect_success "propset CR on crlf files" \
test_expect_success 'fetch and pull latest from svn and checkout a new wc' \
"git-svn fetch &&
git pull . remotes/git-svn &&
- svn co $svnrepo new_wc"
+ svn co \"\$svnrepo\" new_wc"
for i in crlf ne_crlf lf ne_lf cr ne_cr empty_cr empty_lf empty empty_crlf
do
diff --git a/t/t9102-git-svn-deep-rmdir.sh b/t/t9102-git-svn-deep-rmdir.sh
index 4e08083..8eaf7d3 100755
--- a/t/t9102-git-svn-deep-rmdir.sh
+++ b/t/t9102-git-svn-deep-rmdir.sh
@@ -9,12 +9,12 @@ test_expect_success 'initialize repo' "
mkdir -p deeply/nested/directory/number/2 &&
echo foo > deeply/nested/directory/number/1/file &&
echo foo > deeply/nested/directory/number/2/another &&
- svn import -m 'import for git-svn' . $svnrepo &&
+ svn import -m 'import for git-svn' . \"\$svnrepo\" &&
cd ..
"
test_expect_success 'mirror via git-svn' "
- git-svn init $svnrepo &&
+ git-svn init \"\$svnrepo\" &&
git-svn fetch &&
git checkout -f -b test-rmdir remotes/git-svn
"
@@ -23,7 +23,7 @@ test_expect_success 'Try a commit on rmdir' "
git rm -f deeply/nested/directory/number/2/another &&
git commit -a -m 'remove another' &&
git-svn set-tree --rmdir HEAD &&
- svn ls -R $svnrepo | grep ^deeply/nested/directory/number/1
+ svn ls -R \"\$svnrepo\" | grep ^deeply/nested/directory/number/1
"
diff --git a/t/t9103-git-svn-tracked-directory-removed.sh b/t/t9103-git-svn-tracked-directory-removed.sh
index 0f0b0fd..c7734e6 100755
--- a/t/t9103-git-svn-tracked-directory-removed.sh
+++ b/t/t9103-git-svn-tracked-directory-removed.sh
@@ -6,34 +6,34 @@
test_description='git-svn tracking removed top-level path'
. ./lib-git-svn.sh
-test_expect_success 'make history for tracking' '
+test_expect_success 'make history for tracking' "
mkdir import &&
mkdir import/trunk &&
echo hello >> import/trunk/README &&
- svn import -m initial import $svnrepo &&
+ svn import -m initial import \"\$svnrepo\" &&
rm -rf import &&
- svn co $svnrepo/trunk trunk &&
+ svn co \"\$svnrepo\"/trunk trunk &&
echo bye bye >> trunk/README &&
- svn rm -m "gone" $svnrepo/trunk &&
+ svn rm -m 'gone' \"\$svnrepo\"/trunk &&
rm -rf trunk &&
mkdir trunk &&
- echo "new" > trunk/FOLLOWME &&
- svn import -m "new trunk" trunk $svnrepo/trunk
-'
+ echo 'new' > trunk/FOLLOWME &&
+ svn import -m 'new trunk' trunk \"\$svnrepo\"/trunk
+"
-test_expect_success 'clone repo with git' '
- git svn clone -s $svnrepo x &&
+test_expect_success 'clone repo with git' "
+ git svn clone -s \"\$svnrepo\" x &&
test -f x/FOLLOWME &&
test ! -f x/README
-'
+"
-test_expect_success 'make sure r2 still has old file' '
+test_expect_success 'make sure r2 still has old file' "
cd x &&
- test -n "$(git svn find-rev r1)" &&
- git reset --hard $(git svn find-rev r1) &&
+ test -n \"\$(git svn find-rev r1)\" &&
+ git reset --hard \$(git svn find-rev r1) &&
test -f README &&
test ! -f FOLLOWME &&
- test x$(git svn find-rev r2) = x
-'
+ test x\$(git svn find-rev r2) = x
+"
test_done
diff --git a/t/t9104-git-svn-follow-parent.sh b/t/t9104-git-svn-follow-parent.sh
index 7ba7630..56b1704 100755
--- a/t/t9104-git-svn-follow-parent.sh
+++ b/t/t9104-git-svn-follow-parent.sh
@@ -11,9 +11,9 @@ test_expect_success 'initialize repo' "
cd import &&
mkdir -p trunk &&
echo hello > trunk/readme &&
- svn import -m 'initial' . $svnrepo &&
+ svn import -m 'initial' . \"\$svnrepo\" &&
cd .. &&
- svn co $svnrepo wc &&
+ svn co \"\$svnrepo\" wc &&
cd wc &&
echo world >> trunk/readme &&
poke trunk/readme &&
@@ -27,7 +27,7 @@ test_expect_success 'initialize repo' "
"
test_expect_success 'init and fetch a moved directory' "
- git-svn init --minimize-url -i thunk $svnrepo/thunk &&
+ git-svn init --minimize-url -i thunk \"\$svnrepo\"/thunk &&
git-svn fetch -i thunk &&
test \"\`git rev-parse --verify refs/remotes/thunk@2\`\" \
= \"\`git rev-parse --verify refs/remotes/thunk~1\`\" &&
@@ -38,7 +38,7 @@ test_expect_success 'init and fetch a moved directory' "
"
test_expect_success 'init and fetch from one svn-remote' "
- git config svn-remote.svn.url $svnrepo &&
+ git config svn-remote.svn.url \"\$svnrepo\" &&
git config --add svn-remote.svn.fetch \
trunk:refs/remotes/svn/trunk &&
git config --add svn-remote.svn.fetch \
@@ -52,9 +52,9 @@ test_expect_success 'init and fetch from one svn-remote' "
test_expect_success 'follow deleted parent' "
(svn cp -m 'resurrecting trunk as junk' \
- $svnrepo/trunk@2 $svnrepo/junk ||
+ \"\$svnrepo\"/trunk@2 \"\$svnrepo\"/junk ||
svn cp -m 'resurrecting trunk as junk' \
- -r2 $svnrepo/trunk $svnrepo/junk) &&
+ -r2 \"\$svnrepo\"/trunk \"\$svnrepo\"/junk) &&
git config --add svn-remote.svn.fetch \
junk:refs/remotes/svn/junk &&
git-svn fetch -i svn/thunk &&
@@ -67,10 +67,10 @@ test_expect_success 'follow deleted parent' "
test_expect_success 'follow larger parent' "
mkdir -p import/trunk/thunk/bump/thud &&
echo hi > import/trunk/thunk/bump/thud/file &&
- svn import -m 'import a larger parent' import $svnrepo/larger-parent &&
- svn cp -m 'hi' $svnrepo/larger-parent $svnrepo/another-larger &&
+ svn import -m 'import a larger parent' import \"\$svnrepo\"/larger-parent &&
+ svn cp -m 'hi' \"\$svnrepo\"/larger-parent \"\$svnrepo\"/another-larger &&
git-svn init --minimize-url -i larger \
- $svnrepo/another-larger/trunk/thunk/bump/thud &&
+ \"\$svnrepo\"/another-larger/trunk/thunk/bump/thud &&
git-svn fetch -i larger &&
git rev-parse --verify refs/remotes/larger &&
git rev-parse --verify \
@@ -83,23 +83,23 @@ test_expect_success 'follow larger parent' "
"
test_expect_success 'follow higher-level parent' "
- svn mkdir -m 'follow higher-level parent' $svnrepo/blob &&
- svn co $svnrepo/blob blob &&
+ svn mkdir -m 'follow higher-level parent' \"\$svnrepo\"/blob &&
+ svn co \"\$svnrepo\"/blob blob &&
cd blob &&
echo hi > hi &&
svn add hi &&
svn commit -m 'hihi' &&
cd ..
- svn mkdir -m 'new glob at top level' $svnrepo/glob &&
- svn mv -m 'move blob down a level' $svnrepo/blob $svnrepo/glob/blob &&
- git-svn init --minimize-url -i blob $svnrepo/glob/blob &&
+ svn mkdir -m 'new glob at top level' \"\$svnrepo\"/glob &&
+ svn mv -m 'move blob down a level' \"\$svnrepo\"/blob \"\$svnrepo\"/glob/blob &&
+ git-svn init --minimize-url -i blob \"\$svnrepo\"/glob/blob &&
git-svn fetch -i blob
"
test_expect_success 'follow deleted directory' "
- svn mv -m 'bye!' $svnrepo/glob/blob/hi $svnrepo/glob/blob/bye &&
- svn rm -m 'remove glob' $svnrepo/glob &&
- git-svn init --minimize-url -i glob $svnrepo/glob &&
+ svn mv -m 'bye!' \"\$svnrepo\"/glob/blob/hi \"\$svnrepo\"/glob/blob/bye &&
+ svn rm -m 'remove glob' \"\$svnrepo\"/glob &&
+ git-svn init --minimize-url -i glob \"\$svnrepo\"/glob &&
git-svn fetch -i glob &&
test \"\`git cat-file blob refs/remotes/glob:blob/bye\`\" = hi &&
test \"\`git ls-tree refs/remotes/glob | wc -l \`\" -eq 1
@@ -118,9 +118,9 @@ test_expect_success 'follow-parent avoids deleting relevant info' "
echo 'bad delete test 2' > \
import/trunk/subversion/bindings/swig/perl/another-larger &&
cd import &&
- svn import -m 'r9270 test' . $svnrepo/r9270 &&
+ svn import -m 'r9270 test' . \"\$svnrepo\"/r9270 &&
cd .. &&
- svn co $svnrepo/r9270/trunk/subversion/bindings/swig/perl r9270 &&
+ svn co \"\$svnrepo\"/r9270/trunk/subversion/bindings/swig/perl r9270 &&
cd r9270 &&
svn mkdir native &&
svn mv t native/t &&
@@ -130,7 +130,7 @@ test_expect_success 'follow-parent avoids deleting relevant info' "
svn commit -m 'reorg test' &&
cd .. &&
git-svn init --minimize-url -i r9270-t \
- $svnrepo/r9270/trunk/subversion/bindings/swig/perl/native/t &&
+ \"\$svnrepo\"/r9270/trunk/subversion/bindings/swig/perl/native/t &&
git-svn fetch -i r9270-t &&
test \`git rev-list r9270-t | wc -l\` -eq 2 &&
test \"\`git ls-tree --name-only r9270-t~1\`\" = \
@@ -138,9 +138,9 @@ test_expect_success 'follow-parent avoids deleting relevant info' "
"
test_expect_success "track initial change if it was only made to parent" "
- svn cp -m 'wheee!' $svnrepo/r9270/trunk $svnrepo/r9270/drunk &&
+ svn cp -m 'wheee!' \"\$svnrepo\"/r9270/trunk \"\$svnrepo\"/r9270/drunk &&
git-svn init --minimize-url -i r9270-d \
- $svnrepo/r9270/drunk/subversion/bindings/swig/perl/native/t &&
+ \"\$svnrepo\"/r9270/drunk/subversion/bindings/swig/perl/native/t &&
git-svn fetch -i r9270-d &&
test \`git rev-list r9270-d | wc -l\` -eq 3 &&
test \"\`git ls-tree --name-only r9270-t\`\" = \
@@ -150,7 +150,7 @@ test_expect_success "track initial change if it was only made to parent" "
"
test_expect_success "track multi-parent paths" "
- svn cp -m 'resurrect /glob' $svnrepo/r9270 $svnrepo/glob &&
+ svn cp -m 'resurrect /glob' \"\$svnrepo\"/r9270 \"\$svnrepo\"/glob &&
git-svn multi-fetch &&
test \`git cat-file commit refs/remotes/glob | \
grep '^parent ' | wc -l\` -eq 2
@@ -161,8 +161,8 @@ test_expect_success "multi-fetch continues to work" "
"
test_expect_success "multi-fetch works off a 'clean' repository" "
- rm -r $GIT_DIR/svn $GIT_DIR/refs/remotes $GIT_DIR/logs &&
- mkdir $GIT_DIR/svn &&
+ rm -r \"\$GIT_DIR/svn\" \"\$GIT_DIR/refs/remotes\" \"\$GIT_DIR/logs\" &&
+ mkdir \"\$GIT_DIR/svn\" &&
git-svn multi-fetch
"
diff --git a/t/t9105-git-svn-commit-diff.sh b/t/t9105-git-svn-commit-diff.sh
index 318e172..4f7f9cc 100755
--- a/t/t9105-git-svn-commit-diff.sh
+++ b/t/t9105-git-svn-commit-diff.sh
@@ -8,7 +8,7 @@ test_expect_success 'initialize repo' "
mkdir import &&
cd import &&
echo hello > readme &&
- svn import -m 'initial' . $svnrepo &&
+ svn import -m 'initial' . \"\$svnrepo\" &&
cd .. &&
echo hello > readme &&
git update-index --add readme &&
@@ -26,17 +26,17 @@ prev=`git rev-parse --verify HEAD^1`
test_expect_success 'test the commit-diff command' "
test -n '$prev' && test -n '$head' &&
- git-svn commit-diff -r1 '$prev' '$head' '$svnrepo' &&
- svn co $svnrepo wc &&
+ git-svn commit-diff -r1 '$prev' '$head' \"\$svnrepo\" &&
+ svn co \"\$svnrepo\" wc &&
cmp readme wc/readme
"
test_expect_success 'commit-diff to a sub-directory (with git-svn config)' "
- svn import -m 'sub-directory' import $svnrepo/subdir &&
- git-svn init --minimize-url $svnrepo/subdir &&
+ svn import -m 'sub-directory' import \"\$svnrepo\"/subdir &&
+ git-svn init --minimize-url \"\$svnrepo\"/subdir &&
git-svn fetch &&
git-svn commit-diff -r3 '$prev' '$head' &&
- svn cat $svnrepo/subdir/readme > readme.2 &&
+ svn cat \"\$svnrepo\"/subdir/readme > readme.2 &&
cmp readme readme.2
"
diff --git a/t/t9106-git-svn-commit-diff-clobber.sh b/t/t9106-git-svn-commit-diff-clobber.sh
index f74ab12..bb544f6 100755
--- a/t/t9106-git-svn-commit-diff-clobber.sh
+++ b/t/t9106-git-svn-commit-diff-clobber.sh
@@ -8,14 +8,14 @@ test_expect_success 'initialize repo' "
mkdir import &&
cd import &&
echo initial > file &&
- svn import -m 'initial' . $svnrepo &&
+ svn import -m 'initial' . \"\$svnrepo\" &&
cd .. &&
echo initial > file &&
git update-index --add file &&
git commit -a -m 'initial'
"
test_expect_success 'commit change from svn side' "
- svn co $svnrepo t.svn &&
+ svn co \"\$svnrepo\" t.svn &&
cd t.svn &&
echo second line from svn >> file &&
poke file &&
@@ -27,7 +27,7 @@ test_expect_success 'commit change from svn side' "
test_expect_success 'commit conflicting change from git' "
echo second line from git >> file &&
git commit -a -m 'second line from git' &&
- ! git-svn commit-diff -r1 HEAD~1 HEAD $svnrepo
+ ! git-svn commit-diff -r1 HEAD~1 HEAD \"\$svnrepo\"
"
test_expect_success 'commit complementing change from git' "
@@ -36,14 +36,14 @@ test_expect_success 'commit complementing change from git' "
git commit -a -m 'second line from svn' &&
echo third line from git >> file &&
git commit -a -m 'third line from git' &&
- git-svn commit-diff -r2 HEAD~1 HEAD $svnrepo
+ git-svn commit-diff -r2 HEAD~1 HEAD \"\$svnrepo\"
"
test_expect_success 'dcommit fails to commit because of conflict' "
- git-svn init $svnrepo &&
+ git-svn init \"\$svnrepo\" &&
git-svn fetch &&
git reset --hard refs/remotes/git-svn &&
- svn co $svnrepo t.svn &&
+ svn co \"\$svnrepo\" t.svn &&
cd t.svn &&
echo fourth line from svn >> file &&
poke file &&
@@ -67,7 +67,7 @@ test_expect_success 'dcommit does the svn equivalent of an index merge' "
"
test_expect_success 'commit another change from svn side' "
- svn co $svnrepo t.svn &&
+ svn co \"\$svnrepo\" t.svn &&
cd t.svn &&
echo third line from svn >> file &&
poke file &&
diff --git a/t/t9106-git-svn-dcommit-clobber-series.sh b/t/t9106-git-svn-dcommit-clobber-series.sh
index ca8a00e..477755a 100755
--- a/t/t9106-git-svn-dcommit-clobber-series.sh
+++ b/t/t9106-git-svn-dcommit-clobber-series.sh
@@ -8,9 +8,9 @@ test_expect_success 'initialize repo' "
mkdir import &&
cd import &&
awk 'BEGIN { for (i = 1; i < 64; i++) { print i } }' > file
- svn import -m 'initial' . $svnrepo &&
+ svn import -m 'initial' . \"\$svnrepo\" &&
cd .. &&
- git svn init $svnrepo &&
+ git svn init \"\$svnrepo\" &&
git svn fetch &&
test -e file
"
@@ -18,7 +18,7 @@ test_expect_success 'initialize repo' "
test_expect_success '(supposedly) non-conflicting change from SVN' "
test x\"\`sed -n -e 58p < file\`\" = x58 &&
test x\"\`sed -n -e 61p < file\`\" = x61 &&
- svn co $svnrepo tmp &&
+ svn co \"\$svnrepo\" tmp &&
cd tmp &&
perl -i -p -e 's/^58\$/5588/' file &&
perl -i -p -e 's/^61\$/6611/' file &&
diff --git a/t/t9107-git-svn-migrate.sh b/t/t9107-git-svn-migrate.sh
index 0a41d52..9ab7074 100755
--- a/t/t9107-git-svn-migrate.sh
+++ b/t/t9107-git-svn-migrate.sh
@@ -4,7 +4,7 @@ test_description='git-svn metadata migrations from previous versions'
. ./lib-git-svn.sh
test_expect_success 'setup old-looking metadata' "
- cp $GIT_DIR/config $GIT_DIR/config-old-git-svn &&
+ cp \"\$GIT_DIR\"/config \"\$GIT_DIR\"/config-old-git-svn &&
mkdir import &&
cd import &&
for i in trunk branches/a branches/b \
@@ -12,13 +12,13 @@ test_expect_success 'setup old-looking metadata' "
mkdir -p \$i && \
echo hello >> \$i/README || exit 1
done && \
- svn import -m test . $svnrepo
+ svn import -m test . \"\$svnrepo\"
cd .. &&
- git-svn init $svnrepo &&
+ git-svn init \"\$svnrepo\" &&
git-svn fetch &&
- mv $GIT_DIR/svn/* $GIT_DIR/ &&
- mv $GIT_DIR/svn/.metadata $GIT_DIR/ &&
- rmdir $GIT_DIR/svn &&
+ mv \"\$GIT_DIR\"/svn/* \"\$GIT_DIR\"/ &&
+ mv \"\$GIT_DIR\"/svn/.metadata \"\$GIT_DIR\"/ &&
+ rmdir \"\$GIT_DIR\"/svn &&
git update-ref refs/heads/git-svn-HEAD refs/remotes/git-svn &&
git update-ref refs/heads/svn-HEAD refs/remotes/git-svn &&
git update-ref -d refs/remotes/git-svn refs/remotes/git-svn
@@ -28,20 +28,20 @@ head=`git rev-parse --verify refs/heads/git-svn-HEAD^0`
test_expect_success 'git-svn-HEAD is a real HEAD' "test -n '$head'"
test_expect_success 'initialize old-style (v0) git-svn layout' "
- mkdir -p $GIT_DIR/git-svn/info $GIT_DIR/svn/info &&
- echo $svnrepo > $GIT_DIR/git-svn/info/url &&
- echo $svnrepo > $GIT_DIR/svn/info/url &&
+ mkdir -p \"\$GIT_DIR\"/git-svn/info \"\$GIT_DIR\"/svn/info &&
+ echo \"\$svnrepo\" > \"\$GIT_DIR\"/git-svn/info/url &&
+ echo \"\$svnrepo\" > \"\$GIT_DIR\"/svn/info/url &&
git-svn migrate &&
- ! test -d $GIT_DIR/git-svn &&
+ ! test -d \"\$GIT_DIR\"/git-svn &&
git rev-parse --verify refs/remotes/git-svn^0 &&
git rev-parse --verify refs/remotes/svn^0 &&
- test \`git config --get svn-remote.svn.url\` = '$svnrepo' &&
+ test \"\$(git config --get svn-remote.svn.url)\" = \"\$svnrepo\" &&
test \`git config --get svn-remote.svn.fetch\` = \
':refs/remotes/git-svn'
"
test_expect_success 'initialize a multi-repository repo' "
- git-svn init $svnrepo -T trunk -t tags -b branches &&
+ git-svn init \"\$svnrepo\" -T trunk -t tags -b branches &&
git config --get-all svn-remote.svn.fetch > fetch.out &&
grep '^trunk:refs/remotes/trunk$' fetch.out &&
test -n \"\`git config --get svn-remote.svn.branches \
@@ -76,14 +76,14 @@ test_expect_success 'multi-fetch works on partial urls + paths' "
test_expect_success 'migrate --minimize on old inited layout' "
git config --unset-all svn-remote.svn.fetch &&
git config --unset-all svn-remote.svn.url &&
- rm -rf $GIT_DIR/svn &&
+ rm -rf \"\$GIT_DIR\"/svn &&
for i in \`cat fetch.out\`; do
path=\`expr \$i : '\\([^:]*\\):.*$'\`
ref=\`expr \$i : '[^:]*:refs/remotes/\\(.*\\)$'\`
if test -z \"\$ref\"; then continue; fi
if test -n \"\$path\"; then path=\"/\$path\"; fi
- ( mkdir -p $GIT_DIR/svn/\$ref/info/ &&
- echo $svnrepo\$path > $GIT_DIR/svn/\$ref/info/url ) || exit 1;
+ ( mkdir -p \"\$GIT_DIR\"/svn/\$ref/info/ &&
+ echo \"\$svnrepo\"\$path > \"\$GIT_DIR\"/svn/\$ref/info/url ) || exit 1;
done &&
git-svn migrate --minimize &&
test -z \"\`git config -l |grep -v '^svn-remote\.git-svn\.'\`\" &&
@@ -99,17 +99,17 @@ test_expect_success 'migrate --minimize on old inited layout' "
test_expect_success ".rev_db auto-converted to .rev_map.UUID" "
git-svn fetch -i trunk &&
- test -z \"\$(ls $GIT_DIR/svn/trunk/.rev_db.* 2>/dev/null)\" &&
- expect=\"\$(ls $GIT_DIR/svn/trunk/.rev_map.*)\" &&
+ test -z \"\$(ls \"\$GIT_DIR\"/svn/trunk/.rev_db.* 2>/dev/null)\" &&
+ expect=\"\$(ls \"\$GIT_DIR\"/svn/trunk/.rev_map.*)\" &&
test -n \"\$expect\" &&
- rev_db=\$(echo \$expect | sed -e 's,_map,_db,') &&
- convert_to_rev_db \$expect \$rev_db &&
- rm -f \$expect &&
- test -f \$rev_db &&
+ rev_db=\"\$(echo \$expect | sed -e 's,_map,_db,')\" &&
+ convert_to_rev_db \"\$expect\" \"\$rev_db\" &&
+ rm -f \"\$expect\" &&
+ test -f \"\$rev_db\" &&
git-svn fetch -i trunk &&
- test -z \"\$(ls $GIT_DIR/svn/trunk/.rev_db.* 2>/dev/null)\" &&
- test ! -e $GIT_DIR/svn/trunk/.rev_db &&
- test -f \$expect
+ test -z \"\$(ls \"\$GIT_DIR\"/svn/trunk/.rev_db.* 2>/dev/null)\" &&
+ test ! -e \"\$GIT_DIR\"/svn/trunk/.rev_db &&
+ test -f \"\$expect\"
"
test_done
diff --git a/t/t9108-git-svn-glob.sh b/t/t9108-git-svn-glob.sh
index db4344c..8f03f2d 100755
--- a/t/t9108-git-svn-glob.sh
+++ b/t/t9108-git-svn-glob.sh
@@ -14,8 +14,8 @@ test_expect_success 'test refspec globbing' "
mkdir -p trunk/src/a trunk/src/b trunk/doc &&
echo 'hello world' > trunk/src/a/readme &&
echo 'goodbye world' > trunk/src/b/readme &&
- svn import -m 'initial' trunk $svnrepo/trunk &&
- svn co $svnrepo tmp &&
+ svn import -m 'initial' trunk \"\$svnrepo\"/trunk &&
+ svn co \"\$svnrepo\" tmp &&
cd tmp &&
mkdir branches tags &&
svn add branches tags &&
@@ -38,7 +38,7 @@ test_expect_success 'test refspec globbing' "
poke tags/end/src/b/readme &&
svn commit -m 'nothing to see here'
cd .. &&
- git config --add svn-remote.svn.url $svnrepo &&
+ git config --add svn-remote.svn.url \"\$svnrepo\" &&
git config --add svn-remote.svn.fetch \
'trunk/src/a:refs/remotes/trunk' &&
git config --add svn-remote.svn.branches \
@@ -60,7 +60,7 @@ echo nothing to see here >> expect.two
cat expect.end >> expect.two
test_expect_success 'test left-hand-side only globbing' "
- git config --add svn-remote.two.url $svnrepo &&
+ git config --add svn-remote.two.url \"\$svnrepo\" &&
git config --add svn-remote.two.fetch trunk:refs/remotes/two/trunk &&
git config --add svn-remote.two.branches \
'branches/*:refs/remotes/two/branches/*' &&
diff --git a/t/t9110-git-svn-use-svm-props.sh b/t/t9110-git-svn-use-svm-props.sh
index 6235af4..d9ac558 100755
--- a/t/t9110-git-svn-use-svm-props.sh
+++ b/t/t9110-git-svn-use-svm-props.sh
@@ -8,11 +8,11 @@ test_description='git-svn useSvmProps test'
. ./lib-git-svn.sh
test_expect_success 'load svm repo' "
- svnadmin load -q $rawsvnrepo < ../t9110/svm.dump &&
- git-svn init --minimize-url -R arr -i bar $svnrepo/mirror/arr &&
- git-svn init --minimize-url -R argh -i dir $svnrepo/mirror/argh &&
+ svnadmin load -q \"\$rawsvnrepo\" < ../t9110/svm.dump &&
+ git-svn init --minimize-url -R arr -i bar \"\$svnrepo\"/mirror/arr &&
+ git-svn init --minimize-url -R argh -i dir \"\$svnrepo\"/mirror/argh &&
git-svn init --minimize-url -R argh -i e \
- $svnrepo/mirror/argh/a/b/c/d/e &&
+ \"\$svnrepo\"/mirror/argh/a/b/c/d/e &&
git config svn.useSvmProps true &&
git-svn fetch --all
"
diff --git a/t/t9111-git-svn-use-svnsync-props.sh b/t/t9111-git-svn-use-svnsync-props.sh
index ec7dedd..77185bc 100755
--- a/t/t9111-git-svn-use-svnsync-props.sh
+++ b/t/t9111-git-svn-use-svnsync-props.sh
@@ -8,10 +8,10 @@ test_description='git-svn useSvnsyncProps test'
. ./lib-git-svn.sh
test_expect_success 'load svnsync repo' "
- svnadmin load -q $rawsvnrepo < ../t9111/svnsync.dump &&
- git-svn init --minimize-url -R arr -i bar $svnrepo/bar &&
- git-svn init --minimize-url -R argh -i dir $svnrepo/dir &&
- git-svn init --minimize-url -R argh -i e $svnrepo/dir/a/b/c/d/e &&
+ svnadmin load -q \"\$rawsvnrepo\" < ../t9111/svnsync.dump &&
+ git-svn init --minimize-url -R arr -i bar \"\$svnrepo\"/bar &&
+ git-svn init --minimize-url -R argh -i dir \"\$svnrepo\"/dir &&
+ git-svn init --minimize-url -R argh -i e \"\$svnrepo\"/dir/a/b/c/d/e &&
git config svn.useSvnsyncProps true &&
git-svn fetch --all
"
diff --git a/t/t9112-git-svn-md5less-file.sh b/t/t9112-git-svn-md5less-file.sh
index 646a5f0..fb1491d 100755
--- a/t/t9112-git-svn-md5less-file.sh
+++ b/t/t9112-git-svn-md5less-file.sh
@@ -40,8 +40,8 @@ PROPS-END
EOF
-test_expect_success 'load svn dumpfile' "svnadmin load $rawsvnrepo < dumpfile.svn"
+test_expect_success 'load svn dumpfile' "svnadmin load \"\$rawsvnrepo\" < dumpfile.svn"
-test_expect_success 'initialize git-svn' "git-svn init $svnrepo"
+test_expect_success 'initialize git-svn' "git-svn init \"\$svnrepo\""
test_expect_success 'fetch revisions from svn' 'git-svn fetch'
test_done
diff --git a/t/t9113-git-svn-dcommit-new-file.sh b/t/t9113-git-svn-dcommit-new-file.sh
index 9ef0db9..b92a64e 100755
--- a/t/t9113-git-svn-dcommit-new-file.sh
+++ b/t/t9113-git-svn-dcommit-new-file.sh
@@ -15,14 +15,14 @@ test_description='git-svn dcommit new files over svn:// test'
start_svnserve () {
svnserve --listen-port $SVNSERVE_PORT \
- --root $rawsvnrepo \
+ --root "$rawsvnrepo" \
--listen-once \
--listen-host 127.0.0.1 &
}
test_expect_success 'start tracking an empty repo' "
- svn mkdir -m 'empty dir' $svnrepo/empty-dir &&
- echo anon-access = write >> $rawsvnrepo/conf/svnserve.conf &&
+ svn mkdir -m 'empty dir' \"\$svnrepo\"/empty-dir &&
+ echo anon-access = write >> \"\$rawsvnrepo\"/conf/svnserve.conf &&
start_svnserve &&
git svn init svn://127.0.0.1:$SVNSERVE_PORT &&
git svn fetch
diff --git a/t/t9114-git-svn-dcommit-merge.sh b/t/t9114-git-svn-dcommit-merge.sh
index 225060b..74b971c 100755
--- a/t/t9114-git-svn-dcommit-merge.sh
+++ b/t/t9114-git-svn-dcommit-merge.sh
@@ -35,7 +35,7 @@ EOF
}
test_expect_success 'setup svn repository' "
- svn co $svnrepo mysvnwork &&
+ svn co \"\$svnrepo\" mysvnwork &&
mkdir -p mysvnwork/trunk &&
cd mysvnwork &&
big_text_block >> trunk/README &&
@@ -45,7 +45,7 @@ test_expect_success 'setup svn repository' "
"
test_expect_success 'setup git mirror and merge' "
- git svn init $svnrepo -t tags -T trunk -b branches &&
+ git svn init \"\$svnrepo\" -t tags -T trunk -b branches &&
git svn fetch &&
git checkout --track -b svn remotes/trunk &&
git checkout -b merge &&
diff --git a/t/t9115-git-svn-dcommit-funky-renames.sh b/t/t9115-git-svn-dcommit-funky-renames.sh
index 182299c..f83f4f9 100755
--- a/t/t9115-git-svn-dcommit-funky-renames.sh
+++ b/t/t9115-git-svn-dcommit-funky-renames.sh
@@ -8,12 +8,12 @@ test_description='git-svn dcommit can commit renames of files with ugly names'
. ./lib-git-svn.sh
test_expect_success 'load repository with strange names' "
- svnadmin load -q $rawsvnrepo < ../t9115/funky-names.dump &&
+ svnadmin load -q \"\$rawsvnrepo\" < ../t9115/funky-names.dump &&
start_httpd
"
test_expect_success 'init and fetch repository' "
- git svn init $svnrepo &&
+ git svn init \"\$svnrepo\" &&
git svn fetch &&
git reset --hard git-svn
"
diff --git a/t/t9116-git-svn-log.sh b/t/t9116-git-svn-log.sh
index e1e8bdf..13081b8 100755
--- a/t/t9116-git-svn-log.sh
+++ b/t/t9116-git-svn-log.sh
@@ -14,9 +14,9 @@ test_expect_success 'setup repository and import' "
mkdir -p \$i && \
echo hello >> \$i/README || exit 1
done && \
- svn import -m test . $svnrepo
+ svn import -m test . \"\$svnrepo\"
cd .. &&
- git-svn init $svnrepo -T trunk -b branches -t tags &&
+ git-svn init \"\$svnrepo\" -T trunk -b branches -t tags &&
git-svn fetch &&
git reset --hard trunk &&
echo bye >> README &&
diff --git a/t/t9117-git-svn-init-clone.sh b/t/t9117-git-svn-init-clone.sh
index d482b40..c924915 100755
--- a/t/t9117-git-svn-init-clone.sh
+++ b/t/t9117-git-svn-init-clone.sh
@@ -16,13 +16,13 @@ cd tmp
test_expect_success 'setup svnrepo' "
mkdir project project/trunk project/branches project/tags &&
echo foo > project/trunk/foo &&
- svn import -m '$test_description' project $svnrepo/project &&
+ svn import -m '$test_description' project \"\$svnrepo\"/project &&
rm -rf project
"
test_expect_success 'basic clone' "
test ! -d trunk &&
- git svn clone $svnrepo/project/trunk &&
+ git svn clone \"\$svnrepo\"/project/trunk &&
test -d trunk/.git/svn &&
test -e trunk/foo &&
rm -rf trunk
@@ -30,7 +30,7 @@ test_expect_success 'basic clone' "
test_expect_success 'clone to target directory' "
test ! -d target &&
- git svn clone $svnrepo/project/trunk target &&
+ git svn clone \"\$svnrepo\"/project/trunk target &&
test -d target/.git/svn &&
test -e target/foo &&
rm -rf target
@@ -38,7 +38,7 @@ test_expect_success 'clone to target directory' "
test_expect_success 'clone with --stdlayout' "
test ! -d project &&
- git svn clone -s $svnrepo/project &&
+ git svn clone -s \"\$svnrepo\"/project &&
test -d project/.git/svn &&
test -e project/foo &&
rm -rf project
@@ -46,7 +46,7 @@ test_expect_success 'clone with --stdlayout' "
test_expect_success 'clone to target directory with --stdlayout' "
test ! -d target &&
- git svn clone -s $svnrepo/project target &&
+ git svn clone -s \"\$svnrepo\"/project target &&
test -d target/.git/svn &&
test -e target/foo &&
rm -rf target
diff --git a/t/t9118-git-svn-funky-branch-names.sh b/t/t9118-git-svn-funky-branch-names.sh
index 640bb06..0f107fc 100755
--- a/t/t9118-git-svn-funky-branch-names.sh
+++ b/t/t9118-git-svn-funky-branch-names.sh
@@ -9,17 +9,17 @@ test_description='git-svn funky branch names'
test_expect_success 'setup svnrepo' "
mkdir project project/trunk project/branches project/tags &&
echo foo > project/trunk/foo &&
- svn import -m '$test_description' project \"$svnrepo/pr ject\" &&
+ svn import -m '\$test_description' project \"\$svnrepo/pr ject\" &&
rm -rf project &&
- svn cp -m 'fun' \"$svnrepo/pr ject/trunk\" \
- \"$svnrepo/pr ject/branches/fun plugin\" &&
- svn cp -m 'more fun!' \"$svnrepo/pr ject/branches/fun plugin\" \
- \"$svnrepo/pr ject/branches/more fun plugin!\" &&
+ svn cp -m 'fun' \"\$svnrepo/pr ject/trunk\" \
+ \"\$svnrepo/pr ject/branches/fun plugin\" &&
+ svn cp -m 'more fun!' \"\$svnrepo/pr ject/branches/fun plugin\" \
+ \"\$svnrepo/pr ject/branches/more fun plugin!\" &&
start_httpd
"
test_expect_success 'test clone with funky branch names' "
- git svn clone -s \"$svnrepo/pr ject\" project &&
+ git svn clone -s \"\$svnrepo/pr ject\" project &&
cd project &&
git rev-parse 'refs/remotes/fun%20plugin' &&
git rev-parse 'refs/remotes/more%20fun%20plugin!' &&
diff --git a/t/t9120-git-svn-clone-with-percent-escapes.sh b/t/t9120-git-svn-clone-with-percent-escapes.sh
index 9a4eabe..1414c0f 100755
--- a/t/t9120-git-svn-clone-with-percent-escapes.sh
+++ b/t/t9120-git-svn-clone-with-percent-escapes.sh
@@ -9,7 +9,7 @@ test_description='git-svn clone with percent escapes'
test_expect_success 'setup svnrepo' "
mkdir project project/trunk project/branches project/tags &&
echo foo > project/trunk/foo &&
- svn import -m '$test_description' project '$svnrepo/pr ject' &&
+ svn import -m \"\$test_description\" project \"\$svnrepo/pr ject\" &&
rm -rf project &&
start_httpd
"
diff --git a/t/t9500-gitweb-standalone-no-errors.sh b/t/t9500-gitweb-standalone-no-errors.sh
index 796cd7d..0f36e6c 100755
--- a/t/t9500-gitweb-standalone-no-errors.sh
+++ b/t/t9500-gitweb-standalone-no-errors.sh
@@ -10,6 +10,7 @@ commandline, and checks that it would not write any errors
or warnings to log.'
gitweb_init () {
+ safe_pwd="$(perl -MPOSIX=getcwd -e 'print quotemeta(getcwd)')"
cat >gitweb_config.perl <<EOF
#!/usr/bin/perl
@@ -17,16 +18,16 @@ gitweb_init () {
our \$version = "current";
our \$GIT = "git";
-our \$projectroot = "$(pwd)";
+our \$projectroot = "$safe_pwd";
our \$project_maxdepth = 8;
our \$home_link_str = "projects";
our \$site_name = "[localhost]";
our \$site_header = "";
our \$site_footer = "";
our \$home_text = "indextext.html";
-our @stylesheets = ("file:///$(pwd)/../../gitweb/gitweb.css");
-our \$logo = "file:///$(pwd)/../../gitweb/git-logo.png";
-our \$favicon = "file:///$(pwd)/../../gitweb/git-favicon.png";
+our @stylesheets = ("file:///$safe_pwd/../../gitweb/gitweb.css");
+our \$logo = "file:///$safe_pwd/../../gitweb/git-logo.png";
+our \$favicon = "file:///$safe_pwd/../../gitweb/git-favicon.png";
our \$projects_list = "";
our \$export_ok = "";
our \$strict_export = "";
@@ -45,13 +46,13 @@ gitweb_run () {
export QUERY_STRING=""$1""
export PATH_INFO=""$2""
- export GITWEB_CONFIG=$(pwd)/gitweb_config.perl
+ export GITWEB_CONFIG="$(pwd)/gitweb_config.perl"
# some of git commands write to STDERR on error, but this is not
# written to web server logs, so we are not interested in that:
# we are interested only in properly formatted errors/warnings
rm -f gitweb.log &&
- perl -- $(pwd)/../../gitweb/gitweb.perl \
+ perl -- "$(pwd)/../../gitweb/gitweb.perl" \
>/dev/null 2>gitweb.log &&
if grep -q -s "^[[]" gitweb.log >/dev/null; then false; else true; fi
--
1.5.5.8.gbbd98
^ permalink raw reply related [relevance 10%]
* [PATCH v2 09/10] Fix tests breaking when checkout path contains shell metacharacters
@ 2008-04-10 6:50 10% ` Bryan Donlan
0 siblings, 0 replies; 200+ results
From: Bryan Donlan @ 2008-04-10 6:50 UTC (permalink / raw)
To: git; +Cc: Johannes Sixt, Adam Roben, gitster, Bryan Donlan
This fixes the remainder of the issues where the test script itself is at
fault for failing when the git checkout path contains whitespace or other
shell metacharacters.
Signed-off-by: Bryan Donlan <bdonlan@fushizen.net>
---
t/t0000-basic.sh | 4 +-
t/t1020-subdirectory.sh | 22 +++++-----
t/t3050-subprojects-fetch.sh | 2 +-
t/t3404-rebase-interactive.sh | 3 +-
t/t5500-fetch-pack.sh | 2 +-
t/t5512-ls-remote.sh | 2 +-
t/t5516-fetch-push.sh | 4 +-
t/t5700-clone-reference.sh | 2 +-
t/t5710-info-alternate.sh | 2 +-
t/t7003-filter-branch.sh | 2 +-
t/t7010-setup.sh | 2 +-
t/t7300-clean.sh | 2 +-
t/t7501-commit.sh | 8 ++--
t/t7504-commit-msg-hook.sh | 23 ++++++-----
t/t7505-prepare-commit-msg-hook.sh | 17 +++++---
t/t9100-git-svn-basic.sh | 54 ++++++++++++------------
t/t9101-git-svn-props.sh | 6 +-
t/t9102-git-svn-deep-rmdir.sh | 6 +-
t/t9103-git-svn-tracked-directory-removed.sh | 30 +++++++-------
t/t9104-git-svn-follow-parent.sh | 50 +++++++++++-----------
t/t9105-git-svn-commit-diff.sh | 12 +++---
t/t9106-git-svn-commit-diff-clobber.sh | 14 +++---
t/t9106-git-svn-dcommit-clobber-series.sh | 6 +-
t/t9107-git-svn-migrate.sh | 48 +++++++++++-----------
t/t9108-git-svn-glob.sh | 8 ++--
t/t9110-git-svn-use-svm-props.sh | 8 ++--
t/t9111-git-svn-use-svnsync-props.sh | 8 ++--
t/t9112-git-svn-md5less-file.sh | 4 +-
t/t9113-git-svn-dcommit-new-file.sh | 6 +-
t/t9114-git-svn-dcommit-merge.sh | 4 +-
t/t9115-git-svn-dcommit-funky-renames.sh | 4 +-
t/t9116-git-svn-log.sh | 4 +-
t/t9117-git-svn-init-clone.sh | 10 ++--
t/t9118-git-svn-funky-branch-names.sh | 12 +++---
t/t9120-git-svn-clone-with-percent-escapes.sh | 2 +-
t/t9500-gitweb-standalone-no-errors.sh | 11 +++--
36 files changed, 205 insertions(+), 199 deletions(-)
diff --git a/t/t0000-basic.sh b/t/t0000-basic.sh
index 27b54cb..690f80a 100755
--- a/t/t0000-basic.sh
+++ b/t/t0000-basic.sh
@@ -305,10 +305,10 @@ test_expect_success 'absolute path works as expected' '
file="$dir"/index &&
test "$file" = "$(test-absolute-path $dir2/index)" &&
basename=blub &&
- test "$dir/$basename" = $(cd .git && test-absolute-path $basename) &&
+ test "$dir/$basename" = "$(cd .git && test-absolute-path "$basename")" &&
ln -s ../first/file .git/syml &&
sym="$(cd first; pwd -P)"/file &&
- test "$sym" = "$(test-absolute-path $dir2/syml)"
+ test "$sym" = "$(test-absolute-path "$dir2/syml")"
'
test_expect_success 'very long name in the index handled sanely' '
diff --git a/t/t1020-subdirectory.sh b/t/t1020-subdirectory.sh
index b9cef34..fc386ba 100755
--- a/t/t1020-subdirectory.sh
+++ b/t/t1020-subdirectory.sh
@@ -21,7 +21,7 @@ LF='
'
test_expect_success 'update-index and ls-files' '
- cd $HERE &&
+ cd "$HERE" &&
git update-index --add one &&
case "`git ls-files`" in
one) echo ok one ;;
@@ -41,7 +41,7 @@ test_expect_success 'update-index and ls-files' '
'
test_expect_success 'cat-file' '
- cd $HERE &&
+ cd "$HERE" &&
two=`git ls-files -s dir/two` &&
two=`expr "$two" : "[0-7]* \\([0-9a-f]*\\)"` &&
echo "$two" &&
@@ -54,7 +54,7 @@ test_expect_success 'cat-file' '
rm -f actual dir/actual
test_expect_success 'diff-files' '
- cd $HERE &&
+ cd "$HERE" &&
echo a >>one &&
echo d >>dir/two &&
case "`git diff-files --name-only`" in
@@ -74,7 +74,7 @@ test_expect_success 'diff-files' '
'
test_expect_success 'write-tree' '
- cd $HERE &&
+ cd "$HERE" &&
top=`git write-tree` &&
echo $top &&
cd dir &&
@@ -84,7 +84,7 @@ test_expect_success 'write-tree' '
'
test_expect_success 'checkout-index' '
- cd $HERE &&
+ cd "$HERE" &&
git checkout-index -f -u one &&
cmp one original.one &&
cd dir &&
@@ -93,7 +93,7 @@ test_expect_success 'checkout-index' '
'
test_expect_success 'read-tree' '
- cd $HERE &&
+ cd "$HERE" &&
rm -f one dir/two &&
tree=`git write-tree` &&
git read-tree --reset -u "$tree" &&
@@ -107,27 +107,27 @@ test_expect_success 'read-tree' '
'
test_expect_success 'no file/rev ambiguity check inside .git' '
- cd $HERE &&
+ cd "$HERE" &&
git commit -a -m 1 &&
- cd $HERE/.git &&
+ cd "$HERE"/.git &&
git show -s HEAD
'
test_expect_success 'no file/rev ambiguity check inside a bare repo' '
- cd $HERE &&
+ cd "$HERE" &&
git clone -s --bare .git foo.git &&
cd foo.git && GIT_DIR=. git show -s HEAD
'
# This still does not work as it should...
: test_expect_success 'no file/rev ambiguity check inside a bare repo' '
- cd $HERE &&
+ cd "$HERE" &&
git clone -s --bare .git foo.git &&
cd foo.git && git show -s HEAD
'
test_expect_success 'detection should not be fooled by a symlink' '
- cd $HERE &&
+ cd "$HERE" &&
rm -fr foo.git &&
git clone -s .git another &&
ln -s another yetanother &&
diff --git a/t/t3050-subprojects-fetch.sh b/t/t3050-subprojects-fetch.sh
index 2b21b10..4261e96 100755
--- a/t/t3050-subprojects-fetch.sh
+++ b/t/t3050-subprojects-fetch.sh
@@ -20,7 +20,7 @@ test_expect_success setup '
'
test_expect_success clone '
- git clone file://`pwd`/.git cloned &&
+ git clone "file://$(pwd)/.git" cloned &&
(git rev-parse HEAD; git ls-files -s) >expected &&
(
cd cloned &&
diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh
index 9cf873f..b9e3dbd 100755
--- a/t/t3404-rebase-interactive.sh
+++ b/t/t3404-rebase-interactive.sh
@@ -91,9 +91,8 @@ for line in $FAKE_LINES; do
done
EOF
+test_set_editor "$(pwd)/fake-editor.sh"
chmod a+x fake-editor.sh
-VISUAL="$(pwd)/fake-editor.sh"
-export VISUAL
test_expect_success 'no changes are a nop' '
git rebase -i F &&
diff --git a/t/t5500-fetch-pack.sh b/t/t5500-fetch-pack.sh
index 1700d07..140e874 100755
--- a/t/t5500-fetch-pack.sh
+++ b/t/t5500-fetch-pack.sh
@@ -129,7 +129,7 @@ pull_to_client 2nd "B" $((64*3))
pull_to_client 3rd "A" $((1*3)) # old fails
-test_expect_success "clone shallow" "git-clone --depth 2 file://`pwd`/. shallow"
+test_expect_success "clone shallow" 'git-clone --depth 2 "file://$(pwd)/." shallow'
(cd shallow; git count-objects -v) > count.shallow
diff --git a/t/t5512-ls-remote.sh b/t/t5512-ls-remote.sh
index c0dc949..1dd8eed 100755
--- a/t/t5512-ls-remote.sh
+++ b/t/t5512-ls-remote.sh
@@ -17,7 +17,7 @@ test_expect_success setup '
git show-ref -d | sed -e "s/ / /"
) >expected.all &&
- git remote add self $(pwd)/.git
+ git remote add self "$(pwd)/.git"
'
diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh
index 793ffc6..2b2b2ef 100755
--- a/t/t5516-fetch-push.sh
+++ b/t/t5516-fetch-push.sh
@@ -105,7 +105,7 @@ test_expect_success 'fetch with insteadOf' '
(
TRASH=$(pwd) &&
cd testrepo &&
- git config url./$TRASH/.insteadOf trash/
+ git config "url./$TRASH/.insteadOf" trash/ &&
git config remote.up.url trash/. &&
git config remote.up.fetch "refs/heads/*:refs/remotes/origin/*" &&
git fetch up &&
@@ -146,7 +146,7 @@ test_expect_success 'push with wildcard' '
test_expect_success 'push with insteadOf' '
mk_empty &&
TRASH=$(pwd) &&
- git config url./$TRASH/.insteadOf trash/ &&
+ git config "url./$TRASH/.insteadOf" trash/ &&
git push trash/testrepo refs/heads/master:refs/remotes/origin/master &&
(
cd testrepo &&
diff --git a/t/t5700-clone-reference.sh b/t/t5700-clone-reference.sh
index b6a5486..e5619a9 100755
--- a/t/t5700-clone-reference.sh
+++ b/t/t5700-clone-reference.sh
@@ -51,7 +51,7 @@ diff expected current'
cd "$base_dir"
test_expect_success 'cloning with reference (no -l -s)' \
-'git clone --reference B file://`pwd`/A D'
+'git clone --reference B "file://$(pwd)/A" D'
cd "$base_dir"
diff --git a/t/t5710-info-alternate.sh b/t/t5710-info-alternate.sh
index 910ccb4..1abf1a2 100755
--- a/t/t5710-info-alternate.sh
+++ b/t/t5710-info-alternate.sh
@@ -81,7 +81,7 @@ test_valid_repo'
cd "$base_dir"
test_expect_success 'breaking of loops' \
-"echo '$base_dir/B/.git/objects' >> '$base_dir'/A/.git/objects/info/alternates&&
+"echo \"\$base_dir\"/B/.git/objects >> \"\$base_dir\"/A/.git/objects/info/alternates&&
cd C &&
test_valid_repo"
diff --git a/t/t7003-filter-branch.sh b/t/t7003-filter-branch.sh
index efd658a..fd09030 100755
--- a/t/t7003-filter-branch.sh
+++ b/t/t7003-filter-branch.sh
@@ -125,7 +125,7 @@ test_expect_success 'use index-filter to move into a subdirectory' '
"git ls-files -s | sed \"s-\\t-&newsubdir/-\" |
GIT_INDEX_FILE=\$GIT_INDEX_FILE.new \
git update-index --index-info &&
- mv \$GIT_INDEX_FILE.new \$GIT_INDEX_FILE" directorymoved &&
+ mv \"\$GIT_INDEX_FILE.new\" \"\$GIT_INDEX_FILE\"" directorymoved &&
test -z "$(git diff HEAD directorymoved:newsubdir)"'
test_expect_success 'stops when msg filter fails' '
diff --git a/t/t7010-setup.sh b/t/t7010-setup.sh
index 02cf7c5..d8a7c79 100755
--- a/t/t7010-setup.sh
+++ b/t/t7010-setup.sh
@@ -122,7 +122,7 @@ test_expect_success 'commit using absolute path names' '
test_expect_success 'log using absolute path names' '
echo bb >>a/b/c/d &&
- git commit -m "bb" $(pwd)/a/b/c/d &&
+ git commit -m "bb" "$(pwd)/a/b/c/d" &&
git log a/b/c/d >f1.txt &&
git log "$(pwd)/a/b/c/d" >f2.txt &&
diff --git a/t/t7300-clean.sh b/t/t7300-clean.sh
index afccfc9..54b1352 100755
--- a/t/t7300-clean.sh
+++ b/t/t7300-clean.sh
@@ -111,7 +111,7 @@ test_expect_success 'git-clean with absolute path' '
touch a.out src/part3.c docs/manual.txt obj.o build/lib.so &&
would_clean=$(
cd docs &&
- git clean -n $(pwd)/../src |
+ git clean -n "$(pwd)/../src" |
sed -n -e "s|^Would remove ||p"
) &&
test "$would_clean" = ../src/part3.c || {
diff --git a/t/t7501-commit.sh b/t/t7501-commit.sh
index c0288f3..e5fdb63 100755
--- a/t/t7501-commit.sh
+++ b/t/t7501-commit.sh
@@ -79,8 +79,8 @@ test_expect_success \
cat >editor <<\EOF
#!/bin/sh
-sed -e "s/a file/an amend commit/g" < $1 > $1-
-mv $1- $1
+sed -e "s/a file/an amend commit/g" < "$1" > "$1-"
+mv "$1-" "$1"
EOF
chmod 755 editor
@@ -99,8 +99,8 @@ test_expect_success \
cat >editor <<\EOF
#!/bin/sh
-sed -e "s/amend/older/g" < $1 > $1-
-mv $1- $1
+sed -e "s/amend/older/g" < "$1" > "$1-"
+mv "$1-" "$1"
EOF
chmod 755 editor
diff --git a/t/t7504-commit-msg-hook.sh b/t/t7504-commit-msg-hook.sh
index eff36aa..88577af 100755
--- a/t/t7504-commit-msg-hook.sh
+++ b/t/t7504-commit-msg-hook.sh
@@ -19,6 +19,9 @@ cp FAKE_MSG "$1"
exit 0
EOF
chmod +x fake-editor
+
+## Not using test_set_editor here so we can easily ensure the editor variable
+## is only set for the editor tests
FAKE_EDITOR="$(pwd)/fake-editor"
export FAKE_EDITOR
@@ -27,7 +30,7 @@ test_expect_success 'with no hook (editor)' '
echo "more foo" >> file &&
git add file &&
echo "more foo" > FAKE_MSG &&
- GIT_EDITOR="$FAKE_EDITOR" git commit
+ GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit
'
@@ -44,7 +47,7 @@ test_expect_success '--no-verify with no hook (editor)' '
echo "more bar" > file &&
git add file &&
echo "more bar" > FAKE_MSG &&
- GIT_EDITOR="$FAKE_EDITOR" git commit --no-verify
+ GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit --no-verify
'
@@ -71,7 +74,7 @@ test_expect_success 'with succeeding hook (editor)' '
echo "more more" >> file &&
git add file &&
echo "more more" > FAKE_MSG &&
- GIT_EDITOR="$FAKE_EDITOR" git commit
+ GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit
'
@@ -88,7 +91,7 @@ test_expect_success '--no-verify with succeeding hook (editor)' '
echo "even more more" >> file &&
git add file &&
echo "even more more" > FAKE_MSG &&
- GIT_EDITOR="$FAKE_EDITOR" git commit --no-verify
+ GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit --no-verify
'
@@ -111,7 +114,7 @@ test_expect_success 'with failing hook (editor)' '
echo "more another" >> file &&
git add file &&
echo "more another" > FAKE_MSG &&
- ! (GIT_EDITOR="$FAKE_EDITOR" git commit)
+ ! (GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit)
'
@@ -128,7 +131,7 @@ test_expect_success '--no-verify with failing hook (editor)' '
echo "more stuff" >> file &&
git add file &&
echo "more stuff" > FAKE_MSG &&
- GIT_EDITOR="$FAKE_EDITOR" git commit --no-verify
+ GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit --no-verify
'
@@ -146,7 +149,7 @@ test_expect_success 'with non-executable hook (editor)' '
echo "content again" >> file &&
git add file &&
echo "content again" > FAKE_MSG &&
- GIT_EDITOR="$FAKE_EDITOR" git commit -m "content again"
+ GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit -m "content again"
'
@@ -163,7 +166,7 @@ test_expect_success '--no-verify with non-executable hook (editor)' '
echo "even more content" >> file &&
git add file &&
echo "even more content" > FAKE_MSG &&
- GIT_EDITOR="$FAKE_EDITOR" git commit --no-verify
+ GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit --no-verify
'
@@ -193,7 +196,7 @@ test_expect_success 'hook edits commit message (editor)' '
echo "additional content" >> file &&
git add file &&
echo "additional content" > FAKE_MSG &&
- GIT_EDITOR="$FAKE_EDITOR" git commit &&
+ GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit &&
commit_msg_is "new message"
'
@@ -212,7 +215,7 @@ test_expect_success "hook doesn't edit commit message (editor)" '
echo "more plus" >> file &&
git add file &&
echo "more plus" > FAKE_MSG &&
- GIT_EDITOR="$FAKE_EDITOR" git commit --no-verify &&
+ GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit --no-verify &&
commit_msg_is "more plus"
'
diff --git a/t/t7505-prepare-commit-msg-hook.sh b/t/t7505-prepare-commit-msg-hook.sh
index 802aa62..cd6c7c8 100755
--- a/t/t7505-prepare-commit-msg-hook.sh
+++ b/t/t7505-prepare-commit-msg-hook.sh
@@ -18,6 +18,9 @@ cat > fake-editor <<'EOF'
exit 0
EOF
chmod +x fake-editor
+
+## Not using test_set_editor here so we can easily ensure the editor variable
+## is only set for the editor tests
FAKE_EDITOR="$(pwd)/fake-editor"
export FAKE_EDITOR
@@ -58,7 +61,7 @@ test_expect_success 'with hook (-m editor)' '
echo "more" >> file &&
git add file &&
- GIT_EDITOR="$FAKE_EDITOR" git commit -e -m "more more" &&
+ GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit -e -m "more more" &&
test "`git log -1 --pretty=format:%s`" = message
'
@@ -85,7 +88,7 @@ test_expect_success 'with hook (-F editor)' '
echo "more" >> file &&
git add file &&
- (echo more more | GIT_EDITOR="$FAKE_EDITOR" git commit -e -F -) &&
+ (echo more more | GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit -e -F -) &&
test "`git log -1 --pretty=format:%s`" = message
'
@@ -104,7 +107,7 @@ test_expect_success 'with hook (editor)' '
echo "more more" >> file &&
git add file &&
- GIT_EDITOR="$FAKE_EDITOR" git commit &&
+ GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit &&
test "`git log -1 --pretty=format:%s`" = default
'
@@ -114,7 +117,7 @@ test_expect_success 'with hook (--amend)' '
head=`git rev-parse HEAD` &&
echo "more" >> file &&
git add file &&
- GIT_EDITOR="$FAKE_EDITOR" git commit --amend &&
+ GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit --amend &&
test "`git log -1 --pretty=format:%s`" = "$head"
'
@@ -124,7 +127,7 @@ test_expect_success 'with hook (-c)' '
head=`git rev-parse HEAD` &&
echo "more" >> file &&
git add file &&
- GIT_EDITOR="$FAKE_EDITOR" git commit -c $head &&
+ GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit -c $head &&
test "`git log -1 --pretty=format:%s`" = "$head"
'
@@ -139,7 +142,7 @@ test_expect_success 'with failing hook' '
head=`git rev-parse HEAD` &&
echo "more" >> file &&
git add file &&
- ! GIT_EDITOR="$FAKE_EDITOR" git commit -c $head
+ ! GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit -c $head
'
@@ -148,7 +151,7 @@ test_expect_success 'with failing hook (--no-verify)' '
head=`git rev-parse HEAD` &&
echo "more" >> file &&
git add file &&
- ! GIT_EDITOR="$FAKE_EDITOR" git commit --no-verify -c $head
+ ! GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit --no-verify -c $head
'
diff --git a/t/t9100-git-svn-basic.sh b/t/t9100-git-svn-basic.sh
index 4e24ab3..528c0a9 100755
--- a/t/t9100-git-svn-basic.sh
+++ b/t/t9100-git-svn-basic.sh
@@ -31,16 +31,16 @@ test_expect_success \
echo 'zzz' > bar/zzz &&
echo '#!/bin/sh' > exec.sh &&
chmod +x exec.sh &&
- svn import -m 'import for git-svn' . $svnrepo >/dev/null &&
+ svn import -m 'import for git-svn' . \"\$svnrepo\" >/dev/null &&
cd .. &&
rm -rf import &&
- git-svn init $svnrepo"
+ git-svn init \"\$svnrepo\""
test_expect_success \
'import an SVN revision into git' \
'git-svn fetch'
-test_expect_success "checkout from svn" "svn co $svnrepo '$SVN_TREE'"
+test_expect_success "checkout from svn" "svn co \"\$svnrepo\" \"\$SVN_TREE\""
name='try a deep --rmdir with a commit'
test_expect_success "$name" "
@@ -51,8 +51,8 @@ test_expect_success "$name" "
git commit -m '$name' &&
git-svn set-tree --find-copies-harder --rmdir \
remotes/git-svn..mybranch &&
- svn up '$SVN_TREE' &&
- test -d '$SVN_TREE'/dir && test ! -d '$SVN_TREE'/dir/a"
+ svn up \"\$SVN_TREE\" &&
+ test -d \"\$SVN_TREE\"/dir && test ! -d \"\$SVN_TREE\"/dir/a"
name='detect node change from file to directory #1'
@@ -69,7 +69,7 @@ test_expect_success "$name" "
name='detect node change from directory to file #1'
test_expect_success "$name" "
- rm -rf dir '$GIT_DIR'/index &&
+ rm -rf dir \"\$GIT_DIR\"/index &&
git checkout -f -b mybranch2 remotes/git-svn &&
mv bar/zzz zzz &&
rm -rf bar &&
@@ -83,7 +83,7 @@ test_expect_success "$name" "
name='detect node change from file to directory #2'
test_expect_success "$name" "
- rm -f '$GIT_DIR'/index &&
+ rm -f \"\$GIT_DIR\"/index &&
git checkout -f -b mybranch3 remotes/git-svn &&
rm bar/zzz &&
git update-index --remove bar/zzz &&
@@ -97,7 +97,7 @@ test_expect_success "$name" "
name='detect node change from directory to file #2'
test_expect_success "$name" "
- rm -f '$GIT_DIR'/index &&
+ rm -f \"\$GIT_DIR\"/index &&
git checkout -f -b mybranch4 remotes/git-svn &&
rm -rf dir &&
git update-index --remove -- dir/file &&
@@ -111,15 +111,15 @@ test_expect_success "$name" "
name='remove executable bit from a file'
test_expect_success "$name" "
- rm -f '$GIT_DIR'/index &&
+ rm -f \"\$GIT_DIR\"/index &&
git checkout -f -b mybranch5 remotes/git-svn &&
chmod -x exec.sh &&
git update-index exec.sh &&
git commit -m '$name' &&
git-svn set-tree --find-copies-harder --rmdir \
remotes/git-svn..mybranch5 &&
- svn up '$SVN_TREE' &&
- test ! -x '$SVN_TREE'/exec.sh"
+ svn up \"\$SVN_TREE\" &&
+ test ! -x \"\$SVN_TREE\"/exec.sh"
name='add executable bit back file'
@@ -129,8 +129,8 @@ test_expect_success "$name" "
git commit -m '$name' &&
git-svn set-tree --find-copies-harder --rmdir \
remotes/git-svn..mybranch5 &&
- svn up '$SVN_TREE' &&
- test -x '$SVN_TREE'/exec.sh"
+ svn up \"\$SVN_TREE\" &&
+ test -x \"\$SVN_TREE\"/exec.sh"
name='executable file becomes a symlink to bar/zzz (file)'
@@ -141,8 +141,8 @@ test_expect_success "$name" "
git commit -m '$name' &&
git-svn set-tree --find-copies-harder --rmdir \
remotes/git-svn..mybranch5 &&
- svn up '$SVN_TREE' &&
- test -L '$SVN_TREE'/exec.sh"
+ svn up \"\$SVN_TREE\" &&
+ test -L \"\$SVN_TREE\"/exec.sh"
name='new symlink is added to a file that was also just made executable'
@@ -153,9 +153,9 @@ test_expect_success "$name" "
git commit -m '$name' &&
git-svn set-tree --find-copies-harder --rmdir \
remotes/git-svn..mybranch5 &&
- svn up '$SVN_TREE' &&
- test -x '$SVN_TREE'/bar/zzz &&
- test -L '$SVN_TREE'/exec-2.sh"
+ svn up \"\$SVN_TREE\" &&
+ test -x \"\$SVN_TREE\"/bar/zzz &&
+ test -L \"\$SVN_TREE\"/exec-2.sh"
name='modify a symlink to become a file'
test_expect_success "$name" "
@@ -166,10 +166,10 @@ test_expect_success "$name" "
git commit -m '$name' &&
git-svn set-tree --find-copies-harder --rmdir \
remotes/git-svn..mybranch5 &&
- svn up '$SVN_TREE' &&
- test -f '$SVN_TREE'/exec-2.sh &&
- test ! -L '$SVN_TREE'/exec-2.sh &&
- git diff help $SVN_TREE/exec-2.sh"
+ svn up \"\$SVN_TREE\" &&
+ test -f \"\$SVN_TREE\"/exec-2.sh &&
+ test ! -L \"\$SVN_TREE\"/exec-2.sh &&
+ git diff help \"\$SVN_TREE\"/exec-2.sh"
if test "$have_utf8" = t
then
@@ -190,7 +190,7 @@ name='test fetch functionality (svn => git) with alternate GIT_SVN_ID'
GIT_SVN_ID=alt
export GIT_SVN_ID
test_expect_success "$name" \
- "git-svn init $svnrepo && git-svn fetch &&
+ "git-svn init \"\$svnrepo\" && git-svn fetch &&
git rev-list --pretty=raw remotes/git-svn | grep ^tree | uniq > a &&
git rev-list --pretty=raw remotes/alt | grep ^tree | uniq > b &&
git diff a b"
@@ -220,16 +220,16 @@ test_expect_success 'exit if remote refs are ambigious' "
"
test_expect_success 'exit if init-ing a would clobber a URL' "
- svnadmin create ${PWD}/svnrepo2 &&
- svn mkdir -m 'mkdir bar' ${svnrepo}2/bar &&
+ svnadmin create \"\${PWD}/svnrepo2\" &&
+ svn mkdir -m 'mkdir bar' \"\${svnrepo}2/bar\" &&
git config --unset svn-remote.svn.fetch \
'^bar:refs/remotes/git-svn$' &&
- ! git-svn init ${svnrepo}2/bar
+ ! git-svn init \"\${svnrepo}2/bar\"
"
test_expect_success \
'init allows us to connect to another directory in the same repo' "
- git-svn init --minimize-url -i bar $svnrepo/bar &&
+ git-svn init --minimize-url -i bar \"\$svnrepo/bar\" &&
git config --get svn-remote.svn.fetch \
'^bar:refs/remotes/bar$' &&
git config --get svn-remote.svn.fetch \
diff --git a/t/t9101-git-svn-props.sh b/t/t9101-git-svn-props.sh
index d7a7047..fa8b7ee 100755
--- a/t/t9101-git-svn-props.sh
+++ b/t/t9101-git-svn-props.sh
@@ -52,7 +52,7 @@ EOF
cd ..
rm -rf import
-test_expect_success 'checkout working copy from svn' "svn co $svnrepo test_wc"
+test_expect_success 'checkout working copy from svn' "svn co \"\$svnrepo\" test_wc"
test_expect_success 'setup some commits to svn' \
'cd test_wc &&
echo Greetings >> kw.c &&
@@ -66,7 +66,7 @@ test_expect_success 'setup some commits to svn' \
svn commit -m "Propset Id" &&
cd ..'
-test_expect_success 'initialize git-svn' "git-svn init $svnrepo"
+test_expect_success 'initialize git-svn' "git-svn init \"\$svnrepo\""
test_expect_success 'fetch revisions from svn' 'git-svn fetch'
name='test svn:keywords ignoring'
@@ -92,7 +92,7 @@ test_expect_success "propset CR on crlf files" \
test_expect_success 'fetch and pull latest from svn and checkout a new wc' \
"git-svn fetch &&
git pull . remotes/git-svn &&
- svn co $svnrepo new_wc"
+ svn co \"\$svnrepo\" new_wc"
for i in crlf ne_crlf lf ne_lf cr ne_cr empty_cr empty_lf empty empty_crlf
do
diff --git a/t/t9102-git-svn-deep-rmdir.sh b/t/t9102-git-svn-deep-rmdir.sh
index 4e08083..8eaf7d3 100755
--- a/t/t9102-git-svn-deep-rmdir.sh
+++ b/t/t9102-git-svn-deep-rmdir.sh
@@ -9,12 +9,12 @@ test_expect_success 'initialize repo' "
mkdir -p deeply/nested/directory/number/2 &&
echo foo > deeply/nested/directory/number/1/file &&
echo foo > deeply/nested/directory/number/2/another &&
- svn import -m 'import for git-svn' . $svnrepo &&
+ svn import -m 'import for git-svn' . \"\$svnrepo\" &&
cd ..
"
test_expect_success 'mirror via git-svn' "
- git-svn init $svnrepo &&
+ git-svn init \"\$svnrepo\" &&
git-svn fetch &&
git checkout -f -b test-rmdir remotes/git-svn
"
@@ -23,7 +23,7 @@ test_expect_success 'Try a commit on rmdir' "
git rm -f deeply/nested/directory/number/2/another &&
git commit -a -m 'remove another' &&
git-svn set-tree --rmdir HEAD &&
- svn ls -R $svnrepo | grep ^deeply/nested/directory/number/1
+ svn ls -R \"\$svnrepo\" | grep ^deeply/nested/directory/number/1
"
diff --git a/t/t9103-git-svn-tracked-directory-removed.sh b/t/t9103-git-svn-tracked-directory-removed.sh
index 0f0b0fd..c7734e6 100755
--- a/t/t9103-git-svn-tracked-directory-removed.sh
+++ b/t/t9103-git-svn-tracked-directory-removed.sh
@@ -6,34 +6,34 @@
test_description='git-svn tracking removed top-level path'
. ./lib-git-svn.sh
-test_expect_success 'make history for tracking' '
+test_expect_success 'make history for tracking' "
mkdir import &&
mkdir import/trunk &&
echo hello >> import/trunk/README &&
- svn import -m initial import $svnrepo &&
+ svn import -m initial import \"\$svnrepo\" &&
rm -rf import &&
- svn co $svnrepo/trunk trunk &&
+ svn co \"\$svnrepo\"/trunk trunk &&
echo bye bye >> trunk/README &&
- svn rm -m "gone" $svnrepo/trunk &&
+ svn rm -m 'gone' \"\$svnrepo\"/trunk &&
rm -rf trunk &&
mkdir trunk &&
- echo "new" > trunk/FOLLOWME &&
- svn import -m "new trunk" trunk $svnrepo/trunk
-'
+ echo 'new' > trunk/FOLLOWME &&
+ svn import -m 'new trunk' trunk \"\$svnrepo\"/trunk
+"
-test_expect_success 'clone repo with git' '
- git svn clone -s $svnrepo x &&
+test_expect_success 'clone repo with git' "
+ git svn clone -s \"\$svnrepo\" x &&
test -f x/FOLLOWME &&
test ! -f x/README
-'
+"
-test_expect_success 'make sure r2 still has old file' '
+test_expect_success 'make sure r2 still has old file' "
cd x &&
- test -n "$(git svn find-rev r1)" &&
- git reset --hard $(git svn find-rev r1) &&
+ test -n \"\$(git svn find-rev r1)\" &&
+ git reset --hard \$(git svn find-rev r1) &&
test -f README &&
test ! -f FOLLOWME &&
- test x$(git svn find-rev r2) = x
-'
+ test x\$(git svn find-rev r2) = x
+"
test_done
diff --git a/t/t9104-git-svn-follow-parent.sh b/t/t9104-git-svn-follow-parent.sh
index 7ba7630..56b1704 100755
--- a/t/t9104-git-svn-follow-parent.sh
+++ b/t/t9104-git-svn-follow-parent.sh
@@ -11,9 +11,9 @@ test_expect_success 'initialize repo' "
cd import &&
mkdir -p trunk &&
echo hello > trunk/readme &&
- svn import -m 'initial' . $svnrepo &&
+ svn import -m 'initial' . \"\$svnrepo\" &&
cd .. &&
- svn co $svnrepo wc &&
+ svn co \"\$svnrepo\" wc &&
cd wc &&
echo world >> trunk/readme &&
poke trunk/readme &&
@@ -27,7 +27,7 @@ test_expect_success 'initialize repo' "
"
test_expect_success 'init and fetch a moved directory' "
- git-svn init --minimize-url -i thunk $svnrepo/thunk &&
+ git-svn init --minimize-url -i thunk \"\$svnrepo\"/thunk &&
git-svn fetch -i thunk &&
test \"\`git rev-parse --verify refs/remotes/thunk@2\`\" \
= \"\`git rev-parse --verify refs/remotes/thunk~1\`\" &&
@@ -38,7 +38,7 @@ test_expect_success 'init and fetch a moved directory' "
"
test_expect_success 'init and fetch from one svn-remote' "
- git config svn-remote.svn.url $svnrepo &&
+ git config svn-remote.svn.url \"\$svnrepo\" &&
git config --add svn-remote.svn.fetch \
trunk:refs/remotes/svn/trunk &&
git config --add svn-remote.svn.fetch \
@@ -52,9 +52,9 @@ test_expect_success 'init and fetch from one svn-remote' "
test_expect_success 'follow deleted parent' "
(svn cp -m 'resurrecting trunk as junk' \
- $svnrepo/trunk@2 $svnrepo/junk ||
+ \"\$svnrepo\"/trunk@2 \"\$svnrepo\"/junk ||
svn cp -m 'resurrecting trunk as junk' \
- -r2 $svnrepo/trunk $svnrepo/junk) &&
+ -r2 \"\$svnrepo\"/trunk \"\$svnrepo\"/junk) &&
git config --add svn-remote.svn.fetch \
junk:refs/remotes/svn/junk &&
git-svn fetch -i svn/thunk &&
@@ -67,10 +67,10 @@ test_expect_success 'follow deleted parent' "
test_expect_success 'follow larger parent' "
mkdir -p import/trunk/thunk/bump/thud &&
echo hi > import/trunk/thunk/bump/thud/file &&
- svn import -m 'import a larger parent' import $svnrepo/larger-parent &&
- svn cp -m 'hi' $svnrepo/larger-parent $svnrepo/another-larger &&
+ svn import -m 'import a larger parent' import \"\$svnrepo\"/larger-parent &&
+ svn cp -m 'hi' \"\$svnrepo\"/larger-parent \"\$svnrepo\"/another-larger &&
git-svn init --minimize-url -i larger \
- $svnrepo/another-larger/trunk/thunk/bump/thud &&
+ \"\$svnrepo\"/another-larger/trunk/thunk/bump/thud &&
git-svn fetch -i larger &&
git rev-parse --verify refs/remotes/larger &&
git rev-parse --verify \
@@ -83,23 +83,23 @@ test_expect_success 'follow larger parent' "
"
test_expect_success 'follow higher-level parent' "
- svn mkdir -m 'follow higher-level parent' $svnrepo/blob &&
- svn co $svnrepo/blob blob &&
+ svn mkdir -m 'follow higher-level parent' \"\$svnrepo\"/blob &&
+ svn co \"\$svnrepo\"/blob blob &&
cd blob &&
echo hi > hi &&
svn add hi &&
svn commit -m 'hihi' &&
cd ..
- svn mkdir -m 'new glob at top level' $svnrepo/glob &&
- svn mv -m 'move blob down a level' $svnrepo/blob $svnrepo/glob/blob &&
- git-svn init --minimize-url -i blob $svnrepo/glob/blob &&
+ svn mkdir -m 'new glob at top level' \"\$svnrepo\"/glob &&
+ svn mv -m 'move blob down a level' \"\$svnrepo\"/blob \"\$svnrepo\"/glob/blob &&
+ git-svn init --minimize-url -i blob \"\$svnrepo\"/glob/blob &&
git-svn fetch -i blob
"
test_expect_success 'follow deleted directory' "
- svn mv -m 'bye!' $svnrepo/glob/blob/hi $svnrepo/glob/blob/bye &&
- svn rm -m 'remove glob' $svnrepo/glob &&
- git-svn init --minimize-url -i glob $svnrepo/glob &&
+ svn mv -m 'bye!' \"\$svnrepo\"/glob/blob/hi \"\$svnrepo\"/glob/blob/bye &&
+ svn rm -m 'remove glob' \"\$svnrepo\"/glob &&
+ git-svn init --minimize-url -i glob \"\$svnrepo\"/glob &&
git-svn fetch -i glob &&
test \"\`git cat-file blob refs/remotes/glob:blob/bye\`\" = hi &&
test \"\`git ls-tree refs/remotes/glob | wc -l \`\" -eq 1
@@ -118,9 +118,9 @@ test_expect_success 'follow-parent avoids deleting relevant info' "
echo 'bad delete test 2' > \
import/trunk/subversion/bindings/swig/perl/another-larger &&
cd import &&
- svn import -m 'r9270 test' . $svnrepo/r9270 &&
+ svn import -m 'r9270 test' . \"\$svnrepo\"/r9270 &&
cd .. &&
- svn co $svnrepo/r9270/trunk/subversion/bindings/swig/perl r9270 &&
+ svn co \"\$svnrepo\"/r9270/trunk/subversion/bindings/swig/perl r9270 &&
cd r9270 &&
svn mkdir native &&
svn mv t native/t &&
@@ -130,7 +130,7 @@ test_expect_success 'follow-parent avoids deleting relevant info' "
svn commit -m 'reorg test' &&
cd .. &&
git-svn init --minimize-url -i r9270-t \
- $svnrepo/r9270/trunk/subversion/bindings/swig/perl/native/t &&
+ \"\$svnrepo\"/r9270/trunk/subversion/bindings/swig/perl/native/t &&
git-svn fetch -i r9270-t &&
test \`git rev-list r9270-t | wc -l\` -eq 2 &&
test \"\`git ls-tree --name-only r9270-t~1\`\" = \
@@ -138,9 +138,9 @@ test_expect_success 'follow-parent avoids deleting relevant info' "
"
test_expect_success "track initial change if it was only made to parent" "
- svn cp -m 'wheee!' $svnrepo/r9270/trunk $svnrepo/r9270/drunk &&
+ svn cp -m 'wheee!' \"\$svnrepo\"/r9270/trunk \"\$svnrepo\"/r9270/drunk &&
git-svn init --minimize-url -i r9270-d \
- $svnrepo/r9270/drunk/subversion/bindings/swig/perl/native/t &&
+ \"\$svnrepo\"/r9270/drunk/subversion/bindings/swig/perl/native/t &&
git-svn fetch -i r9270-d &&
test \`git rev-list r9270-d | wc -l\` -eq 3 &&
test \"\`git ls-tree --name-only r9270-t\`\" = \
@@ -150,7 +150,7 @@ test_expect_success "track initial change if it was only made to parent" "
"
test_expect_success "track multi-parent paths" "
- svn cp -m 'resurrect /glob' $svnrepo/r9270 $svnrepo/glob &&
+ svn cp -m 'resurrect /glob' \"\$svnrepo\"/r9270 \"\$svnrepo\"/glob &&
git-svn multi-fetch &&
test \`git cat-file commit refs/remotes/glob | \
grep '^parent ' | wc -l\` -eq 2
@@ -161,8 +161,8 @@ test_expect_success "multi-fetch continues to work" "
"
test_expect_success "multi-fetch works off a 'clean' repository" "
- rm -r $GIT_DIR/svn $GIT_DIR/refs/remotes $GIT_DIR/logs &&
- mkdir $GIT_DIR/svn &&
+ rm -r \"\$GIT_DIR/svn\" \"\$GIT_DIR/refs/remotes\" \"\$GIT_DIR/logs\" &&
+ mkdir \"\$GIT_DIR/svn\" &&
git-svn multi-fetch
"
diff --git a/t/t9105-git-svn-commit-diff.sh b/t/t9105-git-svn-commit-diff.sh
index 318e172..4f7f9cc 100755
--- a/t/t9105-git-svn-commit-diff.sh
+++ b/t/t9105-git-svn-commit-diff.sh
@@ -8,7 +8,7 @@ test_expect_success 'initialize repo' "
mkdir import &&
cd import &&
echo hello > readme &&
- svn import -m 'initial' . $svnrepo &&
+ svn import -m 'initial' . \"\$svnrepo\" &&
cd .. &&
echo hello > readme &&
git update-index --add readme &&
@@ -26,17 +26,17 @@ prev=`git rev-parse --verify HEAD^1`
test_expect_success 'test the commit-diff command' "
test -n '$prev' && test -n '$head' &&
- git-svn commit-diff -r1 '$prev' '$head' '$svnrepo' &&
- svn co $svnrepo wc &&
+ git-svn commit-diff -r1 '$prev' '$head' \"\$svnrepo\" &&
+ svn co \"\$svnrepo\" wc &&
cmp readme wc/readme
"
test_expect_success 'commit-diff to a sub-directory (with git-svn config)' "
- svn import -m 'sub-directory' import $svnrepo/subdir &&
- git-svn init --minimize-url $svnrepo/subdir &&
+ svn import -m 'sub-directory' import \"\$svnrepo\"/subdir &&
+ git-svn init --minimize-url \"\$svnrepo\"/subdir &&
git-svn fetch &&
git-svn commit-diff -r3 '$prev' '$head' &&
- svn cat $svnrepo/subdir/readme > readme.2 &&
+ svn cat \"\$svnrepo\"/subdir/readme > readme.2 &&
cmp readme readme.2
"
diff --git a/t/t9106-git-svn-commit-diff-clobber.sh b/t/t9106-git-svn-commit-diff-clobber.sh
index f74ab12..bb544f6 100755
--- a/t/t9106-git-svn-commit-diff-clobber.sh
+++ b/t/t9106-git-svn-commit-diff-clobber.sh
@@ -8,14 +8,14 @@ test_expect_success 'initialize repo' "
mkdir import &&
cd import &&
echo initial > file &&
- svn import -m 'initial' . $svnrepo &&
+ svn import -m 'initial' . \"\$svnrepo\" &&
cd .. &&
echo initial > file &&
git update-index --add file &&
git commit -a -m 'initial'
"
test_expect_success 'commit change from svn side' "
- svn co $svnrepo t.svn &&
+ svn co \"\$svnrepo\" t.svn &&
cd t.svn &&
echo second line from svn >> file &&
poke file &&
@@ -27,7 +27,7 @@ test_expect_success 'commit change from svn side' "
test_expect_success 'commit conflicting change from git' "
echo second line from git >> file &&
git commit -a -m 'second line from git' &&
- ! git-svn commit-diff -r1 HEAD~1 HEAD $svnrepo
+ ! git-svn commit-diff -r1 HEAD~1 HEAD \"\$svnrepo\"
"
test_expect_success 'commit complementing change from git' "
@@ -36,14 +36,14 @@ test_expect_success 'commit complementing change from git' "
git commit -a -m 'second line from svn' &&
echo third line from git >> file &&
git commit -a -m 'third line from git' &&
- git-svn commit-diff -r2 HEAD~1 HEAD $svnrepo
+ git-svn commit-diff -r2 HEAD~1 HEAD \"\$svnrepo\"
"
test_expect_success 'dcommit fails to commit because of conflict' "
- git-svn init $svnrepo &&
+ git-svn init \"\$svnrepo\" &&
git-svn fetch &&
git reset --hard refs/remotes/git-svn &&
- svn co $svnrepo t.svn &&
+ svn co \"\$svnrepo\" t.svn &&
cd t.svn &&
echo fourth line from svn >> file &&
poke file &&
@@ -67,7 +67,7 @@ test_expect_success 'dcommit does the svn equivalent of an index merge' "
"
test_expect_success 'commit another change from svn side' "
- svn co $svnrepo t.svn &&
+ svn co \"\$svnrepo\" t.svn &&
cd t.svn &&
echo third line from svn >> file &&
poke file &&
diff --git a/t/t9106-git-svn-dcommit-clobber-series.sh b/t/t9106-git-svn-dcommit-clobber-series.sh
index ca8a00e..477755a 100755
--- a/t/t9106-git-svn-dcommit-clobber-series.sh
+++ b/t/t9106-git-svn-dcommit-clobber-series.sh
@@ -8,9 +8,9 @@ test_expect_success 'initialize repo' "
mkdir import &&
cd import &&
awk 'BEGIN { for (i = 1; i < 64; i++) { print i } }' > file
- svn import -m 'initial' . $svnrepo &&
+ svn import -m 'initial' . \"\$svnrepo\" &&
cd .. &&
- git svn init $svnrepo &&
+ git svn init \"\$svnrepo\" &&
git svn fetch &&
test -e file
"
@@ -18,7 +18,7 @@ test_expect_success 'initialize repo' "
test_expect_success '(supposedly) non-conflicting change from SVN' "
test x\"\`sed -n -e 58p < file\`\" = x58 &&
test x\"\`sed -n -e 61p < file\`\" = x61 &&
- svn co $svnrepo tmp &&
+ svn co \"\$svnrepo\" tmp &&
cd tmp &&
perl -i -p -e 's/^58\$/5588/' file &&
perl -i -p -e 's/^61\$/6611/' file &&
diff --git a/t/t9107-git-svn-migrate.sh b/t/t9107-git-svn-migrate.sh
index 0a41d52..9ab7074 100755
--- a/t/t9107-git-svn-migrate.sh
+++ b/t/t9107-git-svn-migrate.sh
@@ -4,7 +4,7 @@ test_description='git-svn metadata migrations from previous versions'
. ./lib-git-svn.sh
test_expect_success 'setup old-looking metadata' "
- cp $GIT_DIR/config $GIT_DIR/config-old-git-svn &&
+ cp \"\$GIT_DIR\"/config \"\$GIT_DIR\"/config-old-git-svn &&
mkdir import &&
cd import &&
for i in trunk branches/a branches/b \
@@ -12,13 +12,13 @@ test_expect_success 'setup old-looking metadata' "
mkdir -p \$i && \
echo hello >> \$i/README || exit 1
done && \
- svn import -m test . $svnrepo
+ svn import -m test . \"\$svnrepo\"
cd .. &&
- git-svn init $svnrepo &&
+ git-svn init \"\$svnrepo\" &&
git-svn fetch &&
- mv $GIT_DIR/svn/* $GIT_DIR/ &&
- mv $GIT_DIR/svn/.metadata $GIT_DIR/ &&
- rmdir $GIT_DIR/svn &&
+ mv \"\$GIT_DIR\"/svn/* \"\$GIT_DIR\"/ &&
+ mv \"\$GIT_DIR\"/svn/.metadata \"\$GIT_DIR\"/ &&
+ rmdir \"\$GIT_DIR\"/svn &&
git update-ref refs/heads/git-svn-HEAD refs/remotes/git-svn &&
git update-ref refs/heads/svn-HEAD refs/remotes/git-svn &&
git update-ref -d refs/remotes/git-svn refs/remotes/git-svn
@@ -28,20 +28,20 @@ head=`git rev-parse --verify refs/heads/git-svn-HEAD^0`
test_expect_success 'git-svn-HEAD is a real HEAD' "test -n '$head'"
test_expect_success 'initialize old-style (v0) git-svn layout' "
- mkdir -p $GIT_DIR/git-svn/info $GIT_DIR/svn/info &&
- echo $svnrepo > $GIT_DIR/git-svn/info/url &&
- echo $svnrepo > $GIT_DIR/svn/info/url &&
+ mkdir -p \"\$GIT_DIR\"/git-svn/info \"\$GIT_DIR\"/svn/info &&
+ echo \"\$svnrepo\" > \"\$GIT_DIR\"/git-svn/info/url &&
+ echo \"\$svnrepo\" > \"\$GIT_DIR\"/svn/info/url &&
git-svn migrate &&
- ! test -d $GIT_DIR/git-svn &&
+ ! test -d \"\$GIT_DIR\"/git-svn &&
git rev-parse --verify refs/remotes/git-svn^0 &&
git rev-parse --verify refs/remotes/svn^0 &&
- test \`git config --get svn-remote.svn.url\` = '$svnrepo' &&
+ test \"\$(git config --get svn-remote.svn.url)\" = \"\$svnrepo\" &&
test \`git config --get svn-remote.svn.fetch\` = \
':refs/remotes/git-svn'
"
test_expect_success 'initialize a multi-repository repo' "
- git-svn init $svnrepo -T trunk -t tags -b branches &&
+ git-svn init \"\$svnrepo\" -T trunk -t tags -b branches &&
git config --get-all svn-remote.svn.fetch > fetch.out &&
grep '^trunk:refs/remotes/trunk$' fetch.out &&
test -n \"\`git config --get svn-remote.svn.branches \
@@ -76,14 +76,14 @@ test_expect_success 'multi-fetch works on partial urls + paths' "
test_expect_success 'migrate --minimize on old inited layout' "
git config --unset-all svn-remote.svn.fetch &&
git config --unset-all svn-remote.svn.url &&
- rm -rf $GIT_DIR/svn &&
+ rm -rf \"\$GIT_DIR\"/svn &&
for i in \`cat fetch.out\`; do
path=\`expr \$i : '\\([^:]*\\):.*$'\`
ref=\`expr \$i : '[^:]*:refs/remotes/\\(.*\\)$'\`
if test -z \"\$ref\"; then continue; fi
if test -n \"\$path\"; then path=\"/\$path\"; fi
- ( mkdir -p $GIT_DIR/svn/\$ref/info/ &&
- echo $svnrepo\$path > $GIT_DIR/svn/\$ref/info/url ) || exit 1;
+ ( mkdir -p \"\$GIT_DIR\"/svn/\$ref/info/ &&
+ echo \"\$svnrepo\"\$path > \"\$GIT_DIR\"/svn/\$ref/info/url ) || exit 1;
done &&
git-svn migrate --minimize &&
test -z \"\`git config -l |grep -v '^svn-remote\.git-svn\.'\`\" &&
@@ -99,17 +99,17 @@ test_expect_success 'migrate --minimize on old inited layout' "
test_expect_success ".rev_db auto-converted to .rev_map.UUID" "
git-svn fetch -i trunk &&
- test -z \"\$(ls $GIT_DIR/svn/trunk/.rev_db.* 2>/dev/null)\" &&
- expect=\"\$(ls $GIT_DIR/svn/trunk/.rev_map.*)\" &&
+ test -z \"\$(ls \"\$GIT_DIR\"/svn/trunk/.rev_db.* 2>/dev/null)\" &&
+ expect=\"\$(ls \"\$GIT_DIR\"/svn/trunk/.rev_map.*)\" &&
test -n \"\$expect\" &&
- rev_db=\$(echo \$expect | sed -e 's,_map,_db,') &&
- convert_to_rev_db \$expect \$rev_db &&
- rm -f \$expect &&
- test -f \$rev_db &&
+ rev_db=\"\$(echo \$expect | sed -e 's,_map,_db,')\" &&
+ convert_to_rev_db \"\$expect\" \"\$rev_db\" &&
+ rm -f \"\$expect\" &&
+ test -f \"\$rev_db\" &&
git-svn fetch -i trunk &&
- test -z \"\$(ls $GIT_DIR/svn/trunk/.rev_db.* 2>/dev/null)\" &&
- test ! -e $GIT_DIR/svn/trunk/.rev_db &&
- test -f \$expect
+ test -z \"\$(ls \"\$GIT_DIR\"/svn/trunk/.rev_db.* 2>/dev/null)\" &&
+ test ! -e \"\$GIT_DIR\"/svn/trunk/.rev_db &&
+ test -f \"\$expect\"
"
test_done
diff --git a/t/t9108-git-svn-glob.sh b/t/t9108-git-svn-glob.sh
index db4344c..8f03f2d 100755
--- a/t/t9108-git-svn-glob.sh
+++ b/t/t9108-git-svn-glob.sh
@@ -14,8 +14,8 @@ test_expect_success 'test refspec globbing' "
mkdir -p trunk/src/a trunk/src/b trunk/doc &&
echo 'hello world' > trunk/src/a/readme &&
echo 'goodbye world' > trunk/src/b/readme &&
- svn import -m 'initial' trunk $svnrepo/trunk &&
- svn co $svnrepo tmp &&
+ svn import -m 'initial' trunk \"\$svnrepo\"/trunk &&
+ svn co \"\$svnrepo\" tmp &&
cd tmp &&
mkdir branches tags &&
svn add branches tags &&
@@ -38,7 +38,7 @@ test_expect_success 'test refspec globbing' "
poke tags/end/src/b/readme &&
svn commit -m 'nothing to see here'
cd .. &&
- git config --add svn-remote.svn.url $svnrepo &&
+ git config --add svn-remote.svn.url \"\$svnrepo\" &&
git config --add svn-remote.svn.fetch \
'trunk/src/a:refs/remotes/trunk' &&
git config --add svn-remote.svn.branches \
@@ -60,7 +60,7 @@ echo nothing to see here >> expect.two
cat expect.end >> expect.two
test_expect_success 'test left-hand-side only globbing' "
- git config --add svn-remote.two.url $svnrepo &&
+ git config --add svn-remote.two.url \"\$svnrepo\" &&
git config --add svn-remote.two.fetch trunk:refs/remotes/two/trunk &&
git config --add svn-remote.two.branches \
'branches/*:refs/remotes/two/branches/*' &&
diff --git a/t/t9110-git-svn-use-svm-props.sh b/t/t9110-git-svn-use-svm-props.sh
index 6235af4..d9ac558 100755
--- a/t/t9110-git-svn-use-svm-props.sh
+++ b/t/t9110-git-svn-use-svm-props.sh
@@ -8,11 +8,11 @@ test_description='git-svn useSvmProps test'
. ./lib-git-svn.sh
test_expect_success 'load svm repo' "
- svnadmin load -q $rawsvnrepo < ../t9110/svm.dump &&
- git-svn init --minimize-url -R arr -i bar $svnrepo/mirror/arr &&
- git-svn init --minimize-url -R argh -i dir $svnrepo/mirror/argh &&
+ svnadmin load -q \"\$rawsvnrepo\" < ../t9110/svm.dump &&
+ git-svn init --minimize-url -R arr -i bar \"\$svnrepo\"/mirror/arr &&
+ git-svn init --minimize-url -R argh -i dir \"\$svnrepo\"/mirror/argh &&
git-svn init --minimize-url -R argh -i e \
- $svnrepo/mirror/argh/a/b/c/d/e &&
+ \"\$svnrepo\"/mirror/argh/a/b/c/d/e &&
git config svn.useSvmProps true &&
git-svn fetch --all
"
diff --git a/t/t9111-git-svn-use-svnsync-props.sh b/t/t9111-git-svn-use-svnsync-props.sh
index ec7dedd..77185bc 100755
--- a/t/t9111-git-svn-use-svnsync-props.sh
+++ b/t/t9111-git-svn-use-svnsync-props.sh
@@ -8,10 +8,10 @@ test_description='git-svn useSvnsyncProps test'
. ./lib-git-svn.sh
test_expect_success 'load svnsync repo' "
- svnadmin load -q $rawsvnrepo < ../t9111/svnsync.dump &&
- git-svn init --minimize-url -R arr -i bar $svnrepo/bar &&
- git-svn init --minimize-url -R argh -i dir $svnrepo/dir &&
- git-svn init --minimize-url -R argh -i e $svnrepo/dir/a/b/c/d/e &&
+ svnadmin load -q \"\$rawsvnrepo\" < ../t9111/svnsync.dump &&
+ git-svn init --minimize-url -R arr -i bar \"\$svnrepo\"/bar &&
+ git-svn init --minimize-url -R argh -i dir \"\$svnrepo\"/dir &&
+ git-svn init --minimize-url -R argh -i e \"\$svnrepo\"/dir/a/b/c/d/e &&
git config svn.useSvnsyncProps true &&
git-svn fetch --all
"
diff --git a/t/t9112-git-svn-md5less-file.sh b/t/t9112-git-svn-md5less-file.sh
index 646a5f0..fb1491d 100755
--- a/t/t9112-git-svn-md5less-file.sh
+++ b/t/t9112-git-svn-md5less-file.sh
@@ -40,8 +40,8 @@ PROPS-END
EOF
-test_expect_success 'load svn dumpfile' "svnadmin load $rawsvnrepo < dumpfile.svn"
+test_expect_success 'load svn dumpfile' "svnadmin load \"\$rawsvnrepo\" < dumpfile.svn"
-test_expect_success 'initialize git-svn' "git-svn init $svnrepo"
+test_expect_success 'initialize git-svn' "git-svn init \"\$svnrepo\""
test_expect_success 'fetch revisions from svn' 'git-svn fetch'
test_done
diff --git a/t/t9113-git-svn-dcommit-new-file.sh b/t/t9113-git-svn-dcommit-new-file.sh
index 9ef0db9..b92a64e 100755
--- a/t/t9113-git-svn-dcommit-new-file.sh
+++ b/t/t9113-git-svn-dcommit-new-file.sh
@@ -15,14 +15,14 @@ test_description='git-svn dcommit new files over svn:// test'
start_svnserve () {
svnserve --listen-port $SVNSERVE_PORT \
- --root $rawsvnrepo \
+ --root "$rawsvnrepo" \
--listen-once \
--listen-host 127.0.0.1 &
}
test_expect_success 'start tracking an empty repo' "
- svn mkdir -m 'empty dir' $svnrepo/empty-dir &&
- echo anon-access = write >> $rawsvnrepo/conf/svnserve.conf &&
+ svn mkdir -m 'empty dir' \"\$svnrepo\"/empty-dir &&
+ echo anon-access = write >> \"\$rawsvnrepo\"/conf/svnserve.conf &&
start_svnserve &&
git svn init svn://127.0.0.1:$SVNSERVE_PORT &&
git svn fetch
diff --git a/t/t9114-git-svn-dcommit-merge.sh b/t/t9114-git-svn-dcommit-merge.sh
index 225060b..74b971c 100755
--- a/t/t9114-git-svn-dcommit-merge.sh
+++ b/t/t9114-git-svn-dcommit-merge.sh
@@ -35,7 +35,7 @@ EOF
}
test_expect_success 'setup svn repository' "
- svn co $svnrepo mysvnwork &&
+ svn co \"\$svnrepo\" mysvnwork &&
mkdir -p mysvnwork/trunk &&
cd mysvnwork &&
big_text_block >> trunk/README &&
@@ -45,7 +45,7 @@ test_expect_success 'setup svn repository' "
"
test_expect_success 'setup git mirror and merge' "
- git svn init $svnrepo -t tags -T trunk -b branches &&
+ git svn init \"\$svnrepo\" -t tags -T trunk -b branches &&
git svn fetch &&
git checkout --track -b svn remotes/trunk &&
git checkout -b merge &&
diff --git a/t/t9115-git-svn-dcommit-funky-renames.sh b/t/t9115-git-svn-dcommit-funky-renames.sh
index 182299c..f83f4f9 100755
--- a/t/t9115-git-svn-dcommit-funky-renames.sh
+++ b/t/t9115-git-svn-dcommit-funky-renames.sh
@@ -8,12 +8,12 @@ test_description='git-svn dcommit can commit renames of files with ugly names'
. ./lib-git-svn.sh
test_expect_success 'load repository with strange names' "
- svnadmin load -q $rawsvnrepo < ../t9115/funky-names.dump &&
+ svnadmin load -q \"\$rawsvnrepo\" < ../t9115/funky-names.dump &&
start_httpd
"
test_expect_success 'init and fetch repository' "
- git svn init $svnrepo &&
+ git svn init \"\$svnrepo\" &&
git svn fetch &&
git reset --hard git-svn
"
diff --git a/t/t9116-git-svn-log.sh b/t/t9116-git-svn-log.sh
index e1e8bdf..13081b8 100755
--- a/t/t9116-git-svn-log.sh
+++ b/t/t9116-git-svn-log.sh
@@ -14,9 +14,9 @@ test_expect_success 'setup repository and import' "
mkdir -p \$i && \
echo hello >> \$i/README || exit 1
done && \
- svn import -m test . $svnrepo
+ svn import -m test . \"\$svnrepo\"
cd .. &&
- git-svn init $svnrepo -T trunk -b branches -t tags &&
+ git-svn init \"\$svnrepo\" -T trunk -b branches -t tags &&
git-svn fetch &&
git reset --hard trunk &&
echo bye >> README &&
diff --git a/t/t9117-git-svn-init-clone.sh b/t/t9117-git-svn-init-clone.sh
index d482b40..c924915 100755
--- a/t/t9117-git-svn-init-clone.sh
+++ b/t/t9117-git-svn-init-clone.sh
@@ -16,13 +16,13 @@ cd tmp
test_expect_success 'setup svnrepo' "
mkdir project project/trunk project/branches project/tags &&
echo foo > project/trunk/foo &&
- svn import -m '$test_description' project $svnrepo/project &&
+ svn import -m '$test_description' project \"\$svnrepo\"/project &&
rm -rf project
"
test_expect_success 'basic clone' "
test ! -d trunk &&
- git svn clone $svnrepo/project/trunk &&
+ git svn clone \"\$svnrepo\"/project/trunk &&
test -d trunk/.git/svn &&
test -e trunk/foo &&
rm -rf trunk
@@ -30,7 +30,7 @@ test_expect_success 'basic clone' "
test_expect_success 'clone to target directory' "
test ! -d target &&
- git svn clone $svnrepo/project/trunk target &&
+ git svn clone \"\$svnrepo\"/project/trunk target &&
test -d target/.git/svn &&
test -e target/foo &&
rm -rf target
@@ -38,7 +38,7 @@ test_expect_success 'clone to target directory' "
test_expect_success 'clone with --stdlayout' "
test ! -d project &&
- git svn clone -s $svnrepo/project &&
+ git svn clone -s \"\$svnrepo\"/project &&
test -d project/.git/svn &&
test -e project/foo &&
rm -rf project
@@ -46,7 +46,7 @@ test_expect_success 'clone with --stdlayout' "
test_expect_success 'clone to target directory with --stdlayout' "
test ! -d target &&
- git svn clone -s $svnrepo/project target &&
+ git svn clone -s \"\$svnrepo\"/project target &&
test -d target/.git/svn &&
test -e target/foo &&
rm -rf target
diff --git a/t/t9118-git-svn-funky-branch-names.sh b/t/t9118-git-svn-funky-branch-names.sh
index 640bb06..0f107fc 100755
--- a/t/t9118-git-svn-funky-branch-names.sh
+++ b/t/t9118-git-svn-funky-branch-names.sh
@@ -9,17 +9,17 @@ test_description='git-svn funky branch names'
test_expect_success 'setup svnrepo' "
mkdir project project/trunk project/branches project/tags &&
echo foo > project/trunk/foo &&
- svn import -m '$test_description' project \"$svnrepo/pr ject\" &&
+ svn import -m '\$test_description' project \"\$svnrepo/pr ject\" &&
rm -rf project &&
- svn cp -m 'fun' \"$svnrepo/pr ject/trunk\" \
- \"$svnrepo/pr ject/branches/fun plugin\" &&
- svn cp -m 'more fun!' \"$svnrepo/pr ject/branches/fun plugin\" \
- \"$svnrepo/pr ject/branches/more fun plugin!\" &&
+ svn cp -m 'fun' \"\$svnrepo/pr ject/trunk\" \
+ \"\$svnrepo/pr ject/branches/fun plugin\" &&
+ svn cp -m 'more fun!' \"\$svnrepo/pr ject/branches/fun plugin\" \
+ \"\$svnrepo/pr ject/branches/more fun plugin!\" &&
start_httpd
"
test_expect_success 'test clone with funky branch names' "
- git svn clone -s \"$svnrepo/pr ject\" project &&
+ git svn clone -s \"\$svnrepo/pr ject\" project &&
cd project &&
git rev-parse 'refs/remotes/fun%20plugin' &&
git rev-parse 'refs/remotes/more%20fun%20plugin!' &&
diff --git a/t/t9120-git-svn-clone-with-percent-escapes.sh b/t/t9120-git-svn-clone-with-percent-escapes.sh
index 9a4eabe..1414c0f 100755
--- a/t/t9120-git-svn-clone-with-percent-escapes.sh
+++ b/t/t9120-git-svn-clone-with-percent-escapes.sh
@@ -9,7 +9,7 @@ test_description='git-svn clone with percent escapes'
test_expect_success 'setup svnrepo' "
mkdir project project/trunk project/branches project/tags &&
echo foo > project/trunk/foo &&
- svn import -m '$test_description' project '$svnrepo/pr ject' &&
+ svn import -m \"\$test_description\" project \"\$svnrepo/pr ject\" &&
rm -rf project &&
start_httpd
"
diff --git a/t/t9500-gitweb-standalone-no-errors.sh b/t/t9500-gitweb-standalone-no-errors.sh
index e7b911e..405bad5 100755
--- a/t/t9500-gitweb-standalone-no-errors.sh
+++ b/t/t9500-gitweb-standalone-no-errors.sh
@@ -10,6 +10,7 @@ commandline, and checks that it would not write any errors
or warnings to log.'
gitweb_init () {
+ safe_pwd="$(perl -MPOSIX=getcwd -e 'print quotemeta(getcwd)')"
cat >gitweb_config.perl <<EOF
#!/usr/bin/perl
@@ -17,16 +18,16 @@ gitweb_init () {
our \$version = "current";
our \$GIT = "git";
-our \$projectroot = "$(pwd)";
+our \$projectroot = "$safe_pwd";
our \$project_maxdepth = 8;
our \$home_link_str = "projects";
our \$site_name = "[localhost]";
our \$site_header = "";
our \$site_footer = "";
our \$home_text = "indextext.html";
-our @stylesheets = ("file:///$(pwd)/../../gitweb/gitweb.css");
-our \$logo = "file:///$(pwd)/../../gitweb/git-logo.png";
-our \$favicon = "file:///$(pwd)/../../gitweb/git-favicon.png";
+our @stylesheets = ("file:///$safe_pwd/../../gitweb/gitweb.css");
+our \$logo = "file:///$safe_pwd/../../gitweb/git-logo.png";
+our \$favicon = "file:///$safe_pwd/../../gitweb/git-favicon.png";
our \$projects_list = "";
our \$export_ok = "";
our \$strict_export = "";
@@ -53,7 +54,7 @@ gitweb_run () {
# written to web server logs, so we are not interested in that:
# we are interested only in properly formatted errors/warnings
rm -f gitweb.log &&
- perl -- $(pwd)/../../gitweb/gitweb.perl \
+ perl -- "$(pwd)/../../gitweb/gitweb.perl" \
>/dev/null 2>gitweb.log &&
if grep -q -s "^[[]" gitweb.log >/dev/null; then false; else true; fi
--
1.5.5.33.gc0a39.dirty
^ permalink raw reply related [relevance 10%]
* [PATCH] Have tests and programs understand paths containing spaces
@ 2008-04-22 21:28 9% Arjen Laarhoven
0 siblings, 0 replies; 200+ results
From: Arjen Laarhoven @ 2008-04-22 21:28 UTC (permalink / raw)
To: Git Mailing List; +Cc: Junio C Hamano
A lot of tests and some core programs didn't work when used in a path
containing whitespace. Correct the quoting of all affected programs to
fix this.
Signed-off-by: Arjen Laarhoven <arjen@yaph.org>
---
builtin-tag.c | 2 +-
git-rebase.sh | 2 +-
git-send-email.perl | 2 +-
git-sh-setup.sh | 2 +-
t/lib-git-svn.sh | 8 ++--
t/t0000-basic.sh | 2 +-
t/t1020-subdirectory.sh | 22 ++++++------
t/t3050-subprojects-fetch.sh | 2 +-
t/t3404-rebase-interactive.sh | 2 +-
t/t5500-fetch-pack.sh | 2 +-
t/t5512-ls-remote.sh | 2 +-
t/t5516-fetch-push.sh | 10 +++---
t/t5700-clone-reference.sh | 4 +-
t/t7003-filter-branch.sh | 4 +-
t/t7005-editor.sh | 4 +-
t/t7010-setup.sh | 2 +-
t/t7300-clean.sh | 2 +-
t/t7501-commit.sh | 8 ++--
t/t9001-send-email.sh | 4 +-
t/t9100-git-svn-basic.sh | 26 +++++++-------
t/t9101-git-svn-props.sh | 6 ++--
t/t9102-git-svn-deep-rmdir.sh | 6 ++--
t/t9103-git-svn-tracked-directory-removed.sh | 10 +++---
t/t9104-git-svn-follow-parent.sh | 50 +++++++++++++-------------
t/t9105-git-svn-commit-diff.sh | 10 +++---
t/t9106-git-svn-commit-diff-clobber.sh | 14 ++++----
t/t9106-git-svn-dcommit-clobber-series.sh | 6 ++--
t/t9107-git-svn-migrate.sh | 48 ++++++++++++------------
t/t9108-git-svn-glob.sh | 8 ++--
t/t9110-git-svn-use-svm-props.sh | 8 ++--
t/t9111-git-svn-use-svnsync-props.sh | 8 ++--
t/t9112-git-svn-md5less-file.sh | 4 +-
t/t9113-git-svn-dcommit-new-file.sh | 6 ++--
t/t9114-git-svn-dcommit-merge.sh | 4 +-
t/t9115-git-svn-dcommit-funky-renames.sh | 4 +-
t/t9116-git-svn-log.sh | 4 +-
t/t9117-git-svn-init-clone.sh | 10 +++---
t/t9121-git-svn-fetch-renamed-dir.sh | 4 +-
t/t9400-git-cvsserver-server.sh | 20 +++++-----
t/t9500-gitweb-standalone-no-errors.sh | 4 +-
t/t9600-cvsimport.sh | 6 ++--
t/test-lib.sh | 10 +++---
42 files changed, 181 insertions(+), 181 deletions(-)
diff --git a/builtin-tag.c b/builtin-tag.c
index 129ff57..2d04d4f 100644
--- a/builtin-tag.c
+++ b/builtin-tag.c
@@ -55,7 +55,7 @@ void launch_editor(const char *path, struct strbuf *buffer, const char *const *e
strbuf_init(&arg0, 0);
if (strcspn(editor, "$ \t'") != len) {
/* there are specials */
- strbuf_addf(&arg0, "%s \"$@\"", editor);
+ strbuf_addf(&arg0, "'%s' \"$@\"", editor);
args[i++] = "sh";
args[i++] = "-c";
args[i++] = arg0.buf;
diff --git a/git-rebase.sh b/git-rebase.sh
index 9b13b83..c43afe5 100755
--- a/git-rebase.sh
+++ b/git-rebase.sh
@@ -214,7 +214,7 @@ do
else
die "No rebase in progress?"
fi
- git reset --hard $(cat $dotest/orig-head)
+ git reset --hard $(cat "$dotest/orig-head")
rm -r "$dotest"
exit
;;
diff --git a/git-send-email.perl b/git-send-email.perl
index 9e568bf..40a521a 100755
--- a/git-send-email.perl
+++ b/git-send-email.perl
@@ -512,7 +512,7 @@ EOT
close(C);
my $editor = $ENV{GIT_EDITOR} || Git::config(@repo, "core.editor") || $ENV{VISUAL} || $ENV{EDITOR} || "vi";
- system('sh', '-c', '$0 $@', $editor, $compose_filename);
+ system('sh', '-c', '"$0" $@', $editor, $compose_filename);
open(C2,">",$compose_filename . ".final")
or die "Failed to open $compose_filename.final : " . $!;
diff --git a/git-sh-setup.sh b/git-sh-setup.sh
index a44b1c7..a8a024b 100755
--- a/git-sh-setup.sh
+++ b/git-sh-setup.sh
@@ -73,7 +73,7 @@ git_editor() {
exit 1
;;
esac
- eval "${GIT_EDITOR:=vi}" '"$@"'
+ eval '"${GIT_EDITOR:=vi}"' '"$@"'
}
is_bare_repository () {
diff --git a/t/lib-git-svn.sh b/t/lib-git-svn.sh
index 9decd2e..f6645f9 100644
--- a/t/lib-git-svn.sh
+++ b/t/lib-git-svn.sh
@@ -7,9 +7,9 @@ then
exit
fi
-GIT_DIR=$PWD/.git
-GIT_SVN_DIR=$GIT_DIR/svn/git-svn
-SVN_TREE=$GIT_SVN_DIR/svn-tree
+GIT_DIR="$PWD/.git"
+GIT_SVN_DIR="$GIT_DIR/svn/git-svn"
+SVN_TREE="$GIT_SVN_DIR/svn-tree"
svn >/dev/null 2>&1
if test $? -ne 1
@@ -19,7 +19,7 @@ then
exit
fi
-svnrepo=$PWD/svnrepo
+svnrepo="$PWD/svnrepo"
perl -w -e "
use SVN::Core;
diff --git a/t/t0000-basic.sh b/t/t0000-basic.sh
index 27b54cb..e6fa7de 100755
--- a/t/t0000-basic.sh
+++ b/t/t0000-basic.sh
@@ -305,7 +305,7 @@ test_expect_success 'absolute path works as expected' '
file="$dir"/index &&
test "$file" = "$(test-absolute-path $dir2/index)" &&
basename=blub &&
- test "$dir/$basename" = $(cd .git && test-absolute-path $basename) &&
+ test "$dir/$basename" = "$(cd .git && test-absolute-path $basename)" &&
ln -s ../first/file .git/syml &&
sym="$(cd first; pwd -P)"/file &&
test "$sym" = "$(test-absolute-path $dir2/syml)"
diff --git a/t/t1020-subdirectory.sh b/t/t1020-subdirectory.sh
index b9cef34..5ed7fa4 100755
--- a/t/t1020-subdirectory.sh
+++ b/t/t1020-subdirectory.sh
@@ -21,7 +21,7 @@ LF='
'
test_expect_success 'update-index and ls-files' '
- cd $HERE &&
+ cd "$HERE" &&
git update-index --add one &&
case "`git ls-files`" in
one) echo ok one ;;
@@ -41,7 +41,7 @@ test_expect_success 'update-index and ls-files' '
'
test_expect_success 'cat-file' '
- cd $HERE &&
+ cd "$HERE" &&
two=`git ls-files -s dir/two` &&
two=`expr "$two" : "[0-7]* \\([0-9a-f]*\\)"` &&
echo "$two" &&
@@ -54,7 +54,7 @@ test_expect_success 'cat-file' '
rm -f actual dir/actual
test_expect_success 'diff-files' '
- cd $HERE &&
+ cd "$HERE" &&
echo a >>one &&
echo d >>dir/two &&
case "`git diff-files --name-only`" in
@@ -74,7 +74,7 @@ test_expect_success 'diff-files' '
'
test_expect_success 'write-tree' '
- cd $HERE &&
+ cd "$HERE" &&
top=`git write-tree` &&
echo $top &&
cd dir &&
@@ -84,7 +84,7 @@ test_expect_success 'write-tree' '
'
test_expect_success 'checkout-index' '
- cd $HERE &&
+ cd "$HERE" &&
git checkout-index -f -u one &&
cmp one original.one &&
cd dir &&
@@ -93,7 +93,7 @@ test_expect_success 'checkout-index' '
'
test_expect_success 'read-tree' '
- cd $HERE &&
+ cd "$HERE" &&
rm -f one dir/two &&
tree=`git write-tree` &&
git read-tree --reset -u "$tree" &&
@@ -107,27 +107,27 @@ test_expect_success 'read-tree' '
'
test_expect_success 'no file/rev ambiguity check inside .git' '
- cd $HERE &&
+ cd "$HERE" &&
git commit -a -m 1 &&
- cd $HERE/.git &&
+ cd "$HERE/.git" &&
git show -s HEAD
'
test_expect_success 'no file/rev ambiguity check inside a bare repo' '
- cd $HERE &&
+ cd "$HERE" &&
git clone -s --bare .git foo.git &&
cd foo.git && GIT_DIR=. git show -s HEAD
'
# This still does not work as it should...
: test_expect_success 'no file/rev ambiguity check inside a bare repo' '
- cd $HERE &&
+ cd "$HERE" &&
git clone -s --bare .git foo.git &&
cd foo.git && git show -s HEAD
'
test_expect_success 'detection should not be fooled by a symlink' '
- cd $HERE &&
+ cd "$HERE" &&
rm -fr foo.git &&
git clone -s .git another &&
ln -s another yetanother &&
diff --git a/t/t3050-subprojects-fetch.sh b/t/t3050-subprojects-fetch.sh
index 2b21b10..4261e96 100755
--- a/t/t3050-subprojects-fetch.sh
+++ b/t/t3050-subprojects-fetch.sh
@@ -20,7 +20,7 @@ test_expect_success setup '
'
test_expect_success clone '
- git clone file://`pwd`/.git cloned &&
+ git clone "file://$(pwd)/.git" cloned &&
(git rev-parse HEAD; git ls-files -s) >expected &&
(
cd cloned &&
diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh
index 9cf873f..e619a29 100755
--- a/t/t3404-rebase-interactive.sh
+++ b/t/t3404-rebase-interactive.sh
@@ -174,7 +174,7 @@ test_expect_success 'squash' '
test_tick &&
GIT_AUTHOR_NAME="Nitfol" git commit -m "nitfol" file7 &&
echo "******************************" &&
- FAKE_LINES="1 squash 2" git rebase -i --onto master HEAD~2 &&
+ FAKE_LINES="1 squash 2" git rebase -v -i --onto master HEAD~2 &&
test B = $(cat file7) &&
test $(git rev-parse HEAD^) = $(git rev-parse master)
'
diff --git a/t/t5500-fetch-pack.sh b/t/t5500-fetch-pack.sh
index 788b4a5..c52707b 100755
--- a/t/t5500-fetch-pack.sh
+++ b/t/t5500-fetch-pack.sh
@@ -129,7 +129,7 @@ pull_to_client 2nd "B" $((64*3))
pull_to_client 3rd "A" $((1*3)) # old fails
-test_expect_success "clone shallow" "git-clone --depth 2 file://`pwd`/. shallow"
+test_expect_success "clone shallow" 'git-clone --depth 2 "file://$(pwd)/." shallow'
(cd shallow; git count-objects -v) > count.shallow
diff --git a/t/t5512-ls-remote.sh b/t/t5512-ls-remote.sh
index c0dc949..e3df3ed 100755
--- a/t/t5512-ls-remote.sh
+++ b/t/t5512-ls-remote.sh
@@ -17,7 +17,7 @@ test_expect_success setup '
git show-ref -d | sed -e "s/ / /"
) >expected.all &&
- git remote add self $(pwd)/.git
+ git remote add self "$(pwd)"/.git
'
diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh
index 6d7e738..a86042e 100755
--- a/t/t5516-fetch-push.sh
+++ b/t/t5516-fetch-push.sh
@@ -4,7 +4,7 @@ test_description='fetching and pushing, with or without wildcard'
. ./test-lib.sh
-D=`pwd`
+D=$(pwd)
mk_empty () {
rm -fr testrepo &&
@@ -103,9 +103,9 @@ test_expect_success 'fetch with wildcard' '
test_expect_success 'fetch with insteadOf' '
mk_empty &&
(
- TRASH=$(pwd)/ &&
+ TRASH="$(pwd)"/ &&
cd testrepo &&
- git config url.$TRASH.insteadOf trash/
+ git config url."$TRASH".insteadOf trash/
git config remote.up.url trash/. &&
git config remote.up.fetch "refs/heads/*:refs/remotes/origin/*" &&
git fetch up &&
@@ -145,8 +145,8 @@ test_expect_success 'push with wildcard' '
test_expect_success 'push with insteadOf' '
mk_empty &&
- TRASH=$(pwd)/ &&
- git config url.$TRASH.insteadOf trash/ &&
+ TRASH="$(pwd)"/ &&
+ git config url."$TRASH".insteadOf trash/ &&
git push trash/testrepo refs/heads/master:refs/remotes/origin/master &&
(
cd testrepo &&
diff --git a/t/t5700-clone-reference.sh b/t/t5700-clone-reference.sh
index b6a5486..b6905c1 100755
--- a/t/t5700-clone-reference.sh
+++ b/t/t5700-clone-reference.sh
@@ -6,7 +6,7 @@
test_description='test clone --reference'
. ./test-lib.sh
-base_dir=`pwd`
+base_dir="$(pwd)"
test_expect_success 'preparing first repository' \
'test_create_repo A && cd A &&
@@ -51,7 +51,7 @@ diff expected current'
cd "$base_dir"
test_expect_success 'cloning with reference (no -l -s)' \
-'git clone --reference B file://`pwd`/A D'
+'git clone --reference B file://"$(pwd)"/A D'
cd "$base_dir"
diff --git a/t/t7003-filter-branch.sh b/t/t7003-filter-branch.sh
index efd658a..5863cc2 100755
--- a/t/t7003-filter-branch.sh
+++ b/t/t7003-filter-branch.sh
@@ -123,9 +123,9 @@ test_expect_success 'use index-filter to move into a subdirectory' '
git branch directorymoved &&
git-filter-branch -f --index-filter \
"git ls-files -s | sed \"s-\\t-&newsubdir/-\" |
- GIT_INDEX_FILE=\$GIT_INDEX_FILE.new \
+ GIT_INDEX_FILE=\"\$GIT_INDEX_FILE\".new \
git update-index --index-info &&
- mv \$GIT_INDEX_FILE.new \$GIT_INDEX_FILE" directorymoved &&
+ mv \"\$GIT_INDEX_FILE\".new \"\$GIT_INDEX_FILE\"" directorymoved &&
test -z "$(git diff HEAD directorymoved:newsubdir)"'
test_expect_success 'stops when msg filter fails' '
diff --git a/t/t7005-editor.sh b/t/t7005-editor.sh
index 2d919d6..2bf6a55 100755
--- a/t/t7005-editor.sh
+++ b/t/t7005-editor.sh
@@ -92,7 +92,7 @@ test_expect_success 'editor with a space' '
if echo "echo space > \"\$1\"" > "e space.sh"
then
chmod a+x "e space.sh" &&
- GIT_EDITOR="./e\ space.sh" git commit --amend &&
+ GIT_EDITOR="./e space.sh" git commit --amend &&
test space = "$(git show -s --pretty=format:%s)"
else
say "Skipping; FS does not support spaces in filenames"
@@ -105,7 +105,7 @@ test_expect_success 'core.editor with a space' '
if test -f "e space.sh"
then
- git config core.editor \"./e\ space.sh\" &&
+ git config core.editor "./e space.sh" &&
git commit --amend &&
test space = "$(git show -s --pretty=format:%s)"
else
diff --git a/t/t7010-setup.sh b/t/t7010-setup.sh
index 02cf7c5..d8a7c79 100755
--- a/t/t7010-setup.sh
+++ b/t/t7010-setup.sh
@@ -122,7 +122,7 @@ test_expect_success 'commit using absolute path names' '
test_expect_success 'log using absolute path names' '
echo bb >>a/b/c/d &&
- git commit -m "bb" $(pwd)/a/b/c/d &&
+ git commit -m "bb" "$(pwd)/a/b/c/d" &&
git log a/b/c/d >f1.txt &&
git log "$(pwd)/a/b/c/d" >f2.txt &&
diff --git a/t/t7300-clean.sh b/t/t7300-clean.sh
index a50492f..4c9701f 100755
--- a/t/t7300-clean.sh
+++ b/t/t7300-clean.sh
@@ -112,7 +112,7 @@ test_expect_success 'git-clean with absolute path' '
touch a.out src/part3.c docs/manual.txt obj.o build/lib.so &&
would_clean=$(
cd docs &&
- git clean -n $(pwd)/../src |
+ git clean -n "$(pwd)"/../src |
sed -n -e "s|^Would remove ||p"
) &&
test "$would_clean" = ../src/part3.c || {
diff --git a/t/t7501-commit.sh b/t/t7501-commit.sh
index c0288f3..4e5418a 100755
--- a/t/t7501-commit.sh
+++ b/t/t7501-commit.sh
@@ -79,8 +79,8 @@ test_expect_success \
cat >editor <<\EOF
#!/bin/sh
-sed -e "s/a file/an amend commit/g" < $1 > $1-
-mv $1- $1
+sed -e "s/a file/an amend commit/g" < "$1" > "$1"-
+mv "$1"- "$1"
EOF
chmod 755 editor
@@ -99,8 +99,8 @@ test_expect_success \
cat >editor <<\EOF
#!/bin/sh
-sed -e "s/amend/older/g" < $1 > $1-
-mv $1- $1
+sed -e "s/amend/older/g" < "$1" > "$1"-
+mv "$1"- "$1"
EOF
chmod 755 editor
diff --git a/t/t9001-send-email.sh b/t/t9001-send-email.sh
index c0973b4..5047708 100755
--- a/t/t9001-send-email.sh
+++ b/t/t9001-send-email.sh
@@ -32,7 +32,7 @@ clean_fake_sendmail() {
}
test_expect_success 'Extract patches' '
- patches=`git format-patch -n HEAD^1`
+ patches=$(git format-patch -n HEAD^1)
'
test_expect_success 'Send patches' '
@@ -147,7 +147,7 @@ test_expect_success 'setup fake editor' '
test_expect_success '--compose works' '
clean_fake_sendmail &&
echo y | \
- GIT_EDITOR=$(pwd)/fake-editor \
+ GIT_EDITOR="$(pwd)/fake-editor" \
GIT_SEND_EMAIL_NOTTY=1 \
git send-email \
--compose --subject foo \
diff --git a/t/t9100-git-svn-basic.sh b/t/t9100-git-svn-basic.sh
index 4e24ab3..8f93821 100755
--- a/t/t9100-git-svn-basic.sh
+++ b/t/t9100-git-svn-basic.sh
@@ -20,27 +20,27 @@ esac
echo 'define NO_SVN_TESTS to skip git-svn tests'
test_expect_success \
- 'initialize git-svn' "
+ 'initialize git-svn' '
mkdir import &&
cd import &&
echo foo > foo &&
ln -s foo foo.link
mkdir -p dir/a/b/c/d/e &&
- echo 'deep dir' > dir/a/b/c/d/e/file &&
+ echo "deep dir" > dir/a/b/c/d/e/file &&
mkdir bar &&
- echo 'zzz' > bar/zzz &&
- echo '#!/bin/sh' > exec.sh &&
+ echo "zzz" > bar/zzz &&
+ echo "#!/bin/sh" > exec.sh &&
chmod +x exec.sh &&
- svn import -m 'import for git-svn' . $svnrepo >/dev/null &&
+ svn import -m "import for git-svn" . "$svnrepo" >/dev/null &&
cd .. &&
rm -rf import &&
- git-svn init $svnrepo"
+ git-svn init "$svnrepo"'
test_expect_success \
'import an SVN revision into git' \
'git-svn fetch'
-test_expect_success "checkout from svn" "svn co $svnrepo '$SVN_TREE'"
+test_expect_success "checkout from svn" "svn co '$svnrepo' '$SVN_TREE'"
name='try a deep --rmdir with a commit'
test_expect_success "$name" "
@@ -169,7 +169,7 @@ test_expect_success "$name" "
svn up '$SVN_TREE' &&
test -f '$SVN_TREE'/exec-2.sh &&
test ! -L '$SVN_TREE'/exec-2.sh &&
- git diff help $SVN_TREE/exec-2.sh"
+ git diff help '$SVN_TREE'/exec-2.sh"
if test "$have_utf8" = t
then
@@ -190,7 +190,7 @@ name='test fetch functionality (svn => git) with alternate GIT_SVN_ID'
GIT_SVN_ID=alt
export GIT_SVN_ID
test_expect_success "$name" \
- "git-svn init $svnrepo && git-svn fetch &&
+ "git-svn init '$svnrepo' && git-svn fetch &&
git rev-list --pretty=raw remotes/git-svn | grep ^tree | uniq > a &&
git rev-list --pretty=raw remotes/alt | grep ^tree | uniq > b &&
git diff a b"
@@ -220,16 +220,16 @@ test_expect_success 'exit if remote refs are ambigious' "
"
test_expect_success 'exit if init-ing a would clobber a URL' "
- svnadmin create ${PWD}/svnrepo2 &&
- svn mkdir -m 'mkdir bar' ${svnrepo}2/bar &&
+ svnadmin create '${PWD}/svnrepo2' &&
+ svn mkdir -m 'mkdir bar' '${svnrepo}2/bar' &&
git config --unset svn-remote.svn.fetch \
'^bar:refs/remotes/git-svn$' &&
- ! git-svn init ${svnrepo}2/bar
+ ! git-svn init '${svnrepo}2/bar'
"
test_expect_success \
'init allows us to connect to another directory in the same repo' "
- git-svn init --minimize-url -i bar $svnrepo/bar &&
+ git-svn init --minimize-url -i bar '$svnrepo/bar' &&
git config --get svn-remote.svn.fetch \
'^bar:refs/remotes/bar$' &&
git config --get svn-remote.svn.fetch \
diff --git a/t/t9101-git-svn-props.sh b/t/t9101-git-svn-props.sh
index d7a7047..2616df6 100755
--- a/t/t9101-git-svn-props.sh
+++ b/t/t9101-git-svn-props.sh
@@ -52,7 +52,7 @@ EOF
cd ..
rm -rf import
-test_expect_success 'checkout working copy from svn' "svn co $svnrepo test_wc"
+test_expect_success 'checkout working copy from svn' "svn co '$svnrepo' test_wc"
test_expect_success 'setup some commits to svn' \
'cd test_wc &&
echo Greetings >> kw.c &&
@@ -66,7 +66,7 @@ test_expect_success 'setup some commits to svn' \
svn commit -m "Propset Id" &&
cd ..'
-test_expect_success 'initialize git-svn' "git-svn init $svnrepo"
+test_expect_success 'initialize git-svn' "git-svn init '$svnrepo'"
test_expect_success 'fetch revisions from svn' 'git-svn fetch'
name='test svn:keywords ignoring'
@@ -92,7 +92,7 @@ test_expect_success "propset CR on crlf files" \
test_expect_success 'fetch and pull latest from svn and checkout a new wc' \
"git-svn fetch &&
git pull . remotes/git-svn &&
- svn co $svnrepo new_wc"
+ svn co '$svnrepo' new_wc"
for i in crlf ne_crlf lf ne_lf cr ne_cr empty_cr empty_lf empty empty_crlf
do
diff --git a/t/t9102-git-svn-deep-rmdir.sh b/t/t9102-git-svn-deep-rmdir.sh
index 4e08083..99c8840 100755
--- a/t/t9102-git-svn-deep-rmdir.sh
+++ b/t/t9102-git-svn-deep-rmdir.sh
@@ -9,12 +9,12 @@ test_expect_success 'initialize repo' "
mkdir -p deeply/nested/directory/number/2 &&
echo foo > deeply/nested/directory/number/1/file &&
echo foo > deeply/nested/directory/number/2/another &&
- svn import -m 'import for git-svn' . $svnrepo &&
+ svn import -m 'import for git-svn' . '$svnrepo' &&
cd ..
"
test_expect_success 'mirror via git-svn' "
- git-svn init $svnrepo &&
+ git-svn init '$svnrepo' &&
git-svn fetch &&
git checkout -f -b test-rmdir remotes/git-svn
"
@@ -23,7 +23,7 @@ test_expect_success 'Try a commit on rmdir' "
git rm -f deeply/nested/directory/number/2/another &&
git commit -a -m 'remove another' &&
git-svn set-tree --rmdir HEAD &&
- svn ls -R $svnrepo | grep ^deeply/nested/directory/number/1
+ svn ls -R '$svnrepo' | grep ^deeply/nested/directory/number/1
"
diff --git a/t/t9103-git-svn-tracked-directory-removed.sh b/t/t9103-git-svn-tracked-directory-removed.sh
index 0f0b0fd..a85050a 100755
--- a/t/t9103-git-svn-tracked-directory-removed.sh
+++ b/t/t9103-git-svn-tracked-directory-removed.sh
@@ -10,19 +10,19 @@ test_expect_success 'make history for tracking' '
mkdir import &&
mkdir import/trunk &&
echo hello >> import/trunk/README &&
- svn import -m initial import $svnrepo &&
+ svn import -m initial import "$svnrepo" &&
rm -rf import &&
- svn co $svnrepo/trunk trunk &&
+ svn co "$svnrepo/trunk" trunk &&
echo bye bye >> trunk/README &&
- svn rm -m "gone" $svnrepo/trunk &&
+ svn rm -m "gone" "$svnrepo/trunk" &&
rm -rf trunk &&
mkdir trunk &&
echo "new" > trunk/FOLLOWME &&
- svn import -m "new trunk" trunk $svnrepo/trunk
+ svn import -m "new trunk" trunk "$svnrepo/trunk"
'
test_expect_success 'clone repo with git' '
- git svn clone -s $svnrepo x &&
+ git svn clone -s "$svnrepo" x &&
test -f x/FOLLOWME &&
test ! -f x/README
'
diff --git a/t/t9104-git-svn-follow-parent.sh b/t/t9104-git-svn-follow-parent.sh
index 7ba7630..499d9e6 100755
--- a/t/t9104-git-svn-follow-parent.sh
+++ b/t/t9104-git-svn-follow-parent.sh
@@ -11,9 +11,9 @@ test_expect_success 'initialize repo' "
cd import &&
mkdir -p trunk &&
echo hello > trunk/readme &&
- svn import -m 'initial' . $svnrepo &&
+ svn import -m 'initial' . '$svnrepo' &&
cd .. &&
- svn co $svnrepo wc &&
+ svn co '$svnrepo' wc &&
cd wc &&
echo world >> trunk/readme &&
poke trunk/readme &&
@@ -27,7 +27,7 @@ test_expect_success 'initialize repo' "
"
test_expect_success 'init and fetch a moved directory' "
- git-svn init --minimize-url -i thunk $svnrepo/thunk &&
+ git-svn init --minimize-url -i thunk '$svnrepo/thunk' &&
git-svn fetch -i thunk &&
test \"\`git rev-parse --verify refs/remotes/thunk@2\`\" \
= \"\`git rev-parse --verify refs/remotes/thunk~1\`\" &&
@@ -38,7 +38,7 @@ test_expect_success 'init and fetch a moved directory' "
"
test_expect_success 'init and fetch from one svn-remote' "
- git config svn-remote.svn.url $svnrepo &&
+ git config svn-remote.svn.url '$svnrepo' &&
git config --add svn-remote.svn.fetch \
trunk:refs/remotes/svn/trunk &&
git config --add svn-remote.svn.fetch \
@@ -52,9 +52,9 @@ test_expect_success 'init and fetch from one svn-remote' "
test_expect_success 'follow deleted parent' "
(svn cp -m 'resurrecting trunk as junk' \
- $svnrepo/trunk@2 $svnrepo/junk ||
+ '$svnrepo/trunk@2' '$svnrepo/junk' ||
svn cp -m 'resurrecting trunk as junk' \
- -r2 $svnrepo/trunk $svnrepo/junk) &&
+ -r2 '$svnrepo/trunk' '$svnrepo/junk') &&
git config --add svn-remote.svn.fetch \
junk:refs/remotes/svn/junk &&
git-svn fetch -i svn/thunk &&
@@ -67,10 +67,10 @@ test_expect_success 'follow deleted parent' "
test_expect_success 'follow larger parent' "
mkdir -p import/trunk/thunk/bump/thud &&
echo hi > import/trunk/thunk/bump/thud/file &&
- svn import -m 'import a larger parent' import $svnrepo/larger-parent &&
- svn cp -m 'hi' $svnrepo/larger-parent $svnrepo/another-larger &&
+ svn import -m 'import a larger parent' import '$svnrepo/larger-parent' &&
+ svn cp -m 'hi' '$svnrepo/larger-parent' '$svnrepo/another-larger' &&
git-svn init --minimize-url -i larger \
- $svnrepo/another-larger/trunk/thunk/bump/thud &&
+ '$svnrepo/another-larger/trunk/thunk/bump/thud' &&
git-svn fetch -i larger &&
git rev-parse --verify refs/remotes/larger &&
git rev-parse --verify \
@@ -83,23 +83,23 @@ test_expect_success 'follow larger parent' "
"
test_expect_success 'follow higher-level parent' "
- svn mkdir -m 'follow higher-level parent' $svnrepo/blob &&
- svn co $svnrepo/blob blob &&
+ svn mkdir -m 'follow higher-level parent' '$svnrepo/blob' &&
+ svn co '$svnrepo/blob' blob &&
cd blob &&
echo hi > hi &&
svn add hi &&
svn commit -m 'hihi' &&
cd ..
- svn mkdir -m 'new glob at top level' $svnrepo/glob &&
- svn mv -m 'move blob down a level' $svnrepo/blob $svnrepo/glob/blob &&
- git-svn init --minimize-url -i blob $svnrepo/glob/blob &&
+ svn mkdir -m 'new glob at top level' '$svnrepo/glob' &&
+ svn mv -m 'move blob down a level' '$svnrepo/blob' '$svnrepo/glob/blob' &&
+ git-svn init --minimize-url -i blob '$svnrepo/glob/blob' &&
git-svn fetch -i blob
"
test_expect_success 'follow deleted directory' "
- svn mv -m 'bye!' $svnrepo/glob/blob/hi $svnrepo/glob/blob/bye &&
- svn rm -m 'remove glob' $svnrepo/glob &&
- git-svn init --minimize-url -i glob $svnrepo/glob &&
+ svn mv -m 'bye!' '$svnrepo/glob/blob/hi' '$svnrepo/glob/blob/bye' &&
+ svn rm -m 'remove glob' '$svnrepo/glob' &&
+ git-svn init --minimize-url -i glob '$svnrepo/glob' &&
git-svn fetch -i glob &&
test \"\`git cat-file blob refs/remotes/glob:blob/bye\`\" = hi &&
test \"\`git ls-tree refs/remotes/glob | wc -l \`\" -eq 1
@@ -118,9 +118,9 @@ test_expect_success 'follow-parent avoids deleting relevant info' "
echo 'bad delete test 2' > \
import/trunk/subversion/bindings/swig/perl/another-larger &&
cd import &&
- svn import -m 'r9270 test' . $svnrepo/r9270 &&
+ svn import -m 'r9270 test' . '$svnrepo/r9270' &&
cd .. &&
- svn co $svnrepo/r9270/trunk/subversion/bindings/swig/perl r9270 &&
+ svn co '$svnrepo/r9270/trunk/subversion/bindings/swig/perl' r9270 &&
cd r9270 &&
svn mkdir native &&
svn mv t native/t &&
@@ -130,7 +130,7 @@ test_expect_success 'follow-parent avoids deleting relevant info' "
svn commit -m 'reorg test' &&
cd .. &&
git-svn init --minimize-url -i r9270-t \
- $svnrepo/r9270/trunk/subversion/bindings/swig/perl/native/t &&
+ '$svnrepo/r9270/trunk/subversion/bindings/swig/perl/native/t' &&
git-svn fetch -i r9270-t &&
test \`git rev-list r9270-t | wc -l\` -eq 2 &&
test \"\`git ls-tree --name-only r9270-t~1\`\" = \
@@ -138,9 +138,9 @@ test_expect_success 'follow-parent avoids deleting relevant info' "
"
test_expect_success "track initial change if it was only made to parent" "
- svn cp -m 'wheee!' $svnrepo/r9270/trunk $svnrepo/r9270/drunk &&
+ svn cp -m 'wheee!' '$svnrepo/r9270/trunk' '$svnrepo/r9270/drunk' &&
git-svn init --minimize-url -i r9270-d \
- $svnrepo/r9270/drunk/subversion/bindings/swig/perl/native/t &&
+ '$svnrepo/r9270/drunk/subversion/bindings/swig/perl/native/t' &&
git-svn fetch -i r9270-d &&
test \`git rev-list r9270-d | wc -l\` -eq 3 &&
test \"\`git ls-tree --name-only r9270-t\`\" = \
@@ -150,7 +150,7 @@ test_expect_success "track initial change if it was only made to parent" "
"
test_expect_success "track multi-parent paths" "
- svn cp -m 'resurrect /glob' $svnrepo/r9270 $svnrepo/glob &&
+ svn cp -m 'resurrect /glob' '$svnrepo/r9270' '$svnrepo/glob' &&
git-svn multi-fetch &&
test \`git cat-file commit refs/remotes/glob | \
grep '^parent ' | wc -l\` -eq 2
@@ -161,8 +161,8 @@ test_expect_success "multi-fetch continues to work" "
"
test_expect_success "multi-fetch works off a 'clean' repository" "
- rm -r $GIT_DIR/svn $GIT_DIR/refs/remotes $GIT_DIR/logs &&
- mkdir $GIT_DIR/svn &&
+ rm -r '$GIT_DIR/svn' '$GIT_DIR/refs/remotes' '$GIT_DIR/logs' &&
+ mkdir '$GIT_DIR/svn' &&
git-svn multi-fetch
"
diff --git a/t/t9105-git-svn-commit-diff.sh b/t/t9105-git-svn-commit-diff.sh
index 318e172..2e1eb75 100755
--- a/t/t9105-git-svn-commit-diff.sh
+++ b/t/t9105-git-svn-commit-diff.sh
@@ -8,7 +8,7 @@ test_expect_success 'initialize repo' "
mkdir import &&
cd import &&
echo hello > readme &&
- svn import -m 'initial' . $svnrepo &&
+ svn import -m 'initial' . '$svnrepo' &&
cd .. &&
echo hello > readme &&
git update-index --add readme &&
@@ -27,16 +27,16 @@ prev=`git rev-parse --verify HEAD^1`
test_expect_success 'test the commit-diff command' "
test -n '$prev' && test -n '$head' &&
git-svn commit-diff -r1 '$prev' '$head' '$svnrepo' &&
- svn co $svnrepo wc &&
+ svn co '$svnrepo' wc &&
cmp readme wc/readme
"
test_expect_success 'commit-diff to a sub-directory (with git-svn config)' "
- svn import -m 'sub-directory' import $svnrepo/subdir &&
- git-svn init --minimize-url $svnrepo/subdir &&
+ svn import -m 'sub-directory' import '$svnrepo/subdir' &&
+ git-svn init --minimize-url '$svnrepo/subdir' &&
git-svn fetch &&
git-svn commit-diff -r3 '$prev' '$head' &&
- svn cat $svnrepo/subdir/readme > readme.2 &&
+ svn cat '$svnrepo/subdir/readme' > readme.2 &&
cmp readme readme.2
"
diff --git a/t/t9106-git-svn-commit-diff-clobber.sh b/t/t9106-git-svn-commit-diff-clobber.sh
index f74ab12..5125ed0 100755
--- a/t/t9106-git-svn-commit-diff-clobber.sh
+++ b/t/t9106-git-svn-commit-diff-clobber.sh
@@ -8,14 +8,14 @@ test_expect_success 'initialize repo' "
mkdir import &&
cd import &&
echo initial > file &&
- svn import -m 'initial' . $svnrepo &&
+ svn import -m 'initial' . '$svnrepo' &&
cd .. &&
echo initial > file &&
git update-index --add file &&
git commit -a -m 'initial'
"
test_expect_success 'commit change from svn side' "
- svn co $svnrepo t.svn &&
+ svn co '$svnrepo' t.svn &&
cd t.svn &&
echo second line from svn >> file &&
poke file &&
@@ -27,7 +27,7 @@ test_expect_success 'commit change from svn side' "
test_expect_success 'commit conflicting change from git' "
echo second line from git >> file &&
git commit -a -m 'second line from git' &&
- ! git-svn commit-diff -r1 HEAD~1 HEAD $svnrepo
+ ! git-svn commit-diff -r1 HEAD~1 HEAD '$svnrepo'
"
test_expect_success 'commit complementing change from git' "
@@ -36,14 +36,14 @@ test_expect_success 'commit complementing change from git' "
git commit -a -m 'second line from svn' &&
echo third line from git >> file &&
git commit -a -m 'third line from git' &&
- git-svn commit-diff -r2 HEAD~1 HEAD $svnrepo
+ git-svn commit-diff -r2 HEAD~1 HEAD '$svnrepo'
"
test_expect_success 'dcommit fails to commit because of conflict' "
- git-svn init $svnrepo &&
+ git-svn init '$svnrepo' &&
git-svn fetch &&
git reset --hard refs/remotes/git-svn &&
- svn co $svnrepo t.svn &&
+ svn co '$svnrepo' t.svn &&
cd t.svn &&
echo fourth line from svn >> file &&
poke file &&
@@ -67,7 +67,7 @@ test_expect_success 'dcommit does the svn equivalent of an index merge' "
"
test_expect_success 'commit another change from svn side' "
- svn co $svnrepo t.svn &&
+ svn co '$svnrepo' t.svn &&
cd t.svn &&
echo third line from svn >> file &&
poke file &&
diff --git a/t/t9106-git-svn-dcommit-clobber-series.sh b/t/t9106-git-svn-dcommit-clobber-series.sh
index ca8a00e..fb4b67a 100755
--- a/t/t9106-git-svn-dcommit-clobber-series.sh
+++ b/t/t9106-git-svn-dcommit-clobber-series.sh
@@ -8,9 +8,9 @@ test_expect_success 'initialize repo' "
mkdir import &&
cd import &&
awk 'BEGIN { for (i = 1; i < 64; i++) { print i } }' > file
- svn import -m 'initial' . $svnrepo &&
+ svn import -m 'initial' . '$svnrepo' &&
cd .. &&
- git svn init $svnrepo &&
+ git svn init '$svnrepo' &&
git svn fetch &&
test -e file
"
@@ -18,7 +18,7 @@ test_expect_success 'initialize repo' "
test_expect_success '(supposedly) non-conflicting change from SVN' "
test x\"\`sed -n -e 58p < file\`\" = x58 &&
test x\"\`sed -n -e 61p < file\`\" = x61 &&
- svn co $svnrepo tmp &&
+ svn co '$svnrepo' tmp &&
cd tmp &&
perl -i -p -e 's/^58\$/5588/' file &&
perl -i -p -e 's/^61\$/6611/' file &&
diff --git a/t/t9107-git-svn-migrate.sh b/t/t9107-git-svn-migrate.sh
index 0a41d52..545a08a 100755
--- a/t/t9107-git-svn-migrate.sh
+++ b/t/t9107-git-svn-migrate.sh
@@ -4,7 +4,7 @@ test_description='git-svn metadata migrations from previous versions'
. ./lib-git-svn.sh
test_expect_success 'setup old-looking metadata' "
- cp $GIT_DIR/config $GIT_DIR/config-old-git-svn &&
+ cp '$GIT_DIR/config' '$GIT_DIR/config-old-git-svn' &&
mkdir import &&
cd import &&
for i in trunk branches/a branches/b \
@@ -12,13 +12,13 @@ test_expect_success 'setup old-looking metadata' "
mkdir -p \$i && \
echo hello >> \$i/README || exit 1
done && \
- svn import -m test . $svnrepo
+ svn import -m test . '$svnrepo'
cd .. &&
- git-svn init $svnrepo &&
+ git-svn init '$svnrepo' &&
git-svn fetch &&
- mv $GIT_DIR/svn/* $GIT_DIR/ &&
- mv $GIT_DIR/svn/.metadata $GIT_DIR/ &&
- rmdir $GIT_DIR/svn &&
+ mv '$GIT_DIR/svn/'* '$GIT_DIR/' &&
+ mv '$GIT_DIR/svn/.metadata' '$GIT_DIR/' &&
+ rmdir '$GIT_DIR/svn' &&
git update-ref refs/heads/git-svn-HEAD refs/remotes/git-svn &&
git update-ref refs/heads/svn-HEAD refs/remotes/git-svn &&
git update-ref -d refs/remotes/git-svn refs/remotes/git-svn
@@ -28,20 +28,20 @@ head=`git rev-parse --verify refs/heads/git-svn-HEAD^0`
test_expect_success 'git-svn-HEAD is a real HEAD' "test -n '$head'"
test_expect_success 'initialize old-style (v0) git-svn layout' "
- mkdir -p $GIT_DIR/git-svn/info $GIT_DIR/svn/info &&
- echo $svnrepo > $GIT_DIR/git-svn/info/url &&
- echo $svnrepo > $GIT_DIR/svn/info/url &&
+ mkdir -p '$GIT_DIR/git-svn/info' '$GIT_DIR/svn/info' &&
+ echo '$svnrepo' > '$GIT_DIR/git-svn/info/url' &&
+ echo '$svnrepo' > '$GIT_DIR/svn/info/url' &&
git-svn migrate &&
- ! test -d $GIT_DIR/git-svn &&
+ ! test -d '$GIT_DIR/git-svn' &&
git rev-parse --verify refs/remotes/git-svn^0 &&
git rev-parse --verify refs/remotes/svn^0 &&
- test \`git config --get svn-remote.svn.url\` = '$svnrepo' &&
- test \`git config --get svn-remote.svn.fetch\` = \
+ test '$(git config --get svn-remote.svn.url)' = '$svnrepo' &&
+ test '$(git config --get svn-remote.svn.fetch)' = \
':refs/remotes/git-svn'
"
test_expect_success 'initialize a multi-repository repo' "
- git-svn init $svnrepo -T trunk -t tags -b branches &&
+ git-svn init '$svnrepo' -T trunk -t tags -b branches &&
git config --get-all svn-remote.svn.fetch > fetch.out &&
grep '^trunk:refs/remotes/trunk$' fetch.out &&
test -n \"\`git config --get svn-remote.svn.branches \
@@ -76,14 +76,14 @@ test_expect_success 'multi-fetch works on partial urls + paths' "
test_expect_success 'migrate --minimize on old inited layout' "
git config --unset-all svn-remote.svn.fetch &&
git config --unset-all svn-remote.svn.url &&
- rm -rf $GIT_DIR/svn &&
+ rm -rf '$GIT_DIR/svn' &&
for i in \`cat fetch.out\`; do
path=\`expr \$i : '\\([^:]*\\):.*$'\`
ref=\`expr \$i : '[^:]*:refs/remotes/\\(.*\\)$'\`
if test -z \"\$ref\"; then continue; fi
if test -n \"\$path\"; then path=\"/\$path\"; fi
- ( mkdir -p $GIT_DIR/svn/\$ref/info/ &&
- echo $svnrepo\$path > $GIT_DIR/svn/\$ref/info/url ) || exit 1;
+ ( mkdir -p '$GIT_DIR'/svn/\$ref/info/ &&
+ echo '$svnrepo'\$path > '$GIT_DIR'/svn/\$ref/info/url ) || exit 1;
done &&
git-svn migrate --minimize &&
test -z \"\`git config -l |grep -v '^svn-remote\.git-svn\.'\`\" &&
@@ -99,17 +99,17 @@ test_expect_success 'migrate --minimize on old inited layout' "
test_expect_success ".rev_db auto-converted to .rev_map.UUID" "
git-svn fetch -i trunk &&
- test -z \"\$(ls $GIT_DIR/svn/trunk/.rev_db.* 2>/dev/null)\" &&
- expect=\"\$(ls $GIT_DIR/svn/trunk/.rev_map.*)\" &&
+ test -z \"\$(ls '$GIT_DIR'/svn/trunk/.rev_db.* 2>/dev/null)\" &&
+ expect=\"\$(ls '$GIT_DIR'/svn/trunk/.rev_map.*)\" &&
test -n \"\$expect\" &&
rev_db=\$(echo \$expect | sed -e 's,_map,_db,') &&
- convert_to_rev_db \$expect \$rev_db &&
- rm -f \$expect &&
- test -f \$rev_db &&
+ convert_to_rev_db \"\$expect\" \"\$rev_db\" &&j
+ rm -f \"\$expect\" &&
+ test -f \"\$rev_db\" &&
git-svn fetch -i trunk &&
- test -z \"\$(ls $GIT_DIR/svn/trunk/.rev_db.* 2>/dev/null)\" &&
- test ! -e $GIT_DIR/svn/trunk/.rev_db &&
- test -f \$expect
+ test -z \"\$(ls '$GIT_DIR'/svn/trunk/.rev_db.* 2>/dev/null)\" &&
+ test ! -e '$GIT_DIR'/svn/trunk/.rev_db &&
+ test -f \"\$expect\"
"
test_done
diff --git a/t/t9108-git-svn-glob.sh b/t/t9108-git-svn-glob.sh
index db4344c..c6dc0ef 100755
--- a/t/t9108-git-svn-glob.sh
+++ b/t/t9108-git-svn-glob.sh
@@ -14,8 +14,8 @@ test_expect_success 'test refspec globbing' "
mkdir -p trunk/src/a trunk/src/b trunk/doc &&
echo 'hello world' > trunk/src/a/readme &&
echo 'goodbye world' > trunk/src/b/readme &&
- svn import -m 'initial' trunk $svnrepo/trunk &&
- svn co $svnrepo tmp &&
+ svn import -m 'initial' trunk '$svnrepo/trunk' &&
+ svn co '$svnrepo' tmp &&
cd tmp &&
mkdir branches tags &&
svn add branches tags &&
@@ -38,7 +38,7 @@ test_expect_success 'test refspec globbing' "
poke tags/end/src/b/readme &&
svn commit -m 'nothing to see here'
cd .. &&
- git config --add svn-remote.svn.url $svnrepo &&
+ git config --add svn-remote.svn.url '$svnrepo' &&
git config --add svn-remote.svn.fetch \
'trunk/src/a:refs/remotes/trunk' &&
git config --add svn-remote.svn.branches \
@@ -60,7 +60,7 @@ echo nothing to see here >> expect.two
cat expect.end >> expect.two
test_expect_success 'test left-hand-side only globbing' "
- git config --add svn-remote.two.url $svnrepo &&
+ git config --add svn-remote.two.url '$svnrepo' &&
git config --add svn-remote.two.fetch trunk:refs/remotes/two/trunk &&
git config --add svn-remote.two.branches \
'branches/*:refs/remotes/two/branches/*' &&
diff --git a/t/t9110-git-svn-use-svm-props.sh b/t/t9110-git-svn-use-svm-props.sh
index 6235af4..d4ab01f 100755
--- a/t/t9110-git-svn-use-svm-props.sh
+++ b/t/t9110-git-svn-use-svm-props.sh
@@ -8,11 +8,11 @@ test_description='git-svn useSvmProps test'
. ./lib-git-svn.sh
test_expect_success 'load svm repo' "
- svnadmin load -q $rawsvnrepo < ../t9110/svm.dump &&
- git-svn init --minimize-url -R arr -i bar $svnrepo/mirror/arr &&
- git-svn init --minimize-url -R argh -i dir $svnrepo/mirror/argh &&
+ svnadmin load -q '$rawsvnrepo' < ../t9110/svm.dump &&
+ git-svn init --minimize-url -R arr -i bar '$svnrepo/mirror/arr' &&
+ git-svn init --minimize-url -R argh -i dir '$svnrepo/mirror/argh' &&
git-svn init --minimize-url -R argh -i e \
- $svnrepo/mirror/argh/a/b/c/d/e &&
+ '$svnrepo/mirror/argh/a/b/c/d/e' &&
git config svn.useSvmProps true &&
git-svn fetch --all
"
diff --git a/t/t9111-git-svn-use-svnsync-props.sh b/t/t9111-git-svn-use-svnsync-props.sh
index ec7dedd..936f023 100755
--- a/t/t9111-git-svn-use-svnsync-props.sh
+++ b/t/t9111-git-svn-use-svnsync-props.sh
@@ -8,10 +8,10 @@ test_description='git-svn useSvnsyncProps test'
. ./lib-git-svn.sh
test_expect_success 'load svnsync repo' "
- svnadmin load -q $rawsvnrepo < ../t9111/svnsync.dump &&
- git-svn init --minimize-url -R arr -i bar $svnrepo/bar &&
- git-svn init --minimize-url -R argh -i dir $svnrepo/dir &&
- git-svn init --minimize-url -R argh -i e $svnrepo/dir/a/b/c/d/e &&
+ svnadmin load -q '$rawsvnrepo' < ../t9111/svnsync.dump &&
+ git-svn init --minimize-url -R arr -i bar '$svnrepo/bar' &&
+ git-svn init --minimize-url -R argh -i dir '$svnrepo/dir' &&
+ git-svn init --minimize-url -R argh -i e '$svnrepo/dir/a/b/c/d/e' &&
git config svn.useSvnsyncProps true &&
git-svn fetch --all
"
diff --git a/t/t9112-git-svn-md5less-file.sh b/t/t9112-git-svn-md5less-file.sh
index 646a5f0..d6a5a5b 100755
--- a/t/t9112-git-svn-md5less-file.sh
+++ b/t/t9112-git-svn-md5less-file.sh
@@ -40,8 +40,8 @@ PROPS-END
EOF
-test_expect_success 'load svn dumpfile' "svnadmin load $rawsvnrepo < dumpfile.svn"
+test_expect_success 'load svn dumpfile' "svnadmin load '$rawsvnrepo' < dumpfile.svn"
-test_expect_success 'initialize git-svn' "git-svn init $svnrepo"
+test_expect_success 'initialize git-svn' "git-svn init '$svnrepo'"
test_expect_success 'fetch revisions from svn' 'git-svn fetch'
test_done
diff --git a/t/t9113-git-svn-dcommit-new-file.sh b/t/t9113-git-svn-dcommit-new-file.sh
index 9ef0db9..b84a21e 100755
--- a/t/t9113-git-svn-dcommit-new-file.sh
+++ b/t/t9113-git-svn-dcommit-new-file.sh
@@ -15,14 +15,14 @@ test_description='git-svn dcommit new files over svn:// test'
start_svnserve () {
svnserve --listen-port $SVNSERVE_PORT \
- --root $rawsvnrepo \
+ --root "$rawsvnrepo" \
--listen-once \
--listen-host 127.0.0.1 &
}
test_expect_success 'start tracking an empty repo' "
- svn mkdir -m 'empty dir' $svnrepo/empty-dir &&
- echo anon-access = write >> $rawsvnrepo/conf/svnserve.conf &&
+ svn mkdir -m 'empty dir' '$svnrepo/empty-dir' &&
+ echo 'anon-access = write' >> '$rawsvnrepo/conf/svnserve.conf' &&
start_svnserve &&
git svn init svn://127.0.0.1:$SVNSERVE_PORT &&
git svn fetch
diff --git a/t/t9114-git-svn-dcommit-merge.sh b/t/t9114-git-svn-dcommit-merge.sh
index 225060b..9d9e34c 100755
--- a/t/t9114-git-svn-dcommit-merge.sh
+++ b/t/t9114-git-svn-dcommit-merge.sh
@@ -35,7 +35,7 @@ EOF
}
test_expect_success 'setup svn repository' "
- svn co $svnrepo mysvnwork &&
+ svn co '$svnrepo' mysvnwork &&
mkdir -p mysvnwork/trunk &&
cd mysvnwork &&
big_text_block >> trunk/README &&
@@ -45,7 +45,7 @@ test_expect_success 'setup svn repository' "
"
test_expect_success 'setup git mirror and merge' "
- git svn init $svnrepo -t tags -T trunk -b branches &&
+ git svn init '$svnrepo' -t tags -T trunk -b branches &&
git svn fetch &&
git checkout --track -b svn remotes/trunk &&
git checkout -b merge &&
diff --git a/t/t9115-git-svn-dcommit-funky-renames.sh b/t/t9115-git-svn-dcommit-funky-renames.sh
index 182299c..653578d 100755
--- a/t/t9115-git-svn-dcommit-funky-renames.sh
+++ b/t/t9115-git-svn-dcommit-funky-renames.sh
@@ -8,12 +8,12 @@ test_description='git-svn dcommit can commit renames of files with ugly names'
. ./lib-git-svn.sh
test_expect_success 'load repository with strange names' "
- svnadmin load -q $rawsvnrepo < ../t9115/funky-names.dump &&
+ svnadmin load -q '$rawsvnrepo' < ../t9115/funky-names.dump &&
start_httpd
"
test_expect_success 'init and fetch repository' "
- git svn init $svnrepo &&
+ git svn init '$svnrepo' &&
git svn fetch &&
git reset --hard git-svn
"
diff --git a/t/t9116-git-svn-log.sh b/t/t9116-git-svn-log.sh
index e1e8bdf..ab46903 100755
--- a/t/t9116-git-svn-log.sh
+++ b/t/t9116-git-svn-log.sh
@@ -14,9 +14,9 @@ test_expect_success 'setup repository and import' "
mkdir -p \$i && \
echo hello >> \$i/README || exit 1
done && \
- svn import -m test . $svnrepo
+ svn import -m test . '$svnrepo'
cd .. &&
- git-svn init $svnrepo -T trunk -b branches -t tags &&
+ git-svn init '$svnrepo' -T trunk -b branches -t tags &&
git-svn fetch &&
git reset --hard trunk &&
echo bye >> README &&
diff --git a/t/t9117-git-svn-init-clone.sh b/t/t9117-git-svn-init-clone.sh
index d482b40..aa1b167 100755
--- a/t/t9117-git-svn-init-clone.sh
+++ b/t/t9117-git-svn-init-clone.sh
@@ -16,13 +16,13 @@ cd tmp
test_expect_success 'setup svnrepo' "
mkdir project project/trunk project/branches project/tags &&
echo foo > project/trunk/foo &&
- svn import -m '$test_description' project $svnrepo/project &&
+ svn import -m '$test_description' project '$svnrepo/project' &&
rm -rf project
"
test_expect_success 'basic clone' "
test ! -d trunk &&
- git svn clone $svnrepo/project/trunk &&
+ git svn clone '$svnrepo/project/trunk' &&
test -d trunk/.git/svn &&
test -e trunk/foo &&
rm -rf trunk
@@ -30,7 +30,7 @@ test_expect_success 'basic clone' "
test_expect_success 'clone to target directory' "
test ! -d target &&
- git svn clone $svnrepo/project/trunk target &&
+ git svn clone '$svnrepo/project/trunk' target &&
test -d target/.git/svn &&
test -e target/foo &&
rm -rf target
@@ -38,7 +38,7 @@ test_expect_success 'clone to target directory' "
test_expect_success 'clone with --stdlayout' "
test ! -d project &&
- git svn clone -s $svnrepo/project &&
+ git svn clone -s '$svnrepo/project' &&
test -d project/.git/svn &&
test -e project/foo &&
rm -rf project
@@ -46,7 +46,7 @@ test_expect_success 'clone with --stdlayout' "
test_expect_success 'clone to target directory with --stdlayout' "
test ! -d target &&
- git svn clone -s $svnrepo/project target &&
+ git svn clone -s '$svnrepo/project' target &&
test -d target/.git/svn &&
test -e target/foo &&
rm -rf target
diff --git a/t/t9121-git-svn-fetch-renamed-dir.sh b/t/t9121-git-svn-fetch-renamed-dir.sh
index 5143ed6..f6a5d64 100755
--- a/t/t9121-git-svn-fetch-renamed-dir.sh
+++ b/t/t9121-git-svn-fetch-renamed-dir.sh
@@ -8,11 +8,11 @@ test_description='git-svn can fetch renamed directories'
. ./lib-git-svn.sh
test_expect_success 'load repository with renamed directory' "
- svnadmin load -q $rawsvnrepo < ../t9121/renamed-dir.dump
+ svnadmin load -q '$rawsvnrepo' < ../t9121/renamed-dir.dump
"
test_expect_success 'init and fetch repository' "
- git svn init $svnrepo/newname &&
+ git svn init '$svnrepo/newname' &&
git svn fetch
"
diff --git a/t/t9400-git-cvsserver-server.sh b/t/t9400-git-cvsserver-server.sh
index 166b43f..57cba8b 100755
--- a/t/t9400-git-cvsserver-server.sh
+++ b/t/t9400-git-cvsserver-server.sh
@@ -24,8 +24,8 @@ perl -e 'use DBI; use DBD::SQLite' >/dev/null 2>&1 || {
}
unset GIT_DIR GIT_CONFIG
-WORKDIR=$(pwd)
-SERVERDIR=$(pwd)/gitcvs.git
+WORKDIR="$(pwd)"
+SERVERDIR="$(pwd)/gitcvs.git"
git_config="$SERVERDIR/config"
CVSROOT=":fork:$SERVERDIR"
CVSWORK="$(pwd)/cvswork"
@@ -153,21 +153,21 @@ test_expect_success 'req_Root failure (conflicting roots)' \
tail log | grep "^error 1 Conflicting roots specified$"'
test_expect_success 'req_Root (strict paths)' \
- 'cat request-anonymous | git-cvsserver --strict-paths pserver $SERVERDIR >log 2>&1 &&
+ 'cat request-anonymous | git-cvsserver --strict-paths pserver "$SERVERDIR" >log 2>&1 &&
sed -ne \$p log | grep "^I LOVE YOU$"'
test_expect_success 'req_Root failure (strict-paths)' '
! cat request-anonymous |
- git-cvsserver --strict-paths pserver $WORKDIR >log 2>&1
+ git-cvsserver --strict-paths pserver "$WORKDIR" >log 2>&1
'
test_expect_success 'req_Root (w/o strict-paths)' \
- 'cat request-anonymous | git-cvsserver pserver $WORKDIR/ >log 2>&1 &&
+ 'cat request-anonymous | git-cvsserver pserver "$WORKDIR"/ >log 2>&1 &&
sed -ne \$p log | grep "^I LOVE YOU$"'
test_expect_success 'req_Root failure (w/o strict-paths)' '
! cat request-anonymous |
- git-cvsserver pserver $WORKDIR/gitcvs >log 2>&1
+ git-cvsserver pserver "$WORKDIR"/gitcvs >log 2>&1
'
cat >request-base <<EOF
@@ -180,25 +180,25 @@ Root /gitcvs.git
EOF
test_expect_success 'req_Root (base-path)' \
- 'cat request-base | git-cvsserver --strict-paths --base-path $WORKDIR/ pserver $SERVERDIR >log 2>&1 &&
+ 'cat request-base | git-cvsserver --strict-paths --base-path "$WORKDIR"/ pserver "$SERVERDIR" >log 2>&1 &&
sed -ne \$p log | grep "^I LOVE YOU$"'
test_expect_success 'req_Root failure (base-path)' '
! cat request-anonymous |
- git-cvsserver --strict-paths --base-path $WORKDIR pserver $SERVERDIR >log 2>&1
+ git-cvsserver --strict-paths --base-path "$WORKDIR" pserver "$SERVERDIR" >log 2>&1
'
GIT_DIR="$SERVERDIR" git config --bool gitcvs.enabled false || exit 1
test_expect_success 'req_Root (export-all)' \
- 'cat request-anonymous | git-cvsserver --export-all pserver $WORKDIR >log 2>&1 &&
+ 'cat request-anonymous | git-cvsserver --export-all pserver "$WORKDIR" >log 2>&1 &&
sed -ne \$p log | grep "^I LOVE YOU$"'
test_expect_success 'req_Root failure (export-all w/o whitelist)' \
'! (cat request-anonymous | git-cvsserver --export-all pserver >log 2>&1 || false)'
test_expect_success 'req_Root (everything together)' \
- 'cat request-base | git-cvsserver --export-all --strict-paths --base-path $WORKDIR/ pserver $SERVERDIR >log 2>&1 &&
+ 'cat request-base | git-cvsserver --export-all --strict-paths --base-path "$WORKDIR"/ pserver "$SERVERDIR" >log 2>&1 &&
sed -ne \$p log | grep "^I LOVE YOU$"'
GIT_DIR="$SERVERDIR" git config --bool gitcvs.enabled true || exit 1
diff --git a/t/t9500-gitweb-standalone-no-errors.sh b/t/t9500-gitweb-standalone-no-errors.sh
index 061a259..5e486c7 100755
--- a/t/t9500-gitweb-standalone-no-errors.sh
+++ b/t/t9500-gitweb-standalone-no-errors.sh
@@ -45,13 +45,13 @@ gitweb_run () {
export QUERY_STRING=""$1""
export PATH_INFO=""$2""
- export GITWEB_CONFIG=$(pwd)/gitweb_config.perl
+ export GITWEB_CONFIG="$(pwd)"/gitweb_config.perl
# some of git commands write to STDERR on error, but this is not
# written to web server logs, so we are not interested in that:
# we are interested only in properly formatted errors/warnings
rm -f gitweb.log &&
- perl -- $(pwd)/../../gitweb/gitweb.perl \
+ perl -- "$(pwd)"/../../gitweb/gitweb.perl \
>/dev/null 2>gitweb.log &&
if grep -q -s "^[[]" gitweb.log >/dev/null; then false; else true; fi
diff --git a/t/t9600-cvsimport.sh b/t/t9600-cvsimport.sh
index 00a74ee..a65147b 100755
--- a/t/t9600-cvsimport.sh
+++ b/t/t9600-cvsimport.sh
@@ -3,10 +3,10 @@
test_description='git-cvsimport basic tests'
. ./test-lib.sh
-CVSROOT=$(pwd)/cvsroot
+CVSROOT="$(pwd)"/cvsroot
export CVSROOT
# for clean cvsps cache
-HOME=$(pwd)
+HOME="$(pwd)"
export HOME
if ! type cvs >/dev/null 2>&1
@@ -36,7 +36,7 @@ test_expect_success 'setup cvsroot' 'cvs init'
test_expect_success 'setup a cvs module' '
- mkdir $CVSROOT/module &&
+ mkdir "$CVSROOT"/module &&
cvs co -d module-cvs module &&
cd module-cvs &&
cat <<EOF >o_fortuna &&
diff --git a/t/test-lib.sh b/t/test-lib.sh
index 7c2a8ba..8065776 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -329,7 +329,7 @@ test_create_repo () {
repo="$1"
mkdir "$repo"
cd "$repo" || error "Cannot setup test environment"
- "$GIT_EXEC_PATH/git" init --template=$GIT_EXEC_PATH/templates/blt/ >/dev/null 2>&1 ||
+ "$GIT_EXEC_PATH"/git init --template="$GIT_EXEC_PATH"/templates/blt/ >/dev/null 2>&1 ||
error "cannot run git init -- have you built things yet?"
mv .git/hooks .git/hooks-disabled
cd "$owd"
@@ -371,16 +371,16 @@ test_done () {
# Test the binaries we have just built. The tests are kept in
# t/ subdirectory and are run in trash subdirectory.
-PATH=$(pwd)/..:$PATH
-GIT_EXEC_PATH=$(pwd)/..
-GIT_TEMPLATE_DIR=$(pwd)/../templates/blt
+PATH="$(pwd)"/..:$PATH
+GIT_EXEC_PATH="$(pwd)"/..
+GIT_TEMPLATE_DIR="$(pwd)"/../templates/blt
unset GIT_CONFIG
unset GIT_CONFIG_LOCAL
GIT_CONFIG_NOSYSTEM=1
GIT_CONFIG_NOGLOBAL=1
export PATH GIT_EXEC_PATH GIT_TEMPLATE_DIR GIT_CONFIG_NOSYSTEM GIT_CONFIG_NOGLOBAL
-GITPERLLIB=$(pwd)/../perl/blib/lib:$(pwd)/../perl/blib/arch/auto/Git
+GITPERLLIB="$(pwd)"/../perl/blib/lib:"$(pwd)"/../perl/blib/arch/auto/Git
export GITPERLLIB
test -d ../templates/blt || {
error "You haven't built things yet, have you?"
--
1.5.5.67.g9a49
^ permalink raw reply related [relevance 9%]
* [PATCH v3 09/10] Fix tests breaking when checkout path contains shell metacharacters
@ 2008-05-04 5:37 8% ` Bryan Donlan
0 siblings, 0 replies; 200+ results
From: Bryan Donlan @ 2008-05-04 5:37 UTC (permalink / raw)
To: git; +Cc: Johannes Sixt, Adam Roben, gitster, Bryan Donlan
This fixes the remainder of the issues where the test script itself is at
fault for failing when the git checkout path contains whitespace or other
shell metacharacters.
Signed-off-by: Bryan Donlan <bdonlan@fushizen.net>
---
t/t0000-basic.sh | 4 +-
t/t1020-subdirectory.sh | 22 ++--
t/t3050-subprojects-fetch.sh | 2 +-
t/t3404-rebase-interactive.sh | 3 +-
t/t5500-fetch-pack.sh | 2 +-
t/t5512-ls-remote.sh | 2 +-
t/t5516-fetch-push.sh | 6 +-
t/t5700-clone-reference.sh | 2 +-
t/t5710-info-alternate.sh | 4 +-
t/t7003-filter-branch.sh | 2 +-
t/t7010-setup.sh | 2 +-
t/t7300-clean.sh | 2 +-
t/t7501-commit.sh | 8 +-
t/t7504-commit-msg-hook.sh | 23 ++--
t/t7505-prepare-commit-msg-hook.sh | 17 ++-
t/t9100-git-svn-basic.sh | 120 +++++++++---------
t/t9101-git-svn-props.sh | 8 +-
t/t9102-git-svn-deep-rmdir.sh | 20 ++--
t/t9103-git-svn-tracked-directory-removed.sh | 20 ++--
t/t9104-git-svn-follow-parent.sh | 172 ++++++++++++------------
t/t9105-git-svn-commit-diff.sh | 32 +++---
t/t9106-git-svn-commit-diff-clobber.sh | 56 ++++----
t/t9106-git-svn-dcommit-clobber-series.sh | 30 ++--
t/t9107-git-svn-migrate.sh | 124 +++++++++---------
t/t9108-git-svn-glob.sh | 76 ++++++------
t/t9110-git-svn-use-svm-props.sh | 12 +-
t/t9111-git-svn-use-svnsync-props.sh | 12 +-
t/t9112-git-svn-md5less-file.sh | 4 +-
t/t9113-git-svn-dcommit-new-file.sh | 10 +-
t/t9114-git-svn-dcommit-merge.sh | 22 ++--
t/t9115-git-svn-dcommit-funky-renames.sh | 12 +-
t/t9116-git-svn-log.sh | 12 +-
t/t9117-git-svn-init-clone.sh | 30 ++--
t/t9118-git-svn-funky-branch-names.sh | 24 ++--
t/t9120-git-svn-clone-with-percent-escapes.sh | 6 +-
t/t9500-gitweb-standalone-no-errors.sh | 11 +-
36 files changed, 460 insertions(+), 454 deletions(-)
diff --git a/t/t0000-basic.sh b/t/t0000-basic.sh
index 27b54cb..690f80a 100755
--- a/t/t0000-basic.sh
+++ b/t/t0000-basic.sh
@@ -305,10 +305,10 @@ test_expect_success 'absolute path works as expected' '
file="$dir"/index &&
test "$file" = "$(test-absolute-path $dir2/index)" &&
basename=blub &&
- test "$dir/$basename" = $(cd .git && test-absolute-path $basename) &&
+ test "$dir/$basename" = "$(cd .git && test-absolute-path "$basename")" &&
ln -s ../first/file .git/syml &&
sym="$(cd first; pwd -P)"/file &&
- test "$sym" = "$(test-absolute-path $dir2/syml)"
+ test "$sym" = "$(test-absolute-path "$dir2/syml")"
'
test_expect_success 'very long name in the index handled sanely' '
diff --git a/t/t1020-subdirectory.sh b/t/t1020-subdirectory.sh
index b9cef34..fc386ba 100755
--- a/t/t1020-subdirectory.sh
+++ b/t/t1020-subdirectory.sh
@@ -21,7 +21,7 @@ LF='
'
test_expect_success 'update-index and ls-files' '
- cd $HERE &&
+ cd "$HERE" &&
git update-index --add one &&
case "`git ls-files`" in
one) echo ok one ;;
@@ -41,7 +41,7 @@ test_expect_success 'update-index and ls-files' '
'
test_expect_success 'cat-file' '
- cd $HERE &&
+ cd "$HERE" &&
two=`git ls-files -s dir/two` &&
two=`expr "$two" : "[0-7]* \\([0-9a-f]*\\)"` &&
echo "$two" &&
@@ -54,7 +54,7 @@ test_expect_success 'cat-file' '
rm -f actual dir/actual
test_expect_success 'diff-files' '
- cd $HERE &&
+ cd "$HERE" &&
echo a >>one &&
echo d >>dir/two &&
case "`git diff-files --name-only`" in
@@ -74,7 +74,7 @@ test_expect_success 'diff-files' '
'
test_expect_success 'write-tree' '
- cd $HERE &&
+ cd "$HERE" &&
top=`git write-tree` &&
echo $top &&
cd dir &&
@@ -84,7 +84,7 @@ test_expect_success 'write-tree' '
'
test_expect_success 'checkout-index' '
- cd $HERE &&
+ cd "$HERE" &&
git checkout-index -f -u one &&
cmp one original.one &&
cd dir &&
@@ -93,7 +93,7 @@ test_expect_success 'checkout-index' '
'
test_expect_success 'read-tree' '
- cd $HERE &&
+ cd "$HERE" &&
rm -f one dir/two &&
tree=`git write-tree` &&
git read-tree --reset -u "$tree" &&
@@ -107,27 +107,27 @@ test_expect_success 'read-tree' '
'
test_expect_success 'no file/rev ambiguity check inside .git' '
- cd $HERE &&
+ cd "$HERE" &&
git commit -a -m 1 &&
- cd $HERE/.git &&
+ cd "$HERE"/.git &&
git show -s HEAD
'
test_expect_success 'no file/rev ambiguity check inside a bare repo' '
- cd $HERE &&
+ cd "$HERE" &&
git clone -s --bare .git foo.git &&
cd foo.git && GIT_DIR=. git show -s HEAD
'
# This still does not work as it should...
: test_expect_success 'no file/rev ambiguity check inside a bare repo' '
- cd $HERE &&
+ cd "$HERE" &&
git clone -s --bare .git foo.git &&
cd foo.git && git show -s HEAD
'
test_expect_success 'detection should not be fooled by a symlink' '
- cd $HERE &&
+ cd "$HERE" &&
rm -fr foo.git &&
git clone -s .git another &&
ln -s another yetanother &&
diff --git a/t/t3050-subprojects-fetch.sh b/t/t3050-subprojects-fetch.sh
index 2b21b10..4261e96 100755
--- a/t/t3050-subprojects-fetch.sh
+++ b/t/t3050-subprojects-fetch.sh
@@ -20,7 +20,7 @@ test_expect_success setup '
'
test_expect_success clone '
- git clone file://`pwd`/.git cloned &&
+ git clone "file://$(pwd)/.git" cloned &&
(git rev-parse HEAD; git ls-files -s) >expected &&
(
cd cloned &&
diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh
index 9cf873f..b9e3dbd 100755
--- a/t/t3404-rebase-interactive.sh
+++ b/t/t3404-rebase-interactive.sh
@@ -91,9 +91,8 @@ for line in $FAKE_LINES; do
done
EOF
+test_set_editor "$(pwd)/fake-editor.sh"
chmod a+x fake-editor.sh
-VISUAL="$(pwd)/fake-editor.sh"
-export VISUAL
test_expect_success 'no changes are a nop' '
git rebase -i F &&
diff --git a/t/t5500-fetch-pack.sh b/t/t5500-fetch-pack.sh
index 1700d07..140e874 100755
--- a/t/t5500-fetch-pack.sh
+++ b/t/t5500-fetch-pack.sh
@@ -129,7 +129,7 @@ pull_to_client 2nd "B" $((64*3))
pull_to_client 3rd "A" $((1*3)) # old fails
-test_expect_success "clone shallow" "git-clone --depth 2 file://`pwd`/. shallow"
+test_expect_success "clone shallow" 'git-clone --depth 2 "file://$(pwd)/." shallow'
(cd shallow; git count-objects -v) > count.shallow
diff --git a/t/t5512-ls-remote.sh b/t/t5512-ls-remote.sh
index c0dc949..1dd8eed 100755
--- a/t/t5512-ls-remote.sh
+++ b/t/t5512-ls-remote.sh
@@ -17,7 +17,7 @@ test_expect_success setup '
git show-ref -d | sed -e "s/ / /"
) >expected.all &&
- git remote add self $(pwd)/.git
+ git remote add self "$(pwd)/.git"
'
diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh
index 0a757d5..3af03d4 100755
--- a/t/t5516-fetch-push.sh
+++ b/t/t5516-fetch-push.sh
@@ -105,7 +105,7 @@ test_expect_success 'fetch with insteadOf' '
(
TRASH=$(pwd)/ &&
cd testrepo &&
- git config url.$TRASH.insteadOf trash/
+ git config "url.$TRASH.insteadOf" trash/ &&
git config remote.up.url trash/. &&
git config remote.up.fetch "refs/heads/*:refs/remotes/origin/*" &&
git fetch up &&
@@ -145,8 +145,8 @@ test_expect_success 'push with wildcard' '
test_expect_success 'push with insteadOf' '
mk_empty &&
- TRASH=$(pwd)/ &&
- git config url.$TRASH.insteadOf trash/ &&
+ TRASH="$(pwd)/" &&
+ git config "url./$TRASH/.insteadOf" trash/ &&
git push trash/testrepo refs/heads/master:refs/remotes/origin/master &&
(
cd testrepo &&
diff --git a/t/t5700-clone-reference.sh b/t/t5700-clone-reference.sh
index b6a5486..e5619a9 100755
--- a/t/t5700-clone-reference.sh
+++ b/t/t5700-clone-reference.sh
@@ -51,7 +51,7 @@ diff expected current'
cd "$base_dir"
test_expect_success 'cloning with reference (no -l -s)' \
-'git clone --reference B file://`pwd`/A D'
+'git clone --reference B "file://$(pwd)/A" D'
cd "$base_dir"
diff --git a/t/t5710-info-alternate.sh b/t/t5710-info-alternate.sh
index 910ccb4..ef7127c 100755
--- a/t/t5710-info-alternate.sh
+++ b/t/t5710-info-alternate.sh
@@ -81,9 +81,9 @@ test_valid_repo'
cd "$base_dir"
test_expect_success 'breaking of loops' \
-"echo '$base_dir/B/.git/objects' >> '$base_dir'/A/.git/objects/info/alternates&&
+'echo "$base_dir"/B/.git/objects >> "$base_dir"/A/.git/objects/info/alternates&&
cd C &&
-test_valid_repo"
+test_valid_repo'
cd "$base_dir"
diff --git a/t/t7003-filter-branch.sh b/t/t7003-filter-branch.sh
index efd658a..fd09030 100755
--- a/t/t7003-filter-branch.sh
+++ b/t/t7003-filter-branch.sh
@@ -125,7 +125,7 @@ test_expect_success 'use index-filter to move into a subdirectory' '
"git ls-files -s | sed \"s-\\t-&newsubdir/-\" |
GIT_INDEX_FILE=\$GIT_INDEX_FILE.new \
git update-index --index-info &&
- mv \$GIT_INDEX_FILE.new \$GIT_INDEX_FILE" directorymoved &&
+ mv \"\$GIT_INDEX_FILE.new\" \"\$GIT_INDEX_FILE\"" directorymoved &&
test -z "$(git diff HEAD directorymoved:newsubdir)"'
test_expect_success 'stops when msg filter fails' '
diff --git a/t/t7010-setup.sh b/t/t7010-setup.sh
index 02cf7c5..d8a7c79 100755
--- a/t/t7010-setup.sh
+++ b/t/t7010-setup.sh
@@ -122,7 +122,7 @@ test_expect_success 'commit using absolute path names' '
test_expect_success 'log using absolute path names' '
echo bb >>a/b/c/d &&
- git commit -m "bb" $(pwd)/a/b/c/d &&
+ git commit -m "bb" "$(pwd)/a/b/c/d" &&
git log a/b/c/d >f1.txt &&
git log "$(pwd)/a/b/c/d" >f2.txt &&
diff --git a/t/t7300-clean.sh b/t/t7300-clean.sh
index a50492f..bd77239 100755
--- a/t/t7300-clean.sh
+++ b/t/t7300-clean.sh
@@ -112,7 +112,7 @@ test_expect_success 'git-clean with absolute path' '
touch a.out src/part3.c docs/manual.txt obj.o build/lib.so &&
would_clean=$(
cd docs &&
- git clean -n $(pwd)/../src |
+ git clean -n "$(pwd)/../src" |
sed -n -e "s|^Would remove ||p"
) &&
test "$would_clean" = ../src/part3.c || {
diff --git a/t/t7501-commit.sh b/t/t7501-commit.sh
index c0288f3..e5fdb63 100755
--- a/t/t7501-commit.sh
+++ b/t/t7501-commit.sh
@@ -79,8 +79,8 @@ test_expect_success \
cat >editor <<\EOF
#!/bin/sh
-sed -e "s/a file/an amend commit/g" < $1 > $1-
-mv $1- $1
+sed -e "s/a file/an amend commit/g" < "$1" > "$1-"
+mv "$1-" "$1"
EOF
chmod 755 editor
@@ -99,8 +99,8 @@ test_expect_success \
cat >editor <<\EOF
#!/bin/sh
-sed -e "s/amend/older/g" < $1 > $1-
-mv $1- $1
+sed -e "s/amend/older/g" < "$1" > "$1-"
+mv "$1-" "$1"
EOF
chmod 755 editor
diff --git a/t/t7504-commit-msg-hook.sh b/t/t7504-commit-msg-hook.sh
index eff36aa..88577af 100755
--- a/t/t7504-commit-msg-hook.sh
+++ b/t/t7504-commit-msg-hook.sh
@@ -19,6 +19,9 @@ cp FAKE_MSG "$1"
exit 0
EOF
chmod +x fake-editor
+
+## Not using test_set_editor here so we can easily ensure the editor variable
+## is only set for the editor tests
FAKE_EDITOR="$(pwd)/fake-editor"
export FAKE_EDITOR
@@ -27,7 +30,7 @@ test_expect_success 'with no hook (editor)' '
echo "more foo" >> file &&
git add file &&
echo "more foo" > FAKE_MSG &&
- GIT_EDITOR="$FAKE_EDITOR" git commit
+ GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit
'
@@ -44,7 +47,7 @@ test_expect_success '--no-verify with no hook (editor)' '
echo "more bar" > file &&
git add file &&
echo "more bar" > FAKE_MSG &&
- GIT_EDITOR="$FAKE_EDITOR" git commit --no-verify
+ GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit --no-verify
'
@@ -71,7 +74,7 @@ test_expect_success 'with succeeding hook (editor)' '
echo "more more" >> file &&
git add file &&
echo "more more" > FAKE_MSG &&
- GIT_EDITOR="$FAKE_EDITOR" git commit
+ GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit
'
@@ -88,7 +91,7 @@ test_expect_success '--no-verify with succeeding hook (editor)' '
echo "even more more" >> file &&
git add file &&
echo "even more more" > FAKE_MSG &&
- GIT_EDITOR="$FAKE_EDITOR" git commit --no-verify
+ GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit --no-verify
'
@@ -111,7 +114,7 @@ test_expect_success 'with failing hook (editor)' '
echo "more another" >> file &&
git add file &&
echo "more another" > FAKE_MSG &&
- ! (GIT_EDITOR="$FAKE_EDITOR" git commit)
+ ! (GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit)
'
@@ -128,7 +131,7 @@ test_expect_success '--no-verify with failing hook (editor)' '
echo "more stuff" >> file &&
git add file &&
echo "more stuff" > FAKE_MSG &&
- GIT_EDITOR="$FAKE_EDITOR" git commit --no-verify
+ GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit --no-verify
'
@@ -146,7 +149,7 @@ test_expect_success 'with non-executable hook (editor)' '
echo "content again" >> file &&
git add file &&
echo "content again" > FAKE_MSG &&
- GIT_EDITOR="$FAKE_EDITOR" git commit -m "content again"
+ GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit -m "content again"
'
@@ -163,7 +166,7 @@ test_expect_success '--no-verify with non-executable hook (editor)' '
echo "even more content" >> file &&
git add file &&
echo "even more content" > FAKE_MSG &&
- GIT_EDITOR="$FAKE_EDITOR" git commit --no-verify
+ GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit --no-verify
'
@@ -193,7 +196,7 @@ test_expect_success 'hook edits commit message (editor)' '
echo "additional content" >> file &&
git add file &&
echo "additional content" > FAKE_MSG &&
- GIT_EDITOR="$FAKE_EDITOR" git commit &&
+ GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit &&
commit_msg_is "new message"
'
@@ -212,7 +215,7 @@ test_expect_success "hook doesn't edit commit message (editor)" '
echo "more plus" >> file &&
git add file &&
echo "more plus" > FAKE_MSG &&
- GIT_EDITOR="$FAKE_EDITOR" git commit --no-verify &&
+ GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit --no-verify &&
commit_msg_is "more plus"
'
diff --git a/t/t7505-prepare-commit-msg-hook.sh b/t/t7505-prepare-commit-msg-hook.sh
index 802aa62..cd6c7c8 100755
--- a/t/t7505-prepare-commit-msg-hook.sh
+++ b/t/t7505-prepare-commit-msg-hook.sh
@@ -18,6 +18,9 @@ cat > fake-editor <<'EOF'
exit 0
EOF
chmod +x fake-editor
+
+## Not using test_set_editor here so we can easily ensure the editor variable
+## is only set for the editor tests
FAKE_EDITOR="$(pwd)/fake-editor"
export FAKE_EDITOR
@@ -58,7 +61,7 @@ test_expect_success 'with hook (-m editor)' '
echo "more" >> file &&
git add file &&
- GIT_EDITOR="$FAKE_EDITOR" git commit -e -m "more more" &&
+ GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit -e -m "more more" &&
test "`git log -1 --pretty=format:%s`" = message
'
@@ -85,7 +88,7 @@ test_expect_success 'with hook (-F editor)' '
echo "more" >> file &&
git add file &&
- (echo more more | GIT_EDITOR="$FAKE_EDITOR" git commit -e -F -) &&
+ (echo more more | GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit -e -F -) &&
test "`git log -1 --pretty=format:%s`" = message
'
@@ -104,7 +107,7 @@ test_expect_success 'with hook (editor)' '
echo "more more" >> file &&
git add file &&
- GIT_EDITOR="$FAKE_EDITOR" git commit &&
+ GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit &&
test "`git log -1 --pretty=format:%s`" = default
'
@@ -114,7 +117,7 @@ test_expect_success 'with hook (--amend)' '
head=`git rev-parse HEAD` &&
echo "more" >> file &&
git add file &&
- GIT_EDITOR="$FAKE_EDITOR" git commit --amend &&
+ GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit --amend &&
test "`git log -1 --pretty=format:%s`" = "$head"
'
@@ -124,7 +127,7 @@ test_expect_success 'with hook (-c)' '
head=`git rev-parse HEAD` &&
echo "more" >> file &&
git add file &&
- GIT_EDITOR="$FAKE_EDITOR" git commit -c $head &&
+ GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit -c $head &&
test "`git log -1 --pretty=format:%s`" = "$head"
'
@@ -139,7 +142,7 @@ test_expect_success 'with failing hook' '
head=`git rev-parse HEAD` &&
echo "more" >> file &&
git add file &&
- ! GIT_EDITOR="$FAKE_EDITOR" git commit -c $head
+ ! GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit -c $head
'
@@ -148,7 +151,7 @@ test_expect_success 'with failing hook (--no-verify)' '
head=`git rev-parse HEAD` &&
echo "more" >> file &&
git add file &&
- ! GIT_EDITOR="$FAKE_EDITOR" git commit --no-verify -c $head
+ ! GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit --no-verify -c $head
'
diff --git a/t/t9100-git-svn-basic.sh b/t/t9100-git-svn-basic.sh
index 4e24ab3..bdf29c1 100755
--- a/t/t9100-git-svn-basic.sh
+++ b/t/t9100-git-svn-basic.sh
@@ -20,39 +20,39 @@ esac
echo 'define NO_SVN_TESTS to skip git-svn tests'
test_expect_success \
- 'initialize git-svn' "
+ 'initialize git-svn' '
mkdir import &&
cd import &&
echo foo > foo &&
ln -s foo foo.link
mkdir -p dir/a/b/c/d/e &&
- echo 'deep dir' > dir/a/b/c/d/e/file &&
+ echo "deep dir" > dir/a/b/c/d/e/file &&
mkdir bar &&
- echo 'zzz' > bar/zzz &&
- echo '#!/bin/sh' > exec.sh &&
+ echo "zzz" > bar/zzz &&
+ echo "#!/bin/sh" > exec.sh &&
chmod +x exec.sh &&
- svn import -m 'import for git-svn' . $svnrepo >/dev/null &&
+ svn import -m "import for git-svn" . "$svnrepo" >/dev/null &&
cd .. &&
rm -rf import &&
- git-svn init $svnrepo"
+ git-svn init "$svnrepo"'
test_expect_success \
'import an SVN revision into git' \
'git-svn fetch'
-test_expect_success "checkout from svn" "svn co $svnrepo '$SVN_TREE'"
+test_expect_success "checkout from svn" 'svn co "$svnrepo" "$SVN_TREE"'
name='try a deep --rmdir with a commit'
-test_expect_success "$name" "
+test_expect_success "$name" '
git checkout -f -b mybranch remotes/git-svn &&
mv dir/a/b/c/d/e/file dir/file &&
cp dir/file file &&
git update-index --add --remove dir/a/b/c/d/e/file dir/file file &&
- git commit -m '$name' &&
+ git commit -m "$name" &&
git-svn set-tree --find-copies-harder --rmdir \
remotes/git-svn..mybranch &&
- svn up '$SVN_TREE' &&
- test -d '$SVN_TREE'/dir && test ! -d '$SVN_TREE'/dir/a"
+ svn up "$SVN_TREE" &&
+ test -d "$SVN_TREE"/dir && test ! -d "$SVN_TREE"/dir/a'
name='detect node change from file to directory #1'
@@ -68,108 +68,108 @@ test_expect_success "$name" "
name='detect node change from directory to file #1'
-test_expect_success "$name" "
- rm -rf dir '$GIT_DIR'/index &&
+test_expect_success "$name" '
+ rm -rf dir "$GIT_DIR"/index &&
git checkout -f -b mybranch2 remotes/git-svn &&
mv bar/zzz zzz &&
rm -rf bar &&
mv zzz bar &&
git update-index --remove -- bar/zzz &&
git update-index --add -- bar &&
- git commit -m '$name' &&
+ git commit -m "$name" &&
! git-svn set-tree --find-copies-harder --rmdir \
- remotes/git-svn..mybranch2" || true
+ remotes/git-svn..mybranch2' || true
name='detect node change from file to directory #2'
-test_expect_success "$name" "
- rm -f '$GIT_DIR'/index &&
+test_expect_success "$name" '
+ rm -f "$GIT_DIR"/index &&
git checkout -f -b mybranch3 remotes/git-svn &&
rm bar/zzz &&
git update-index --remove bar/zzz &&
mkdir bar/zzz &&
echo yyy > bar/zzz/yyy &&
git update-index --add bar/zzz/yyy &&
- git commit -m '$name' &&
+ git commit -m "$name" &&
! git-svn set-tree --find-copies-harder --rmdir \
- remotes/git-svn..mybranch3" || true
+ remotes/git-svn..mybranch3' || true
name='detect node change from directory to file #2'
-test_expect_success "$name" "
- rm -f '$GIT_DIR'/index &&
+test_expect_success "$name" '
+ rm -f "$GIT_DIR"/index &&
git checkout -f -b mybranch4 remotes/git-svn &&
rm -rf dir &&
git update-index --remove -- dir/file &&
touch dir &&
echo asdf > dir &&
git update-index --add -- dir &&
- git commit -m '$name' &&
+ git commit -m "$name" &&
! git-svn set-tree --find-copies-harder --rmdir \
- remotes/git-svn..mybranch4" || true
+ remotes/git-svn..mybranch4' || true
name='remove executable bit from a file'
-test_expect_success "$name" "
- rm -f '$GIT_DIR'/index &&
+test_expect_success "$name" '
+ rm -f "$GIT_DIR"/index &&
git checkout -f -b mybranch5 remotes/git-svn &&
chmod -x exec.sh &&
git update-index exec.sh &&
- git commit -m '$name' &&
+ git commit -m "$name" &&
git-svn set-tree --find-copies-harder --rmdir \
remotes/git-svn..mybranch5 &&
- svn up '$SVN_TREE' &&
- test ! -x '$SVN_TREE'/exec.sh"
+ svn up "$SVN_TREE" &&
+ test ! -x "$SVN_TREE"/exec.sh'
name='add executable bit back file'
-test_expect_success "$name" "
+test_expect_success "$name" '
chmod +x exec.sh &&
git update-index exec.sh &&
- git commit -m '$name' &&
+ git commit -m "$name" &&
git-svn set-tree --find-copies-harder --rmdir \
remotes/git-svn..mybranch5 &&
- svn up '$SVN_TREE' &&
- test -x '$SVN_TREE'/exec.sh"
+ svn up "$SVN_TREE" &&
+ test -x "$SVN_TREE"/exec.sh'
name='executable file becomes a symlink to bar/zzz (file)'
-test_expect_success "$name" "
+test_expect_success "$name" '
rm exec.sh &&
ln -s bar/zzz exec.sh &&
git update-index exec.sh &&
- git commit -m '$name' &&
+ git commit -m "$name" &&
git-svn set-tree --find-copies-harder --rmdir \
remotes/git-svn..mybranch5 &&
- svn up '$SVN_TREE' &&
- test -L '$SVN_TREE'/exec.sh"
+ svn up "$SVN_TREE" &&
+ test -L "$SVN_TREE"/exec.sh'
name='new symlink is added to a file that was also just made executable'
-test_expect_success "$name" "
+test_expect_success "$name" '
chmod +x bar/zzz &&
ln -s bar/zzz exec-2.sh &&
git update-index --add bar/zzz exec-2.sh &&
- git commit -m '$name' &&
+ git commit -m "$name" &&
git-svn set-tree --find-copies-harder --rmdir \
remotes/git-svn..mybranch5 &&
- svn up '$SVN_TREE' &&
- test -x '$SVN_TREE'/bar/zzz &&
- test -L '$SVN_TREE'/exec-2.sh"
+ svn up "$SVN_TREE" &&
+ test -x "$SVN_TREE"/bar/zzz &&
+ test -L "$SVN_TREE"/exec-2.sh'
name='modify a symlink to become a file'
-test_expect_success "$name" "
+test_expect_success "$name" '
echo git help > help || true &&
rm exec-2.sh &&
cp help exec-2.sh &&
git update-index exec-2.sh &&
- git commit -m '$name' &&
+ git commit -m "$name" &&
git-svn set-tree --find-copies-harder --rmdir \
remotes/git-svn..mybranch5 &&
- svn up '$SVN_TREE' &&
- test -f '$SVN_TREE'/exec-2.sh &&
- test ! -L '$SVN_TREE'/exec-2.sh &&
- git diff help $SVN_TREE/exec-2.sh"
+ svn up "$SVN_TREE" &&
+ test -f "$SVN_TREE"/exec-2.sh &&
+ test ! -L "$SVN_TREE"/exec-2.sh &&
+ git diff help "$SVN_TREE"/exec-2.sh'
if test "$have_utf8" = t
then
@@ -190,10 +190,10 @@ name='test fetch functionality (svn => git) with alternate GIT_SVN_ID'
GIT_SVN_ID=alt
export GIT_SVN_ID
test_expect_success "$name" \
- "git-svn init $svnrepo && git-svn fetch &&
+ 'git-svn init "$svnrepo" && git-svn fetch &&
git rev-list --pretty=raw remotes/git-svn | grep ^tree | uniq > a &&
git rev-list --pretty=raw remotes/alt | grep ^tree | uniq > b &&
- git diff a b"
+ git diff a b'
name='check imported tree checksums expected tree checksums'
rm -f expected
@@ -219,22 +219,22 @@ test_expect_success 'exit if remote refs are ambigious' "
! git-svn migrate
"
-test_expect_success 'exit if init-ing a would clobber a URL' "
- svnadmin create ${PWD}/svnrepo2 &&
- svn mkdir -m 'mkdir bar' ${svnrepo}2/bar &&
+test_expect_success 'exit if init-ing a would clobber a URL' '
+ svnadmin create "${PWD}/svnrepo2" &&
+ svn mkdir -m "mkdir bar" "${svnrepo}2/bar" &&
git config --unset svn-remote.svn.fetch \
- '^bar:refs/remotes/git-svn$' &&
- ! git-svn init ${svnrepo}2/bar
- "
+ "^bar:refs/remotes/git-svn$" &&
+ ! git-svn init "${svnrepo}2/bar"
+ '
test_expect_success \
- 'init allows us to connect to another directory in the same repo' "
- git-svn init --minimize-url -i bar $svnrepo/bar &&
+ 'init allows us to connect to another directory in the same repo' '
+ git-svn init --minimize-url -i bar "$svnrepo/bar" &&
git config --get svn-remote.svn.fetch \
- '^bar:refs/remotes/bar$' &&
+ "^bar:refs/remotes/bar$" &&
git config --get svn-remote.svn.fetch \
- '^:refs/remotes/git-svn$'
- "
+ "^:refs/remotes/git-svn$"
+ '
test_expect_success 'able to dcommit to a subdirectory' "
git-svn fetch -i bar &&
diff --git a/t/t9101-git-svn-props.sh b/t/t9101-git-svn-props.sh
index d7a7047..f420796 100755
--- a/t/t9101-git-svn-props.sh
+++ b/t/t9101-git-svn-props.sh
@@ -52,7 +52,7 @@ EOF
cd ..
rm -rf import
-test_expect_success 'checkout working copy from svn' "svn co $svnrepo test_wc"
+test_expect_success 'checkout working copy from svn' 'svn co "$svnrepo" test_wc'
test_expect_success 'setup some commits to svn' \
'cd test_wc &&
echo Greetings >> kw.c &&
@@ -66,7 +66,7 @@ test_expect_success 'setup some commits to svn' \
svn commit -m "Propset Id" &&
cd ..'
-test_expect_success 'initialize git-svn' "git-svn init $svnrepo"
+test_expect_success 'initialize git-svn' 'git-svn init "$svnrepo"'
test_expect_success 'fetch revisions from svn' 'git-svn fetch'
name='test svn:keywords ignoring'
@@ -90,9 +90,9 @@ test_expect_success "propset CR on crlf files" \
cd ..'
test_expect_success 'fetch and pull latest from svn and checkout a new wc' \
- "git-svn fetch &&
+ 'git-svn fetch &&
git pull . remotes/git-svn &&
- svn co $svnrepo new_wc"
+ svn co "$svnrepo" new_wc'
for i in crlf ne_crlf lf ne_lf cr ne_cr empty_cr empty_lf empty empty_crlf
do
diff --git a/t/t9102-git-svn-deep-rmdir.sh b/t/t9102-git-svn-deep-rmdir.sh
index 4e08083..0e7ce34 100755
--- a/t/t9102-git-svn-deep-rmdir.sh
+++ b/t/t9102-git-svn-deep-rmdir.sh
@@ -2,29 +2,29 @@
test_description='git-svn rmdir'
. ./lib-git-svn.sh
-test_expect_success 'initialize repo' "
+test_expect_success 'initialize repo' '
mkdir import &&
cd import &&
mkdir -p deeply/nested/directory/number/1 &&
mkdir -p deeply/nested/directory/number/2 &&
echo foo > deeply/nested/directory/number/1/file &&
echo foo > deeply/nested/directory/number/2/another &&
- svn import -m 'import for git-svn' . $svnrepo &&
+ svn import -m "import for git-svn" . "$svnrepo" &&
cd ..
- "
+ '
-test_expect_success 'mirror via git-svn' "
- git-svn init $svnrepo &&
+test_expect_success 'mirror via git-svn' '
+ git-svn init "$svnrepo" &&
git-svn fetch &&
git checkout -f -b test-rmdir remotes/git-svn
- "
+ '
-test_expect_success 'Try a commit on rmdir' "
+test_expect_success 'Try a commit on rmdir' '
git rm -f deeply/nested/directory/number/2/another &&
- git commit -a -m 'remove another' &&
+ git commit -a -m "remove another" &&
git-svn set-tree --rmdir HEAD &&
- svn ls -R $svnrepo | grep ^deeply/nested/directory/number/1
- "
+ svn ls -R "$svnrepo" | grep ^deeply/nested/directory/number/1
+ '
test_done
diff --git a/t/t9103-git-svn-tracked-directory-removed.sh b/t/t9103-git-svn-tracked-directory-removed.sh
index 0f0b0fd..9ffd845 100755
--- a/t/t9103-git-svn-tracked-directory-removed.sh
+++ b/t/t9103-git-svn-tracked-directory-removed.sh
@@ -10,30 +10,30 @@ test_expect_success 'make history for tracking' '
mkdir import &&
mkdir import/trunk &&
echo hello >> import/trunk/README &&
- svn import -m initial import $svnrepo &&
+ svn import -m initial import "$svnrepo" &&
rm -rf import &&
- svn co $svnrepo/trunk trunk &&
+ svn co "$svnrepo"/trunk trunk &&
echo bye bye >> trunk/README &&
- svn rm -m "gone" $svnrepo/trunk &&
+ svn rm -m "gone" "$svnrepo"/trunk &&
rm -rf trunk &&
mkdir trunk &&
echo "new" > trunk/FOLLOWME &&
- svn import -m "new trunk" trunk $svnrepo/trunk
+ svn import -m "new trunk" trunk "$svnrepo"/trunk
'
test_expect_success 'clone repo with git' '
- git svn clone -s $svnrepo x &&
+ git svn clone -s "$svnrepo" x &&
test -f x/FOLLOWME &&
test ! -f x/README
'
-test_expect_success 'make sure r2 still has old file' '
+test_expect_success 'make sure r2 still has old file' "
cd x &&
- test -n "$(git svn find-rev r1)" &&
- git reset --hard $(git svn find-rev r1) &&
+ test -n \"\$(git svn find-rev r1)\" &&
+ git reset --hard \$(git svn find-rev r1) &&
test -f README &&
test ! -f FOLLOWME &&
- test x$(git svn find-rev r2) = x
-'
+ test x\$(git svn find-rev r2) = x
+"
test_done
diff --git a/t/t9104-git-svn-follow-parent.sh b/t/t9104-git-svn-follow-parent.sh
index 7ba7630..4d964e2 100755
--- a/t/t9104-git-svn-follow-parent.sh
+++ b/t/t9104-git-svn-follow-parent.sh
@@ -6,165 +6,165 @@
test_description='git-svn fetching'
. ./lib-git-svn.sh
-test_expect_success 'initialize repo' "
+test_expect_success 'initialize repo' '
mkdir import &&
cd import &&
mkdir -p trunk &&
echo hello > trunk/readme &&
- svn import -m 'initial' . $svnrepo &&
+ svn import -m "initial" . "$svnrepo" &&
cd .. &&
- svn co $svnrepo wc &&
+ svn co "$svnrepo" wc &&
cd wc &&
echo world >> trunk/readme &&
poke trunk/readme &&
- svn commit -m 'another commit' &&
+ svn commit -m "another commit" &&
svn up &&
svn mv trunk thunk &&
echo goodbye >> thunk/readme &&
poke thunk/readme &&
- svn commit -m 'bye now' &&
+ svn commit -m "bye now" &&
cd ..
- "
+ '
-test_expect_success 'init and fetch a moved directory' "
- git-svn init --minimize-url -i thunk $svnrepo/thunk &&
+test_expect_success 'init and fetch a moved directory' '
+ git-svn init --minimize-url -i thunk "$svnrepo"/thunk &&
git-svn fetch -i thunk &&
- test \"\`git rev-parse --verify refs/remotes/thunk@2\`\" \
- = \"\`git rev-parse --verify refs/remotes/thunk~1\`\" &&
- test \"\`git cat-file blob refs/remotes/thunk:readme |\
- sed -n -e '3p'\`\" = goodbye &&
- test -z \"\`git config --get svn-remote.svn.fetch \
- '^trunk:refs/remotes/thunk@2$'\`\"
- "
+ test "`git rev-parse --verify refs/remotes/thunk@2`" \
+ = "`git rev-parse --verify refs/remotes/thunk~1`" &&
+ test "`git cat-file blob refs/remotes/thunk:readme |\
+ sed -n -e "3p"`" = goodbye &&
+ test -z "`git config --get svn-remote.svn.fetch \
+ "^trunk:refs/remotes/thunk@2$"`"
+ '
-test_expect_success 'init and fetch from one svn-remote' "
- git config svn-remote.svn.url $svnrepo &&
+test_expect_success 'init and fetch from one svn-remote' '
+ git config svn-remote.svn.url "$svnrepo" &&
git config --add svn-remote.svn.fetch \
trunk:refs/remotes/svn/trunk &&
git config --add svn-remote.svn.fetch \
thunk:refs/remotes/svn/thunk &&
git-svn fetch -i svn/thunk &&
- test \"\`git rev-parse --verify refs/remotes/svn/trunk\`\" \
- = \"\`git rev-parse --verify refs/remotes/svn/thunk~1\`\" &&
- test \"\`git cat-file blob refs/remotes/svn/thunk:readme |\
- sed -n -e '3p'\`\" = goodbye
- "
+ test "`git rev-parse --verify refs/remotes/svn/trunk`" \
+ = "`git rev-parse --verify refs/remotes/svn/thunk~1`" &&
+ test "`git cat-file blob refs/remotes/svn/thunk:readme |\
+ sed -n -e "3p"`" = goodbye
+ '
-test_expect_success 'follow deleted parent' "
- (svn cp -m 'resurrecting trunk as junk' \
- $svnrepo/trunk@2 $svnrepo/junk ||
- svn cp -m 'resurrecting trunk as junk' \
- -r2 $svnrepo/trunk $svnrepo/junk) &&
+test_expect_success 'follow deleted parent' '
+ (svn cp -m "resurrecting trunk as junk" \
+ "$svnrepo"/trunk@2 "$svnrepo"/junk ||
+ svn cp -m "resurrecting trunk as junk" \
+ -r2 "$svnrepo"/trunk "$svnrepo"/junk) &&
git config --add svn-remote.svn.fetch \
junk:refs/remotes/svn/junk &&
git-svn fetch -i svn/thunk &&
git-svn fetch -i svn/junk &&
- test -z \"\`git diff svn/junk svn/trunk\`\" &&
- test \"\`git merge-base svn/junk svn/trunk\`\" \
- = \"\`git rev-parse svn/trunk\`\"
- "
+ test -z "`git diff svn/junk svn/trunk`" &&
+ test "`git merge-base svn/junk svn/trunk`" \
+ = "`git rev-parse svn/trunk`"
+ '
-test_expect_success 'follow larger parent' "
+test_expect_success 'follow larger parent' '
mkdir -p import/trunk/thunk/bump/thud &&
echo hi > import/trunk/thunk/bump/thud/file &&
- svn import -m 'import a larger parent' import $svnrepo/larger-parent &&
- svn cp -m 'hi' $svnrepo/larger-parent $svnrepo/another-larger &&
+ svn import -m "import a larger parent" import "$svnrepo"/larger-parent &&
+ svn cp -m "hi" "$svnrepo"/larger-parent "$svnrepo"/another-larger &&
git-svn init --minimize-url -i larger \
- $svnrepo/another-larger/trunk/thunk/bump/thud &&
+ "$svnrepo"/another-larger/trunk/thunk/bump/thud &&
git-svn fetch -i larger &&
git rev-parse --verify refs/remotes/larger &&
git rev-parse --verify \
refs/remotes/larger-parent/trunk/thunk/bump/thud &&
- test \"\`git merge-base \
+ test "`git merge-base \
refs/remotes/larger-parent/trunk/thunk/bump/thud \
- refs/remotes/larger\`\" = \
- \"\`git rev-parse refs/remotes/larger\`\"
+ refs/remotes/larger`" = \
+ "`git rev-parse refs/remotes/larger`"
true
- "
+ '
-test_expect_success 'follow higher-level parent' "
- svn mkdir -m 'follow higher-level parent' $svnrepo/blob &&
- svn co $svnrepo/blob blob &&
+test_expect_success 'follow higher-level parent' '
+ svn mkdir -m "follow higher-level parent" "$svnrepo"/blob &&
+ svn co "$svnrepo"/blob blob &&
cd blob &&
echo hi > hi &&
svn add hi &&
- svn commit -m 'hihi' &&
+ svn commit -m "hihi" &&
cd ..
- svn mkdir -m 'new glob at top level' $svnrepo/glob &&
- svn mv -m 'move blob down a level' $svnrepo/blob $svnrepo/glob/blob &&
- git-svn init --minimize-url -i blob $svnrepo/glob/blob &&
+ svn mkdir -m "new glob at top level" "$svnrepo"/glob &&
+ svn mv -m "move blob down a level" "$svnrepo"/blob "$svnrepo"/glob/blob &&
+ git-svn init --minimize-url -i blob "$svnrepo"/glob/blob &&
git-svn fetch -i blob
- "
+ '
-test_expect_success 'follow deleted directory' "
- svn mv -m 'bye!' $svnrepo/glob/blob/hi $svnrepo/glob/blob/bye &&
- svn rm -m 'remove glob' $svnrepo/glob &&
- git-svn init --minimize-url -i glob $svnrepo/glob &&
+test_expect_success 'follow deleted directory' '
+ svn mv -m "bye!" "$svnrepo"/glob/blob/hi "$svnrepo"/glob/blob/bye &&
+ svn rm -m "remove glob" "$svnrepo"/glob &&
+ git-svn init --minimize-url -i glob "$svnrepo"/glob &&
git-svn fetch -i glob &&
- test \"\`git cat-file blob refs/remotes/glob:blob/bye\`\" = hi &&
- test \"\`git ls-tree refs/remotes/glob | wc -l \`\" -eq 1
- "
+ test "`git cat-file blob refs/remotes/glob:blob/bye`" = hi &&
+ test "`git ls-tree refs/remotes/glob | wc -l `" -eq 1
+ '
# ref: r9270 of the Subversion repository: (http://svn.collab.net/repos/svn)
# in trunk/subversion/bindings/swig/perl
-test_expect_success 'follow-parent avoids deleting relevant info' "
+test_expect_success 'follow-parent avoids deleting relevant info' '
mkdir -p import/trunk/subversion/bindings/swig/perl/t &&
for i in a b c ; do \
- echo \$i > import/trunk/subversion/bindings/swig/perl/\$i.pm &&
- echo _\$i > import/trunk/subversion/bindings/swig/perl/t/\$i.t; \
+ echo $i > import/trunk/subversion/bindings/swig/perl/$i.pm &&
+ echo _$i > import/trunk/subversion/bindings/swig/perl/t/$i.t; \
done &&
- echo 'bad delete test' > \
+ echo "bad delete test" > \
import/trunk/subversion/bindings/swig/perl/t/larger-parent &&
- echo 'bad delete test 2' > \
+ echo "bad delete test 2" > \
import/trunk/subversion/bindings/swig/perl/another-larger &&
cd import &&
- svn import -m 'r9270 test' . $svnrepo/r9270 &&
+ svn import -m "r9270 test" . "$svnrepo"/r9270 &&
cd .. &&
- svn co $svnrepo/r9270/trunk/subversion/bindings/swig/perl r9270 &&
+ svn co "$svnrepo"/r9270/trunk/subversion/bindings/swig/perl r9270 &&
cd r9270 &&
svn mkdir native &&
svn mv t native/t &&
- for i in a b c; do svn mv \$i.pm native/\$i.pm; done &&
+ for i in a b c; do svn mv $i.pm native/$i.pm; done &&
echo z >> native/t/c.t &&
poke native/t/c.t &&
- svn commit -m 'reorg test' &&
+ svn commit -m "reorg test" &&
cd .. &&
git-svn init --minimize-url -i r9270-t \
- $svnrepo/r9270/trunk/subversion/bindings/swig/perl/native/t &&
+ "$svnrepo"/r9270/trunk/subversion/bindings/swig/perl/native/t &&
git-svn fetch -i r9270-t &&
- test \`git rev-list r9270-t | wc -l\` -eq 2 &&
- test \"\`git ls-tree --name-only r9270-t~1\`\" = \
- \"\`git ls-tree --name-only r9270-t\`\"
- "
+ test `git rev-list r9270-t | wc -l` -eq 2 &&
+ test "`git ls-tree --name-only r9270-t~1`" = \
+ "`git ls-tree --name-only r9270-t`"
+ '
-test_expect_success "track initial change if it was only made to parent" "
- svn cp -m 'wheee!' $svnrepo/r9270/trunk $svnrepo/r9270/drunk &&
+test_expect_success "track initial change if it was only made to parent" '
+ svn cp -m "wheee!" "$svnrepo"/r9270/trunk "$svnrepo"/r9270/drunk &&
git-svn init --minimize-url -i r9270-d \
- $svnrepo/r9270/drunk/subversion/bindings/swig/perl/native/t &&
+ "$svnrepo"/r9270/drunk/subversion/bindings/swig/perl/native/t &&
git-svn fetch -i r9270-d &&
- test \`git rev-list r9270-d | wc -l\` -eq 3 &&
- test \"\`git ls-tree --name-only r9270-t\`\" = \
- \"\`git ls-tree --name-only r9270-d\`\" &&
- test \"\`git rev-parse r9270-t\`\" = \
- \"\`git rev-parse r9270-d~1\`\"
- "
+ test `git rev-list r9270-d | wc -l` -eq 3 &&
+ test "`git ls-tree --name-only r9270-t`" = \
+ "`git ls-tree --name-only r9270-d`" &&
+ test "`git rev-parse r9270-t`" = \
+ "`git rev-parse r9270-d~1`"
+ '
-test_expect_success "track multi-parent paths" "
- svn cp -m 'resurrect /glob' $svnrepo/r9270 $svnrepo/glob &&
+test_expect_success "track multi-parent paths" '
+ svn cp -m "resurrect /glob" "$svnrepo"/r9270 "$svnrepo"/glob &&
git-svn multi-fetch &&
- test \`git cat-file commit refs/remotes/glob | \
- grep '^parent ' | wc -l\` -eq 2
- "
+ test `git cat-file commit refs/remotes/glob | \
+ grep "^parent " | wc -l` -eq 2
+ '
test_expect_success "multi-fetch continues to work" "
git-svn multi-fetch
"
-test_expect_success "multi-fetch works off a 'clean' repository" "
- rm -r $GIT_DIR/svn $GIT_DIR/refs/remotes $GIT_DIR/logs &&
- mkdir $GIT_DIR/svn &&
+test_expect_success "multi-fetch works off a 'clean' repository" '
+ rm -r "$GIT_DIR/svn" "$GIT_DIR/refs/remotes" "$GIT_DIR/logs" &&
+ mkdir "$GIT_DIR/svn" &&
git-svn multi-fetch
- "
+ '
test_debug 'gitk --all &'
diff --git a/t/t9105-git-svn-commit-diff.sh b/t/t9105-git-svn-commit-diff.sh
index 318e172..6323036 100755
--- a/t/t9105-git-svn-commit-diff.sh
+++ b/t/t9105-git-svn-commit-diff.sh
@@ -4,18 +4,18 @@
test_description='git-svn commit-diff'
. ./lib-git-svn.sh
-test_expect_success 'initialize repo' "
+test_expect_success 'initialize repo' '
mkdir import &&
cd import &&
echo hello > readme &&
- svn import -m 'initial' . $svnrepo &&
+ svn import -m "initial" . "$svnrepo" &&
cd .. &&
echo hello > readme &&
git update-index --add readme &&
- git commit -a -m 'initial' &&
+ git commit -a -m "initial" &&
echo world >> readme &&
- git commit -a -m 'another'
- "
+ git commit -a -m "another"
+ '
head=`git rev-parse --verify HEAD^0`
prev=`git rev-parse --verify HEAD^1`
@@ -24,20 +24,20 @@ prev=`git rev-parse --verify HEAD^1`
# commit, so only a basic test of functionality is needed since we've
# already tested commit extensively elsewhere
-test_expect_success 'test the commit-diff command' "
- test -n '$prev' && test -n '$head' &&
- git-svn commit-diff -r1 '$prev' '$head' '$svnrepo' &&
- svn co $svnrepo wc &&
+test_expect_success 'test the commit-diff command' '
+ test -n "$prev" && test -n "$head" &&
+ git-svn commit-diff -r1 "$prev" "$head" "$svnrepo" &&
+ svn co "$svnrepo" wc &&
cmp readme wc/readme
- "
+ '
-test_expect_success 'commit-diff to a sub-directory (with git-svn config)' "
- svn import -m 'sub-directory' import $svnrepo/subdir &&
- git-svn init --minimize-url $svnrepo/subdir &&
+test_expect_success 'commit-diff to a sub-directory (with git-svn config)' '
+ svn import -m "sub-directory" import "$svnrepo"/subdir &&
+ git-svn init --minimize-url "$svnrepo"/subdir &&
git-svn fetch &&
- git-svn commit-diff -r3 '$prev' '$head' &&
- svn cat $svnrepo/subdir/readme > readme.2 &&
+ git-svn commit-diff -r3 "$prev" "$head" &&
+ svn cat "$svnrepo"/subdir/readme > readme.2 &&
cmp readme readme.2
- "
+ '
test_done
diff --git a/t/t9106-git-svn-commit-diff-clobber.sh b/t/t9106-git-svn-commit-diff-clobber.sh
index f74ab12..58a3a7b 100755
--- a/t/t9106-git-svn-commit-diff-clobber.sh
+++ b/t/t9106-git-svn-commit-diff-clobber.sh
@@ -4,56 +4,56 @@
test_description='git-svn commit-diff clobber'
. ./lib-git-svn.sh
-test_expect_success 'initialize repo' "
+test_expect_success 'initialize repo' '
mkdir import &&
cd import &&
echo initial > file &&
- svn import -m 'initial' . $svnrepo &&
+ svn import -m "initial" . "$svnrepo" &&
cd .. &&
echo initial > file &&
git update-index --add file &&
- git commit -a -m 'initial'
- "
-test_expect_success 'commit change from svn side' "
- svn co $svnrepo t.svn &&
+ git commit -a -m "initial"
+ '
+test_expect_success 'commit change from svn side' '
+ svn co "$svnrepo" t.svn &&
cd t.svn &&
echo second line from svn >> file &&
poke file &&
- svn commit -m 'second line from svn' &&
+ svn commit -m "second line from svn" &&
cd .. &&
rm -rf t.svn
- "
+ '
-test_expect_success 'commit conflicting change from git' "
+test_expect_success 'commit conflicting change from git' '
echo second line from git >> file &&
- git commit -a -m 'second line from git' &&
- ! git-svn commit-diff -r1 HEAD~1 HEAD $svnrepo
-"
+ git commit -a -m "second line from git" &&
+ ! git-svn commit-diff -r1 HEAD~1 HEAD "$svnrepo"
+'
-test_expect_success 'commit complementing change from git' "
+test_expect_success 'commit complementing change from git' '
git reset --hard HEAD~1 &&
echo second line from svn >> file &&
- git commit -a -m 'second line from svn' &&
+ git commit -a -m "second line from svn" &&
echo third line from git >> file &&
- git commit -a -m 'third line from git' &&
- git-svn commit-diff -r2 HEAD~1 HEAD $svnrepo
- "
+ git commit -a -m "third line from git" &&
+ git-svn commit-diff -r2 HEAD~1 HEAD "$svnrepo"
+ '
-test_expect_success 'dcommit fails to commit because of conflict' "
- git-svn init $svnrepo &&
+test_expect_success 'dcommit fails to commit because of conflict' '
+ git-svn init "$svnrepo" &&
git-svn fetch &&
git reset --hard refs/remotes/git-svn &&
- svn co $svnrepo t.svn &&
+ svn co "$svnrepo" t.svn &&
cd t.svn &&
echo fourth line from svn >> file &&
poke file &&
- svn commit -m 'fourth line from svn' &&
+ svn commit -m "fourth line from svn" &&
cd .. &&
rm -rf t.svn &&
- echo 'fourth line from git' >> file &&
- git commit -a -m 'fourth line from git' &&
+ echo "fourth line from git" >> file &&
+ git commit -a -m "fourth line from git" &&
! git-svn dcommit
- "
+ '
test_expect_success 'dcommit does the svn equivalent of an index merge' "
git reset --hard refs/remotes/git-svn &&
@@ -66,15 +66,15 @@ test_expect_success 'dcommit does the svn equivalent of an index merge' "
git-svn dcommit
"
-test_expect_success 'commit another change from svn side' "
- svn co $svnrepo t.svn &&
+test_expect_success 'commit another change from svn side' '
+ svn co "$svnrepo" t.svn &&
cd t.svn &&
echo third line from svn >> file &&
poke file &&
- svn commit -m 'third line from svn' &&
+ svn commit -m "third line from svn" &&
cd .. &&
rm -rf t.svn
- "
+ '
test_expect_success 'multiple dcommit from git-svn will not clobber svn' "
git reset --hard refs/remotes/git-svn &&
diff --git a/t/t9106-git-svn-dcommit-clobber-series.sh b/t/t9106-git-svn-dcommit-clobber-series.sh
index ca8a00e..a400dc7 100755
--- a/t/t9106-git-svn-dcommit-clobber-series.sh
+++ b/t/t9106-git-svn-dcommit-clobber-series.sh
@@ -4,30 +4,30 @@
test_description='git-svn dcommit clobber series'
. ./lib-git-svn.sh
-test_expect_success 'initialize repo' "
+test_expect_success 'initialize repo' '
mkdir import &&
cd import &&
- awk 'BEGIN { for (i = 1; i < 64; i++) { print i } }' > file
- svn import -m 'initial' . $svnrepo &&
+ awk "BEGIN { for (i = 1; i < 64; i++) { print i } }" > file
+ svn import -m "initial" . "$svnrepo" &&
cd .. &&
- git svn init $svnrepo &&
+ git svn init "$svnrepo" &&
git svn fetch &&
test -e file
- "
+ '
-test_expect_success '(supposedly) non-conflicting change from SVN' "
- test x\"\`sed -n -e 58p < file\`\" = x58 &&
- test x\"\`sed -n -e 61p < file\`\" = x61 &&
- svn co $svnrepo tmp &&
+test_expect_success '(supposedly) non-conflicting change from SVN' '
+ test x"`sed -n -e 58p < file`" = x58 &&
+ test x"`sed -n -e 61p < file`" = x61 &&
+ svn co "$svnrepo" tmp &&
cd tmp &&
- perl -i -p -e 's/^58\$/5588/' file &&
- perl -i -p -e 's/^61\$/6611/' file &&
+ perl -i -p -e "s/^58$/5588/" file &&
+ perl -i -p -e "s/^61$/6611/" file &&
poke file &&
- test x\"\`sed -n -e 58p < file\`\" = x5588 &&
- test x\"\`sed -n -e 61p < file\`\" = x6611 &&
- svn commit -m '58 => 5588, 61 => 6611' &&
+ test x"`sed -n -e 58p < file`" = x5588 &&
+ test x"`sed -n -e 61p < file`" = x6611 &&
+ svn commit -m "58 => 5588, 61 => 6611" &&
cd ..
- "
+ '
test_expect_success 'some unrelated changes to git' "
echo hi > life &&
diff --git a/t/t9107-git-svn-migrate.sh b/t/t9107-git-svn-migrate.sh
index 0a41d52..d9b553a 100755
--- a/t/t9107-git-svn-migrate.sh
+++ b/t/t9107-git-svn-migrate.sh
@@ -3,61 +3,61 @@
test_description='git-svn metadata migrations from previous versions'
. ./lib-git-svn.sh
-test_expect_success 'setup old-looking metadata' "
- cp $GIT_DIR/config $GIT_DIR/config-old-git-svn &&
+test_expect_success 'setup old-looking metadata' '
+ cp "$GIT_DIR"/config "$GIT_DIR"/config-old-git-svn &&
mkdir import &&
cd import &&
for i in trunk branches/a branches/b \
tags/0.1 tags/0.2 tags/0.3; do
- mkdir -p \$i && \
- echo hello >> \$i/README || exit 1
+ mkdir -p $i && \
+ echo hello >> $i/README || exit 1
done && \
- svn import -m test . $svnrepo
+ svn import -m test . "$svnrepo"
cd .. &&
- git-svn init $svnrepo &&
+ git-svn init "$svnrepo" &&
git-svn fetch &&
- mv $GIT_DIR/svn/* $GIT_DIR/ &&
- mv $GIT_DIR/svn/.metadata $GIT_DIR/ &&
- rmdir $GIT_DIR/svn &&
+ mv "$GIT_DIR"/svn/* "$GIT_DIR"/ &&
+ mv "$GIT_DIR"/svn/.metadata "$GIT_DIR"/ &&
+ rmdir "$GIT_DIR"/svn &&
git update-ref refs/heads/git-svn-HEAD refs/remotes/git-svn &&
git update-ref refs/heads/svn-HEAD refs/remotes/git-svn &&
git update-ref -d refs/remotes/git-svn refs/remotes/git-svn
- "
+ '
head=`git rev-parse --verify refs/heads/git-svn-HEAD^0`
test_expect_success 'git-svn-HEAD is a real HEAD' "test -n '$head'"
-test_expect_success 'initialize old-style (v0) git-svn layout' "
- mkdir -p $GIT_DIR/git-svn/info $GIT_DIR/svn/info &&
- echo $svnrepo > $GIT_DIR/git-svn/info/url &&
- echo $svnrepo > $GIT_DIR/svn/info/url &&
+test_expect_success 'initialize old-style (v0) git-svn layout' '
+ mkdir -p "$GIT_DIR"/git-svn/info "$GIT_DIR"/svn/info &&
+ echo "$svnrepo" > "$GIT_DIR"/git-svn/info/url &&
+ echo "$svnrepo" > "$GIT_DIR"/svn/info/url &&
git-svn migrate &&
- ! test -d $GIT_DIR/git-svn &&
+ ! test -d "$GIT_DIR"/git-svn &&
git rev-parse --verify refs/remotes/git-svn^0 &&
git rev-parse --verify refs/remotes/svn^0 &&
- test \`git config --get svn-remote.svn.url\` = '$svnrepo' &&
- test \`git config --get svn-remote.svn.fetch\` = \
- ':refs/remotes/git-svn'
- "
+ test "$(git config --get svn-remote.svn.url)" = "$svnrepo" &&
+ test `git config --get svn-remote.svn.fetch` = \
+ ":refs/remotes/git-svn"
+ '
-test_expect_success 'initialize a multi-repository repo' "
- git-svn init $svnrepo -T trunk -t tags -b branches &&
+test_expect_success 'initialize a multi-repository repo' '
+ git-svn init "$svnrepo" -T trunk -t tags -b branches &&
git config --get-all svn-remote.svn.fetch > fetch.out &&
- grep '^trunk:refs/remotes/trunk$' fetch.out &&
- test -n \"\`git config --get svn-remote.svn.branches \
- '^branches/\*:refs/remotes/\*$'\`\" &&
- test -n \"\`git config --get svn-remote.svn.tags \
- '^tags/\*:refs/remotes/tags/\*$'\`\" &&
+ grep "^trunk:refs/remotes/trunk$" fetch.out &&
+ test -n "`git config --get svn-remote.svn.branches \
+ "^branches/\*:refs/remotes/\*$"`" &&
+ test -n "`git config --get svn-remote.svn.tags \
+ "^tags/\*:refs/remotes/tags/\*$"`" &&
git config --unset svn-remote.svn.branches \
- '^branches/\*:refs/remotes/\*$' &&
+ "^branches/\*:refs/remotes/\*$" &&
git config --unset svn-remote.svn.tags \
- '^tags/\*:refs/remotes/tags/\*$' &&
- git config --add svn-remote.svn.fetch 'branches/a:refs/remotes/a' &&
- git config --add svn-remote.svn.fetch 'branches/b:refs/remotes/b' &&
+ "^tags/\*:refs/remotes/tags/\*$" &&
+ git config --add svn-remote.svn.fetch "branches/a:refs/remotes/a" &&
+ git config --add svn-remote.svn.fetch "branches/b:refs/remotes/b" &&
for i in tags/0.1 tags/0.2 tags/0.3; do
git config --add svn-remote.svn.fetch \
- \$i:refs/remotes/\$i || exit 1; done
- "
+ $i:refs/remotes/$i || exit 1; done
+ '
# refs should all be different, but the trees should all be the same:
test_expect_success 'multi-fetch works on partial urls + paths' "
@@ -73,43 +73,43 @@ test_expect_success 'multi-fetch works on partial urls + paths' "
refs/remotes/\$j\`\" ||exit 1; done; done
"
-test_expect_success 'migrate --minimize on old inited layout' "
+test_expect_success 'migrate --minimize on old inited layout' '
git config --unset-all svn-remote.svn.fetch &&
git config --unset-all svn-remote.svn.url &&
- rm -rf $GIT_DIR/svn &&
- for i in \`cat fetch.out\`; do
- path=\`expr \$i : '\\([^:]*\\):.*$'\`
- ref=\`expr \$i : '[^:]*:refs/remotes/\\(.*\\)$'\`
- if test -z \"\$ref\"; then continue; fi
- if test -n \"\$path\"; then path=\"/\$path\"; fi
- ( mkdir -p $GIT_DIR/svn/\$ref/info/ &&
- echo $svnrepo\$path > $GIT_DIR/svn/\$ref/info/url ) || exit 1;
+ rm -rf "$GIT_DIR"/svn &&
+ for i in `cat fetch.out`; do
+ path=`expr $i : "\([^:]*\):.*$"`
+ ref=`expr $i : "[^:]*:refs/remotes/\(.*\)$"`
+ if test -z "$ref"; then continue; fi
+ if test -n "$path"; then path="/$path"; fi
+ ( mkdir -p "$GIT_DIR"/svn/$ref/info/ &&
+ echo "$svnrepo"$path > "$GIT_DIR"/svn/$ref/info/url ) || exit 1;
done &&
git-svn migrate --minimize &&
- test -z \"\`git config -l |grep -v '^svn-remote\.git-svn\.'\`\" &&
+ test -z "`git config -l |grep -v "^svn-remote\.git-svn\."`" &&
git config --get-all svn-remote.svn.fetch > fetch.out &&
- grep '^trunk:refs/remotes/trunk$' fetch.out &&
- grep '^branches/a:refs/remotes/a$' fetch.out &&
- grep '^branches/b:refs/remotes/b$' fetch.out &&
- grep '^tags/0\.1:refs/remotes/tags/0\.1$' fetch.out &&
- grep '^tags/0\.2:refs/remotes/tags/0\.2$' fetch.out &&
- grep '^tags/0\.3:refs/remotes/tags/0\.3$' fetch.out
- grep '^:refs/remotes/git-svn' fetch.out
- "
+ grep "^trunk:refs/remotes/trunk$" fetch.out &&
+ grep "^branches/a:refs/remotes/a$" fetch.out &&
+ grep "^branches/b:refs/remotes/b$" fetch.out &&
+ grep "^tags/0\.1:refs/remotes/tags/0\.1$" fetch.out &&
+ grep "^tags/0\.2:refs/remotes/tags/0\.2$" fetch.out &&
+ grep "^tags/0\.3:refs/remotes/tags/0\.3$" fetch.out
+ grep "^:refs/remotes/git-svn" fetch.out
+ '
-test_expect_success ".rev_db auto-converted to .rev_map.UUID" "
+test_expect_success ".rev_db auto-converted to .rev_map.UUID" '
git-svn fetch -i trunk &&
- test -z \"\$(ls $GIT_DIR/svn/trunk/.rev_db.* 2>/dev/null)\" &&
- expect=\"\$(ls $GIT_DIR/svn/trunk/.rev_map.*)\" &&
- test -n \"\$expect\" &&
- rev_db=\$(echo \$expect | sed -e 's,_map,_db,') &&
- convert_to_rev_db \$expect \$rev_db &&
- rm -f \$expect &&
- test -f \$rev_db &&
+ test -z "$(ls "$GIT_DIR"/svn/trunk/.rev_db.* 2>/dev/null)" &&
+ expect="$(ls "$GIT_DIR"/svn/trunk/.rev_map.*)" &&
+ test -n "$expect" &&
+ rev_db="$(echo $expect | sed -e "s,_map,_db,")" &&
+ convert_to_rev_db "$expect" "$rev_db" &&
+ rm -f "$expect" &&
+ test -f "$rev_db" &&
git-svn fetch -i trunk &&
- test -z \"\$(ls $GIT_DIR/svn/trunk/.rev_db.* 2>/dev/null)\" &&
- test ! -e $GIT_DIR/svn/trunk/.rev_db &&
- test -f \$expect
- "
+ test -z "$(ls "$GIT_DIR"/svn/trunk/.rev_db.* 2>/dev/null)" &&
+ test ! -e "$GIT_DIR"/svn/trunk/.rev_db &&
+ test -f "$expect"
+ '
test_done
diff --git a/t/t9108-git-svn-glob.sh b/t/t9108-git-svn-glob.sh
index db4344c..f6f71d0 100755
--- a/t/t9108-git-svn-glob.sh
+++ b/t/t9108-git-svn-glob.sh
@@ -10,77 +10,77 @@ start a new branch
initial
EOF
-test_expect_success 'test refspec globbing' "
+test_expect_success 'test refspec globbing' '
mkdir -p trunk/src/a trunk/src/b trunk/doc &&
- echo 'hello world' > trunk/src/a/readme &&
- echo 'goodbye world' > trunk/src/b/readme &&
- svn import -m 'initial' trunk $svnrepo/trunk &&
- svn co $svnrepo tmp &&
+ echo "hello world" > trunk/src/a/readme &&
+ echo "goodbye world" > trunk/src/b/readme &&
+ svn import -m "initial" trunk "$svnrepo"/trunk &&
+ svn co "$svnrepo" tmp &&
cd tmp &&
mkdir branches tags &&
svn add branches tags &&
svn cp trunk branches/start &&
- svn commit -m 'start a new branch' &&
+ svn commit -m "start a new branch" &&
svn up &&
- echo 'hi' >> branches/start/src/b/readme &&
+ echo "hi" >> branches/start/src/b/readme &&
poke branches/start/src/b/readme &&
- echo 'hey' >> branches/start/src/a/readme &&
+ echo "hey" >> branches/start/src/a/readme &&
poke branches/start/src/a/readme &&
- svn commit -m 'hi' &&
+ svn commit -m "hi" &&
svn up &&
svn cp branches/start tags/end &&
- echo 'bye' >> tags/end/src/b/readme &&
+ echo "bye" >> tags/end/src/b/readme &&
poke tags/end/src/b/readme &&
- echo 'aye' >> tags/end/src/a/readme &&
+ echo "aye" >> tags/end/src/a/readme &&
poke tags/end/src/a/readme &&
- svn commit -m 'the end' &&
- echo 'byebye' >> tags/end/src/b/readme &&
+ svn commit -m "the end" &&
+ echo "byebye" >> tags/end/src/b/readme &&
poke tags/end/src/b/readme &&
- svn commit -m 'nothing to see here'
+ svn commit -m "nothing to see here"
cd .. &&
- git config --add svn-remote.svn.url $svnrepo &&
+ git config --add svn-remote.svn.url "$svnrepo" &&
git config --add svn-remote.svn.fetch \
- 'trunk/src/a:refs/remotes/trunk' &&
+ "trunk/src/a:refs/remotes/trunk" &&
git config --add svn-remote.svn.branches \
- 'branches/*/src/a:refs/remotes/branches/*' &&
+ "branches/*/src/a:refs/remotes/branches/*" &&
git config --add svn-remote.svn.tags\
- 'tags/*/src/a:refs/remotes/tags/*' &&
+ "tags/*/src/a:refs/remotes/tags/*" &&
git-svn multi-fetch &&
git log --pretty=oneline refs/remotes/tags/end | \
- sed -e 's/^.\{41\}//' > output.end &&
+ sed -e "s/^.\{41\}//" > output.end &&
cmp expect.end output.end &&
- test \"\`git rev-parse refs/remotes/tags/end~1\`\" = \
- \"\`git rev-parse refs/remotes/branches/start\`\" &&
- test \"\`git rev-parse refs/remotes/branches/start~2\`\" = \
- \"\`git rev-parse refs/remotes/trunk\`\"
- "
+ test "`git rev-parse refs/remotes/tags/end~1`" = \
+ "`git rev-parse refs/remotes/branches/start`" &&
+ test "`git rev-parse refs/remotes/branches/start~2`" = \
+ "`git rev-parse refs/remotes/trunk`"
+ '
echo try to try > expect.two
echo nothing to see here >> expect.two
cat expect.end >> expect.two
-test_expect_success 'test left-hand-side only globbing' "
- git config --add svn-remote.two.url $svnrepo &&
+test_expect_success 'test left-hand-side only globbing' '
+ git config --add svn-remote.two.url "$svnrepo" &&
git config --add svn-remote.two.fetch trunk:refs/remotes/two/trunk &&
git config --add svn-remote.two.branches \
- 'branches/*:refs/remotes/two/branches/*' &&
+ "branches/*:refs/remotes/two/branches/*" &&
git config --add svn-remote.two.tags \
- 'tags/*:refs/remotes/two/tags/*' &&
+ "tags/*:refs/remotes/two/tags/*" &&
cd tmp &&
- echo 'try try' >> tags/end/src/b/readme &&
+ echo "try try" >> tags/end/src/b/readme &&
poke tags/end/src/b/readme &&
- svn commit -m 'try to try'
+ svn commit -m "try to try"
cd .. &&
git-svn fetch two &&
- test \`git rev-list refs/remotes/two/tags/end | wc -l\` -eq 6 &&
- test \`git rev-list refs/remotes/two/branches/start | wc -l\` -eq 3 &&
- test \`git rev-parse refs/remotes/two/branches/start~2\` = \
- \`git rev-parse refs/remotes/two/trunk\` &&
- test \`git rev-parse refs/remotes/two/tags/end~3\` = \
- \`git rev-parse refs/remotes/two/branches/start\` &&
+ test `git rev-list refs/remotes/two/tags/end | wc -l` -eq 6 &&
+ test `git rev-list refs/remotes/two/branches/start | wc -l` -eq 3 &&
+ test `git rev-parse refs/remotes/two/branches/start~2` = \
+ `git rev-parse refs/remotes/two/trunk` &&
+ test `git rev-parse refs/remotes/two/tags/end~3` = \
+ `git rev-parse refs/remotes/two/branches/start` &&
git log --pretty=oneline refs/remotes/two/tags/end | \
- sed -e 's/^.\{41\}//' > output.two &&
+ sed -e "s/^.\{41\}//" > output.two &&
cmp expect.two output.two
- "
+ '
test_done
diff --git a/t/t9110-git-svn-use-svm-props.sh b/t/t9110-git-svn-use-svm-props.sh
index 6235af4..047659f 100755
--- a/t/t9110-git-svn-use-svm-props.sh
+++ b/t/t9110-git-svn-use-svm-props.sh
@@ -7,15 +7,15 @@ test_description='git-svn useSvmProps test'
. ./lib-git-svn.sh
-test_expect_success 'load svm repo' "
- svnadmin load -q $rawsvnrepo < ../t9110/svm.dump &&
- git-svn init --minimize-url -R arr -i bar $svnrepo/mirror/arr &&
- git-svn init --minimize-url -R argh -i dir $svnrepo/mirror/argh &&
+test_expect_success 'load svm repo' '
+ svnadmin load -q "$rawsvnrepo" < ../t9110/svm.dump &&
+ git-svn init --minimize-url -R arr -i bar "$svnrepo"/mirror/arr &&
+ git-svn init --minimize-url -R argh -i dir "$svnrepo"/mirror/argh &&
git-svn init --minimize-url -R argh -i e \
- $svnrepo/mirror/argh/a/b/c/d/e &&
+ "$svnrepo"/mirror/argh/a/b/c/d/e &&
git config svn.useSvmProps true &&
git-svn fetch --all
- "
+ '
uuid=161ce429-a9dd-4828-af4a-52023f968c89
diff --git a/t/t9111-git-svn-use-svnsync-props.sh b/t/t9111-git-svn-use-svnsync-props.sh
index ec7dedd..a8d74dc 100755
--- a/t/t9111-git-svn-use-svnsync-props.sh
+++ b/t/t9111-git-svn-use-svnsync-props.sh
@@ -7,14 +7,14 @@ test_description='git-svn useSvnsyncProps test'
. ./lib-git-svn.sh
-test_expect_success 'load svnsync repo' "
- svnadmin load -q $rawsvnrepo < ../t9111/svnsync.dump &&
- git-svn init --minimize-url -R arr -i bar $svnrepo/bar &&
- git-svn init --minimize-url -R argh -i dir $svnrepo/dir &&
- git-svn init --minimize-url -R argh -i e $svnrepo/dir/a/b/c/d/e &&
+test_expect_success 'load svnsync repo' '
+ svnadmin load -q "$rawsvnrepo" < ../t9111/svnsync.dump &&
+ git-svn init --minimize-url -R arr -i bar "$svnrepo"/bar &&
+ git-svn init --minimize-url -R argh -i dir "$svnrepo"/dir &&
+ git-svn init --minimize-url -R argh -i e "$svnrepo"/dir/a/b/c/d/e &&
git config svn.useSvnsyncProps true &&
git-svn fetch --all
- "
+ '
uuid=161ce429-a9dd-4828-af4a-52023f968c89
diff --git a/t/t9112-git-svn-md5less-file.sh b/t/t9112-git-svn-md5less-file.sh
index 646a5f0..d470a92 100755
--- a/t/t9112-git-svn-md5less-file.sh
+++ b/t/t9112-git-svn-md5less-file.sh
@@ -40,8 +40,8 @@ PROPS-END
EOF
-test_expect_success 'load svn dumpfile' "svnadmin load $rawsvnrepo < dumpfile.svn"
+test_expect_success 'load svn dumpfile' 'svnadmin load "$rawsvnrepo" < dumpfile.svn'
-test_expect_success 'initialize git-svn' "git-svn init $svnrepo"
+test_expect_success 'initialize git-svn' 'git-svn init "$svnrepo"'
test_expect_success 'fetch revisions from svn' 'git-svn fetch'
test_done
diff --git a/t/t9113-git-svn-dcommit-new-file.sh b/t/t9113-git-svn-dcommit-new-file.sh
index 9ef0db9..31c929b 100755
--- a/t/t9113-git-svn-dcommit-new-file.sh
+++ b/t/t9113-git-svn-dcommit-new-file.sh
@@ -15,18 +15,18 @@ test_description='git-svn dcommit new files over svn:// test'
start_svnserve () {
svnserve --listen-port $SVNSERVE_PORT \
- --root $rawsvnrepo \
+ --root "$rawsvnrepo" \
--listen-once \
--listen-host 127.0.0.1 &
}
-test_expect_success 'start tracking an empty repo' "
- svn mkdir -m 'empty dir' $svnrepo/empty-dir &&
- echo anon-access = write >> $rawsvnrepo/conf/svnserve.conf &&
+test_expect_success 'start tracking an empty repo' '
+ svn mkdir -m "empty dir" "$svnrepo"/empty-dir &&
+ echo anon-access = write >> "$rawsvnrepo"/conf/svnserve.conf &&
start_svnserve &&
git svn init svn://127.0.0.1:$SVNSERVE_PORT &&
git svn fetch
- "
+ '
test_expect_success 'create files in new directory with dcommit' "
mkdir git-new-dir &&
diff --git a/t/t9114-git-svn-dcommit-merge.sh b/t/t9114-git-svn-dcommit-merge.sh
index 225060b..61d7781 100755
--- a/t/t9114-git-svn-dcommit-merge.sh
+++ b/t/t9114-git-svn-dcommit-merge.sh
@@ -34,35 +34,35 @@ cat << EOF
EOF
}
-test_expect_success 'setup svn repository' "
- svn co $svnrepo mysvnwork &&
+test_expect_success 'setup svn repository' '
+ svn co "$svnrepo" mysvnwork &&
mkdir -p mysvnwork/trunk &&
cd mysvnwork &&
big_text_block >> trunk/README &&
svn add trunk &&
- svn ci -m 'first commit' trunk &&
+ svn ci -m "first commit" trunk &&
cd ..
- "
+ '
-test_expect_success 'setup git mirror and merge' "
- git svn init $svnrepo -t tags -T trunk -b branches &&
+test_expect_success 'setup git mirror and merge' '
+ git svn init "$svnrepo" -t tags -T trunk -b branches &&
git svn fetch &&
git checkout --track -b svn remotes/trunk &&
git checkout -b merge &&
echo new file > new_file &&
git add new_file &&
- git commit -a -m 'New file' &&
+ git commit -a -m "New file" &&
echo hello >> README &&
- git commit -a -m 'hello' &&
+ git commit -a -m "hello" &&
echo add some stuff >> new_file &&
- git commit -a -m 'add some stuff' &&
+ git commit -a -m "add some stuff" &&
git checkout svn &&
mv -f README tmp &&
echo friend > README &&
cat tmp >> README &&
- git commit -a -m 'friend' &&
+ git commit -a -m "friend" &&
git pull . merge
- "
+ '
test_debug 'gitk --all & sleep 1'
diff --git a/t/t9115-git-svn-dcommit-funky-renames.sh b/t/t9115-git-svn-dcommit-funky-renames.sh
index 182299c..298445f 100755
--- a/t/t9115-git-svn-dcommit-funky-renames.sh
+++ b/t/t9115-git-svn-dcommit-funky-renames.sh
@@ -7,16 +7,16 @@ test_description='git-svn dcommit can commit renames of files with ugly names'
. ./lib-git-svn.sh
-test_expect_success 'load repository with strange names' "
- svnadmin load -q $rawsvnrepo < ../t9115/funky-names.dump &&
+test_expect_success 'load repository with strange names' '
+ svnadmin load -q "$rawsvnrepo" < ../t9115/funky-names.dump &&
start_httpd
- "
+ '
-test_expect_success 'init and fetch repository' "
- git svn init $svnrepo &&
+test_expect_success 'init and fetch repository' '
+ git svn init "$svnrepo" &&
git svn fetch &&
git reset --hard git-svn
- "
+ '
test_expect_success 'create file in existing ugly and empty dir' '
mkdir "#{bad_directory_name}" &&
diff --git a/t/t9116-git-svn-log.sh b/t/t9116-git-svn-log.sh
index e1e8bdf..4b2cc87 100755
--- a/t/t9116-git-svn-log.sh
+++ b/t/t9116-git-svn-log.sh
@@ -6,17 +6,17 @@
test_description='git-svn log tests'
. ./lib-git-svn.sh
-test_expect_success 'setup repository and import' "
+test_expect_success 'setup repository and import' '
mkdir import &&
cd import &&
for i in trunk branches/a branches/b \
tags/0.1 tags/0.2 tags/0.3; do
- mkdir -p \$i && \
- echo hello >> \$i/README || exit 1
+ mkdir -p $i && \
+ echo hello >> $i/README || exit 1
done && \
- svn import -m test . $svnrepo
+ svn import -m test . "$svnrepo"
cd .. &&
- git-svn init $svnrepo -T trunk -b branches -t tags &&
+ git-svn init "$svnrepo" -T trunk -b branches -t tags &&
git-svn fetch &&
git reset --hard trunk &&
echo bye >> README &&
@@ -37,7 +37,7 @@ test_expect_success 'setup repository and import' "
echo try >> README &&
git commit -a -m try &&
git svn dcommit
- "
+ '
test_expect_success 'run log' "
git reset --hard a &&
diff --git a/t/t9117-git-svn-init-clone.sh b/t/t9117-git-svn-init-clone.sh
index d482b40..7a689bb 100755
--- a/t/t9117-git-svn-init-clone.sh
+++ b/t/t9117-git-svn-init-clone.sh
@@ -13,43 +13,43 @@ rm -r .git
mkdir tmp
cd tmp
-test_expect_success 'setup svnrepo' "
+test_expect_success 'setup svnrepo' '
mkdir project project/trunk project/branches project/tags &&
echo foo > project/trunk/foo &&
- svn import -m '$test_description' project $svnrepo/project &&
+ svn import -m "$test_description" project "$svnrepo"/project &&
rm -rf project
- "
+ '
-test_expect_success 'basic clone' "
+test_expect_success 'basic clone' '
test ! -d trunk &&
- git svn clone $svnrepo/project/trunk &&
+ git svn clone "$svnrepo"/project/trunk &&
test -d trunk/.git/svn &&
test -e trunk/foo &&
rm -rf trunk
- "
+ '
-test_expect_success 'clone to target directory' "
+test_expect_success 'clone to target directory' '
test ! -d target &&
- git svn clone $svnrepo/project/trunk target &&
+ git svn clone "$svnrepo"/project/trunk target &&
test -d target/.git/svn &&
test -e target/foo &&
rm -rf target
- "
+ '
-test_expect_success 'clone with --stdlayout' "
+test_expect_success 'clone with --stdlayout' '
test ! -d project &&
- git svn clone -s $svnrepo/project &&
+ git svn clone -s "$svnrepo"/project &&
test -d project/.git/svn &&
test -e project/foo &&
rm -rf project
- "
+ '
-test_expect_success 'clone to target directory with --stdlayout' "
+test_expect_success 'clone to target directory with --stdlayout' '
test ! -d target &&
- git svn clone -s $svnrepo/project target &&
+ git svn clone -s "$svnrepo"/project target &&
test -d target/.git/svn &&
test -e target/foo &&
rm -rf target
- "
+ '
test_done
diff --git a/t/t9118-git-svn-funky-branch-names.sh b/t/t9118-git-svn-funky-branch-names.sh
index 640bb06..3281cbd 100755
--- a/t/t9118-git-svn-funky-branch-names.sh
+++ b/t/t9118-git-svn-funky-branch-names.sh
@@ -6,25 +6,25 @@
test_description='git-svn funky branch names'
. ./lib-git-svn.sh
-test_expect_success 'setup svnrepo' "
+test_expect_success 'setup svnrepo' '
mkdir project project/trunk project/branches project/tags &&
echo foo > project/trunk/foo &&
- svn import -m '$test_description' project \"$svnrepo/pr ject\" &&
+ svn import -m "$test_description" project "$svnrepo/pr ject" &&
rm -rf project &&
- svn cp -m 'fun' \"$svnrepo/pr ject/trunk\" \
- \"$svnrepo/pr ject/branches/fun plugin\" &&
- svn cp -m 'more fun!' \"$svnrepo/pr ject/branches/fun plugin\" \
- \"$svnrepo/pr ject/branches/more fun plugin!\" &&
+ svn cp -m "fun" "$svnrepo/pr ject/trunk" \
+ "$svnrepo/pr ject/branches/fun plugin" &&
+ svn cp -m "more fun!" "$svnrepo/pr ject/branches/fun plugin" \
+ "$svnrepo/pr ject/branches/more fun plugin!" &&
start_httpd
- "
+ '
-test_expect_success 'test clone with funky branch names' "
- git svn clone -s \"$svnrepo/pr ject\" project &&
+test_expect_success 'test clone with funky branch names' '
+ git svn clone -s "$svnrepo/pr ject" project &&
cd project &&
- git rev-parse 'refs/remotes/fun%20plugin' &&
- git rev-parse 'refs/remotes/more%20fun%20plugin!' &&
+ git rev-parse "refs/remotes/fun%20plugin" &&
+ git rev-parse "refs/remotes/more%20fun%20plugin!" &&
cd ..
- "
+ '
test_expect_success 'test dcommit to funky branch' "
cd project &&
diff --git a/t/t9120-git-svn-clone-with-percent-escapes.sh b/t/t9120-git-svn-clone-with-percent-escapes.sh
index 9a4eabe..5979e13 100755
--- a/t/t9120-git-svn-clone-with-percent-escapes.sh
+++ b/t/t9120-git-svn-clone-with-percent-escapes.sh
@@ -6,13 +6,13 @@
test_description='git-svn clone with percent escapes'
. ./lib-git-svn.sh
-test_expect_success 'setup svnrepo' "
+test_expect_success 'setup svnrepo' '
mkdir project project/trunk project/branches project/tags &&
echo foo > project/trunk/foo &&
- svn import -m '$test_description' project '$svnrepo/pr ject' &&
+ svn import -m "$test_description" project "$svnrepo/pr ject" &&
rm -rf project &&
start_httpd
-"
+'
if test "$SVN_HTTPD_PORT" = ""
then
diff --git a/t/t9500-gitweb-standalone-no-errors.sh b/t/t9500-gitweb-standalone-no-errors.sh
index 3dc261d..ae7082b 100755
--- a/t/t9500-gitweb-standalone-no-errors.sh
+++ b/t/t9500-gitweb-standalone-no-errors.sh
@@ -10,6 +10,7 @@ commandline, and checks that it would not write any errors
or warnings to log.'
gitweb_init () {
+ safe_pwd="$(perl -MPOSIX=getcwd -e 'print quotemeta(getcwd)')"
cat >gitweb_config.perl <<EOF
#!/usr/bin/perl
@@ -17,16 +18,16 @@ gitweb_init () {
our \$version = "current";
our \$GIT = "git";
-our \$projectroot = "$(pwd)";
+our \$projectroot = "$safe_pwd";
our \$project_maxdepth = 8;
our \$home_link_str = "projects";
our \$site_name = "[localhost]";
our \$site_header = "";
our \$site_footer = "";
our \$home_text = "indextext.html";
-our @stylesheets = ("file:///$(pwd)/../../gitweb/gitweb.css");
-our \$logo = "file:///$(pwd)/../../gitweb/git-logo.png";
-our \$favicon = "file:///$(pwd)/../../gitweb/git-favicon.png";
+our @stylesheets = ("file:///$safe_pwd/../../gitweb/gitweb.css");
+our \$logo = "file:///$safe_pwd/../../gitweb/git-logo.png";
+our \$favicon = "file:///$safe_pwd/../../gitweb/git-favicon.png";
our \$projects_list = "";
our \$export_ok = "";
our \$strict_export = "";
@@ -53,7 +54,7 @@ gitweb_run () {
# written to web server logs, so we are not interested in that:
# we are interested only in properly formatted errors/warnings
rm -f gitweb.log &&
- perl -- $(pwd)/../../gitweb/gitweb.perl \
+ perl -- "$(pwd)/../../gitweb/gitweb.perl" \
>/dev/null 2>gitweb.log &&
if grep -q -s "^[[]" gitweb.log >/dev/null; then false; else true; fi
--
1.5.5.1.128.g03a943
^ permalink raw reply related [relevance 8%]
Results 1-200 of ~5000 next (newer) | reverse | options above
-- pct% links below jump to the message on this page, permalinks otherwise --
2005-05-09 16:29 2% Git-aware Darcs: a tutorial Juliusz Chroboczek
2005-07-03 23:46 [ANNOUNCE] Cogito-0.12 Petr Baudis
2005-07-06 12:01 ` Brian Gerst
2005-07-07 14:45 ` Petr Baudis
2005-07-07 17:21 ` Junio C Hamano
2005-07-07 19:04 ` Linus Torvalds
2005-07-07 22:14 ` Petr Baudis
2005-07-07 22:52 ` Linus Torvalds
2005-07-07 23:16 ` [PATCH] Pull efficiently from a dumb git store Junio C Hamano
2005-07-07 23:50 ` [PATCH] rev-list: add "--objects=self-sufficient" flag Junio C Hamano
2005-07-07 23:58 ` Linus Torvalds
2005-07-08 1:02 ` [PATCH] rev-list: add "--full-objects" flag Junio C Hamano
2005-07-08 1:46 ` Linus Torvalds
2005-07-08 2:17 ` Junio C Hamano
2005-07-08 2:39 ` Linus Torvalds
2005-07-09 21:09 ` Eric W. Biederman
2005-07-10 22:36 ` Linus Torvalds
2005-07-11 15:19 ` Eric W. Biederman
2005-07-11 16:38 1% ` Linus Torvalds
2005-07-14 7:08 [PATCH] Documentation: packed GIT support commands Junio C Hamano
2005-07-15 7:59 ` [PATCH] Documentation: update tutorial to talk about push Junio C Hamano
2005-07-15 21:40 ` [PATCH] fetch/pull: support Cogito-style remote branch information Junio C Hamano
2005-07-15 22:42 ` Linus Torvalds
2005-07-16 7:16 3% ` [PATCH] fetch/pull: short-hand notation for remote repositories Junio C Hamano
2005-08-18 7:24 Multi-head pulling series Junio C Hamano
2005-08-18 7:39 6% ` [PATCH 1/3] Start adding the $GIT_DIR/remotes/ support Junio C Hamano
2005-08-20 18:13 Updated multi-head downloads and " Junio C Hamano
2005-08-20 18:22 6% ` [PATCH] Start adding the " Junio C Hamano
2005-09-19 3:18 [BUG] git-show-branch cant show --more Jon Loeliger
2005-09-19 8:12 3% ` Junio C Hamano
2005-09-26 22:23 Cogito: cg-clone doesn't like packed tag objects Junio C Hamano
2005-09-26 22:37 ` Junio C Hamano
2005-09-23 22:24 ` H. Peter Anvin
2005-09-24 1:18 ` Petr Baudis
2005-09-26 21:25 ` Petr Baudis
2005-09-26 22:29 ` Petr Baudis
2005-09-27 4:46 ` Junio C Hamano
2005-09-27 5:02 ` Tom Prince
2005-09-27 5:28 ` Junio C Hamano
2005-09-27 9:40 ` Petr Baudis
2005-09-27 17:07 ` Junio C Hamano
2005-09-27 17:56 3% ` Linus Torvalds
2005-09-27 18:36 2% ` Junio C Hamano
2005-10-03 0:12 3% GIT 0.99.8 Junio C Hamano
2005-10-25 21:34 7% [WIP] Implement a test for git-fetch-pack Johannes Schindelin
2005-10-31 18:23 git push sends more objects than it needs to Luck, Tony
2005-10-31 18:44 ` Linus Torvalds
2005-10-31 19:36 2% ` Linus Torvalds
2005-11-01 0:25 git versus CVS (versus bk) Theodore Ts'o
2005-11-01 9:23 ` hgmq vs. StGIT Catalin Marinas
2005-11-01 15:20 ` Chuck Lever
2005-11-01 15:36 ` Chris Mason
2005-11-01 17:18 ` Catalin Marinas
2005-11-01 18:13 ` Chris Mason
2005-11-01 21:30 ` Catalin Marinas
2005-11-02 15:41 ` Chris Mason
2005-11-05 20:23 ` Catalin Marinas
2005-11-09 23:32 ` Petr Baudis
2005-11-10 16:20 3% ` Catalin Marinas
2005-11-16 12:24 [QUESTION] Access to a huge GIT repository Franck
2005-11-17 10:36 ` Franck
2005-11-17 16:23 ` Linus Torvalds
2005-11-17 21:47 ` Franck
2005-11-17 22:44 ` Linus Torvalds
2005-11-19 12:23 ` Franck
2005-11-19 17:56 ` Linus Torvalds
2005-11-19 19:52 ` Junio C Hamano
2005-11-21 20:11 ` Franck
2005-11-21 20:45 ` Junio C Hamano
2005-11-22 9:22 ` Franck
2005-11-22 9:50 3% ` Junio C Hamano
2005-11-22 10:40 0% ` Franck
2005-12-04 21:34 git-name-rev off-by-one bug Petr Baudis
2005-12-08 6:34 1% ` as promised, docs: git for the confused linux
[not found] <7vbqzrcmgr.fsf@assigned-by-dhcp.cox.net>
2005-12-09 5:44 1% ` linux
2005-12-15 0:44 How to clone-pack the HEAD? Petr Baudis
2005-12-15 1:20 ` Junio C Hamano
2005-12-15 1:32 ` Petr Baudis
2005-12-15 1:45 ` Junio C Hamano
2005-12-15 1:53 ` Junio C Hamano
2005-12-15 5:29 8% ` Junio C Hamano
2006-01-30 7:18 4% [RFC] shallow clone Junio C Hamano
[not found] ` <43DF1F1D.1060704@innova-card.com>
2006-01-31 9:00 1% ` Franck
2006-02-11 4:31 Make "git clone" less of a deathly quiet experience Linus Torvalds
2006-02-11 5:48 ` Junio C Hamano
2006-02-11 7:35 4% ` Craig Schlenter
2006-02-11 8:44 1% ` Radoslaw Szkodzinski
2006-02-11 13:05 2% ` Petr Baudis
2006-02-14 16:28 several quick questions Nicolas Vilz 'niv'
2006-02-14 17:05 ` Linus Torvalds
2006-02-14 18:10 ` Carl Worth
2006-02-14 18:55 ` Keith Packard
2006-02-14 19:04 ` Linus Torvalds
2006-02-14 19:39 ` Keith Packard
2006-02-15 4:11 ` Martin Langhoff
2006-02-15 5:25 ` Keith Packard
2006-02-15 8:21 3% ` Carl Worth
2006-02-16 6:57 3% What's in git.git Junio C Hamano
2006-02-16 7:38 1% [ANNOUNCE] git-svn - bidirection operations between svn and git Eric Wong
2006-02-16 13:42 ` Eduardo Pereira Habkost
2006-02-16 19:25 2% ` Eric Wong
2006-02-26 0:19 1% [PATCH] First cut at libifying revlist generation Linus Torvalds
2006-04-02 10:41 Solaris cloning woes partly diagnosed Junio C Hamano
2006-04-02 18:33 4% ` Linus Torvalds
2006-04-02 19:18 1% ` Linus Torvalds
2006-04-04 18:21 1% ` H. Peter Anvin
2006-04-02 19:10 Jason Riedy
2006-04-02 19:22 4% ` Linus Torvalds
2006-04-13 22:01 6% [PATCH] Shell utilities: Guard against expr' magic tokens Mark Wooding
2006-04-18 21:55 1% [Announce] GIT 1.3.0 Junio C Hamano
2006-04-28 1:59 1% PATCH: New diff-delta.c implementation (updated) Geert Bosch
2006-06-06 18:51 5% [REGRESSION] Interrupted clone/fetch leaves .lock files around Jonas Fonseca
2006-06-09 2:17 Figured out how to get Mozilla into git Jon Smirl
2006-06-09 3:06 ` Martin Langhoff
2006-06-09 3:28 ` Jon Smirl
2006-06-09 7:17 ` Jakub Narebski
2006-06-09 15:01 3% ` Linus Torvalds
2006-06-09 18:13 ` Jon Smirl
2006-06-09 19:00 ` Linus Torvalds
2006-06-09 20:17 3% ` Jon Smirl
2006-06-09 20:44 4% ` Jakub Narebski
2006-06-09 21:05 0% ` Nicolas Pitre
2006-06-09 21:46 0% ` Jon Smirl
2006-06-10 1:23 0% ` Martin Langhoff
2006-06-10 8:58 6% Lazy clone ideas Jakub Narebski
2006-06-11 20:37 1% [PATCH] The name of the hash is SHA-1, use it consistently in Documentation Horst H. von Brand
2006-06-24 16:18 [RFC] GIT user survey Paolo Ciarrocchi
2006-06-24 21:55 ` Adrien Beau
2006-06-24 22:15 ` Matthias Kestenholz
2006-06-29 9:49 4% ` Jakub Narebski
2006-07-28 6:36 Java GIT/Eclipse GIT version 0.1.1 Shawn Pearce
2006-07-28 6:49 1% ` Peter Baumann
2006-07-28 7:08 1% ` Pavel Roskin
2006-07-28 7:23 0% ` Peter Baumann
2006-07-29 3:32 1% ` Shawn Pearce
2006-08-09 10:24 2% [PATCH] Workaround for strange cmp bug Johannes Schindelin
2006-08-14 3:37 Compression and dictionaries Jon Smirl
2006-08-14 12:33 ` Johannes Schindelin
2006-08-14 14:08 ` Jon Smirl
2006-08-14 15:14 ` Alex Riesen
2006-08-14 15:26 1% ` Johannes Schindelin
2006-08-18 8:45 [PATCH] git-apply: document remaining options in the man page Jonas Fonseca
2006-08-18 9:43 ` Junio C Hamano
2006-08-25 0:56 ` [PATCH 1/7] git-apply(1): document missing options and improve existing ones Jonas Fonseca
2006-08-25 0:58 ` [PATCH 2/7] git-ls-remote(1): document --upload-pack Jonas Fonseca
2006-08-25 1:01 ` [PATCH 3/7] git-blame(1): mention options in the synopsis and advertise pickaxe Jonas Fonseca
2006-08-25 1:04 ` [PATCH 4/7] gitk(1): expand the manpage to look less like a template Jonas Fonseca
2006-08-25 1:05 ` [PATCH 5/7] git(7): put the synopsis in a verse style paragraph Jonas Fonseca
2006-08-25 1:06 ` [PATCH 6/7] gitview.txt: improve asciidoc markup Jonas Fonseca
2006-08-25 1:07 7% ` [PATCH 7/7] git-svn(1): " Jonas Fonseca
2006-08-18 22:42 git clone dies (large git repository) Troy Telford
2006-08-19 20:46 4% ` Junio C Hamano
2006-09-02 14:31 Mozilla version control requirements and git Jon Smirl
2006-09-03 1:19 ` Martin Langhoff
2006-09-03 3:29 4% ` Jon Smirl
[not found] <64c62cc942e872b29d7225999e74a07be586674a.1157610743.git.peff@peff.net>
2006-09-07 6:36 2% ` [PATCH 3/3] git-commit.sh: convert run_status to a C builtin Jeff King
2006-09-07 19:52 Change set based shallow clone Jon Smirl
2006-09-07 22:07 ` Junio C Hamano
2006-09-08 3:54 ` Martin Langhoff
2006-09-08 5:30 ` Junio C Hamano
2006-09-08 14:20 5% ` Jon Smirl
2006-09-08 15:50 ` Jakub Narebski
2006-09-09 3:13 4% ` Petr Baudis
2006-09-09 8:39 3% ` Jakub Narebski
2006-09-08 2:23 Jon Smirl
2006-09-08 18:42 ` linux
2006-09-08 21:13 ` Jon Smirl
2006-09-08 23:09 6% ` Linus Torvalds
2006-09-08 8:05 2% [PATCH] git-commit.sh: convert run_status to a C builtin Jeff King
2006-09-24 22:42 4% [PATCH] branch: write branch properties Santi Béjar
2006-09-24 23:00 4% ` Santi Béjar
2006-09-25 0:41 4% ` Santi Béjar
2006-10-14 15:07 VCS comparison table Jon Smirl
2006-10-14 16:40 ` Jakub Narebski
2006-10-16 22:26 ` Aaron Bentley
2006-10-16 23:35 ` Linus Torvalds
2006-10-17 4:24 ` Aaron Bentley
2006-10-17 10:23 ` Sean
2006-10-17 19:51 ` Aaron Bentley
2006-10-21 18:58 3% ` Jan Hudec
[not found] ` <20061021150233.c29e11c5.seanlkml@sympatico.ca>
2006-10-21 19:02 1% ` Sean
2006-10-21 19:02 1% ` Sean
2006-10-14 20:20 2% ` Jakub Narebski
2006-10-14 23:06 0% ` Jon Smirl
2006-10-15 0:03 ` Sean
2006-10-15 0:34 ` Jon Smirl
[not found] ` <20061014214452.8c2d2a5c.seanlkml@sympatico.ca>
2006-10-15 1:44 1% ` Sean
2006-10-15 0:53 1% ` Jakub Narebski
2006-10-15 18:23 0% ` Petr Baudis
2006-10-20 13:17 ` Jakub Narebski
2006-10-20 14:59 ` James Henstridge
2006-10-20 22:50 3% ` Jakub Narebski
2006-10-22 18:53 Matthew D. Fuller
2006-10-23 17:29 ` Linus Torvalds
2006-10-23 22:21 ` Matthew D. Fuller
2006-10-23 22:44 ` Linus Torvalds
2006-10-24 0:26 ` Matthew D. Fuller
2006-10-24 15:58 ` David Lang
2006-10-24 16:34 ` Matthew D. Fuller
2006-10-24 18:03 ` David Lang
2006-10-25 0:27 ` Matthew D. Fuller
2006-10-25 22:40 ` David Lang
2006-10-25 23:53 ` Matthew D. Fuller
2006-10-26 10:13 ` Andreas Ericsson
2006-10-26 11:48 4% ` Jakub Narebski
2006-10-27 19:42 5% [PATCH] enhance clone and fetch -k experience Nicolas Pitre
2006-11-02 0:53 1% What's in git.git Junio C Hamano
2006-11-08 3:21 Junio C Hamano
2006-11-08 4:13 2% ` David Lang
2006-11-08 16:40 1% ` Shallow clone [Was Re: What's in git.git ] Aneesh Kumar K.V
2006-11-08 17:59 1% ` Aneesh Kumar K.V
2006-11-09 4:04 ` Shallow clone Junio C Hamano
2006-11-11 13:57 ` Alexandre Julliard
2006-11-12 8:16 ` Junio C Hamano
2006-11-12 17:59 5% ` Sergey Vlasov
2006-11-12 21:59 1% ` Junio C Hamano
2006-11-13 5:29 1% ` Junio C Hamano
2006-11-09 2:28 0% ` What's in git.git Horst H. von Brand
2006-11-09 2:54 0% ` Junio C Hamano
2006-11-09 3:45 0% ` Dave Dillow
2006-11-12 22:25 3% ` Johannes Schindelin
2006-11-12 15:44 should git download missing objects? Anand Kumria
2006-11-12 19:41 2% ` Junio C Hamano
2006-11-14 16:42 [PATCH] commit: Steer new users toward "git commit -a" rather than update-index Carl Worth
2006-11-14 18:55 ` Andy Whitcroft
2006-11-14 19:22 ` Cleaning up git user-interface warts Carl Worth
2006-11-14 19:47 ` Petr Baudis
2006-11-14 20:56 ` Carl Worth
2006-11-15 0:31 ` Junio C Hamano
2006-11-15 20:51 2% ` Carl Worth
2006-11-15 7:43 1% [ANNOUNCE] GIT 1.4.4 Junio C Hamano
2006-11-25 10:12 3% What's in git.git Junio C Hamano
2006-11-27 0:44 2% [PATCH] (experimental) per-topic shortlog Junio C Hamano
2006-11-30 17:06 [RFC] Submodules in GIT Martin Waitz
2006-12-01 17:08 ` sf
2006-12-01 20:13 ` Linus Torvalds
2006-12-01 22:06 ` Josef Weidendorfer
2006-12-01 22:12 ` Martin Waitz
2006-12-01 22:26 ` Josef Weidendorfer
2006-12-01 22:40 2% ` Martin Waitz
2006-12-01 22:26 4% ` Linus Torvalds
2006-12-01 22:41 ` sf
2006-12-01 23:09 ` Linus Torvalds
2006-12-01 23:49 3% ` sf
2006-12-02 18:57 1% ` Torgil Svensson
2006-12-02 19:41 ` Linus Torvalds
2006-12-03 9:19 ` Torgil Svensson
2006-12-03 17:54 3% ` Linus Torvalds
2006-12-01 22:55 1% ` Josef Weidendorfer
2006-12-14 23:07 ` Josef Weidendorfer
2006-12-15 17:43 ` Torgil Svensson
2006-12-15 21:42 ` Josef Weidendorfer
2006-12-15 23:43 ` Torgil Svensson
2006-12-16 1:13 ` Torgil Svensson
2006-12-16 1:20 ` Torgil Svensson
2006-12-16 1:34 ` Jakub Narebski
2006-12-16 8:40 ` Torgil Svensson
2006-12-16 9:57 2% ` Jakub Narebski
2006-12-16 15:05 2% ` Torgil Svensson
2006-12-04 19:08 [RFC] Two conceptually distinct commit commands Carl Worth
2006-12-06 1:13 ` Junio C Hamano
2006-12-06 4:53 ` Carl Worth
2006-12-06 18:31 ` Junio C Hamano
2006-12-06 23:29 1% ` Carl Worth
2006-12-04 20:41 [RFC] Submodules in GIT Linus Torvalds
2006-12-04 21:36 ` Torgil Svensson
2006-12-05 10:42 ` Andreas Ericsson
2006-12-05 11:09 5% ` Jakub Narebski
2006-12-10 19:51 [RFC \ WISH] Add -o option to git-rev-list Marco Costalba
2006-12-10 20:00 4% ` globs in partial checkout? Michael S. Tsirkin
2006-12-10 20:13 3% ` Linus Torvalds
2006-12-14 23:08 git-fetch fails with error code 128 Andy Parkins
2006-12-15 9:46 ` Andy Parkins
2006-12-15 21:55 ` Junio C Hamano
2006-12-16 22:12 5% ` Andy Parkins
2006-12-16 18:32 Subprojects tasks Junio C Hamano
2006-12-17 0:01 ` Josef Weidendorfer
2006-12-17 11:45 ` Martin Waitz
2006-12-17 13:01 3% ` Jakub Narebski
2006-12-17 13:48 0% ` Martin Waitz
2006-12-27 7:39 [RFH] An early draft of v1.5.0 release notes Junio C Hamano
2006-12-28 1:45 ` An early draft of v1.5.0 release notes (2nd ed) Junio C Hamano
2007-01-10 7:58 6% ` An early draft of v1.5.0 release notes (3rd ed) Junio C Hamano
2007-01-02 0:08 3% Draft v1.5.0 release notes Junio C Hamano
2007-01-09 21:35 Howto use StGit and git-svn at same time Guilhem Bonnefille
2007-01-09 21:41 ` Guilhem Bonnefille
2007-01-09 22:41 ` Yann Dirson
2007-01-15 13:26 ` Guilhem Bonnefille
2007-01-15 20:24 ` Rebasing stgit stacks Yann Dirson
2007-01-15 22:46 ` Catalin Marinas
2007-01-15 23:39 ` Yann Dirson
2007-01-16 22:42 4% ` Catalin Marinas
2007-01-16 23:17 1% ` Yann Dirson
2007-01-15 3:44 6% [PATCH] some doc updates Nicolas Pitre
2007-01-21 8:56 [Announce] GIT v1.5.0-rc2 Junio C Hamano
2007-01-21 11:20 2% ` Junio C Hamano
2007-01-21 19:46 0% ` Horst H. von Brand
2007-01-22 18:08 1% ` Carl Worth
2007-01-25 12:50 Some cleanups Horst H. von Brand
2007-01-25 12:50 1% ` [PATCH] Hash name is SHA-1 Horst H. von Brand
2007-01-27 6:28 git user's manual J. Bruce Fields
2007-01-28 0:22 ` [PATCH] user-manual: set user.name and user.email with repo-config Matthias Lederhofer
2007-01-28 0:32 ` Linus Torvalds
2007-01-28 1:34 ` Matthias Lederhofer
2007-01-28 1:47 ` Linus Torvalds
2007-01-28 2:40 2% ` Tom Prince
2007-01-30 16:20 newbie questions about git design and features (some wrt hg) Mike Coleman
2007-01-30 16:55 2% ` Shawn O. Pearce
2007-02-09 10:49 restriction of pulls Christoph Duelli
2007-02-09 14:54 ` Johannes Schindelin
2007-02-09 15:32 2% ` Rogan Dawes
2007-02-09 16:19 5% ` Andy Parkins
2007-02-10 14:50 ` Johannes Schindelin
2007-02-12 13:58 3% ` Rogan Dawes
2007-02-12 14:13 ` Johannes Schindelin
2007-02-12 14:29 4% ` Rogan Dawes
2007-02-12 7:26 StGIT discards local commits on "stg pull" Pavel Roskin
2007-02-12 9:31 ` Catalin Marinas
2007-02-13 0:20 ` Pavel Roskin
2007-02-13 22:48 ` Catalin Marinas
2007-02-19 20:47 1% ` Yann Dirson
2007-02-14 3:14 2% [ANNOUNCE] GIT 1.5.0 Junio C Hamano
2007-02-15 22:13 16% [PATCH] git-clone: Sync documentation to usage note Christian Schlotter
2007-02-25 7:59 Google Summer of Code 2007 Shawn O. Pearce
2007-03-01 2:08 3% ` Jakub Narebski
2007-02-25 22:38 2% [PATCH 8/8] convert remaining users of "cmp" to "git diff" Johannes Schindelin
2007-03-06 6:35 [PATCH] Make 'make' quieter while building git Shawn O. Pearce
2007-03-06 7:03 ` Junio C Hamano
2007-03-06 7:16 ` Shawn O. Pearce
2007-03-06 10:53 ` Short term release plans Junio C Hamano
2007-03-19 10:53 1% ` GIT v1.5.1-rc1 Junio C Hamano
2007-03-25 12:30 .gitlink for Summer of Code Eric Lesh
2007-03-27 21:11 ` Linus Torvalds
2007-03-27 20:54 ` David Lang
2007-03-27 23:31 ` Jakub Narebski
2007-03-27 23:20 4% ` David Lang
2007-04-04 9:12 1% [ANNOUNCE] GIT 1.5.1 Junio C Hamano
2007-04-10 4:12 [PATCH 0/6] Initial subproject support (RFC?) Linus Torvalds
2007-04-11 22:48 ` [PATCH 5/6] Teach "fsck" not to follow subproject links Linus Torvalds
2007-04-11 23:16 ` Linus Torvalds
2007-04-11 23:53 ` Linus Torvalds
2007-04-11 23:30 ` David Lang
2007-04-12 2:14 ` Linus Torvalds
2007-04-12 18:32 1% ` Dana How
2007-04-17 9:02 GIT vs Other: Need argument Pietro Mascagni
[not found] ` <200704172239.20124.andyparkins@gmail.com>
2007-04-19 11:59 ` Marcin Kasperski
2007-04-19 12:57 3% ` Andy Parkins
2007-05-01 21:46 2% Git benchmarks at OpenOffice.org wiki Jakub Narebski
2007-05-01 22:27 3% ` Junio C Hamano
2007-05-02 14:24 0% ` Jan Holesovsky
2007-05-02 23:30 4% ` Jakub Narebski
2007-05-09 15:30 2% svn user trying to recover from brain damage Joshua Ball
2007-05-09 16:22 1% ` Petr Baudis
2007-05-20 17:57 6% Partial removal of fetching from git-clone skimo
2007-07-18 19:19 1% [PATCH] Implement git commit as a builtin Kristian Høgsberg
2007-07-23 12:52 index-pack died on pread Michal Rokos
2007-07-23 17:04 ` Linus Torvalds
2007-07-25 23:15 2% ` Robin Rosenberg
2007-09-05 7:09 People unaware of the importance of "git gc"? Linus Torvalds
2007-09-05 21:07 3% ` Alex Riesen
2007-09-06 0:23 [PATCH 1/9] Enable wt-status output to a given FILE pointer Kristian Høgsberg
2007-09-06 0:23 ` [PATCH 2/9] Enable wt-status to run against non-standard index file Kristian Høgsberg
2007-09-06 0:23 ` [PATCH 3/9] Add strbuf_printf() to do formatted printing to a strbuf Kristian Høgsberg
2007-09-06 0:23 ` [PATCH 4/9] Introduce entry point for launching add--interactive Kristian Høgsberg
2007-09-06 0:23 ` [PATCH 5/9] Introduce strbuf_read_fd() Kristian Høgsberg
2007-09-06 0:23 ` [PATCH 6/9] Rewrite launch_editor, create_tag and stripspace to use strbufs Kristian Høgsberg
2007-09-06 0:23 ` [PATCH 7/9] Add strbuf_read_path() Kristian Høgsberg
2007-09-06 0:23 ` [PATCH 8/9] Export rerere() and launch_editor() Kristian Høgsberg
2007-09-06 0:23 2% ` [PATCH 9/9] Implement git commit as a builtin command Kristian Høgsberg
2007-09-19 19:01 2% [ANNOUNCE] GIT 1.5.3.2 Junio C Hamano
2007-09-23 17:27 user-manual changes J. Bruce Fields
2007-09-24 3:14 11% ` [PATCH] user-manual: Explain what submodules are good for Michael Smith
2007-09-25 12:44 Michael Smith
2007-09-25 12:44 14% ` Michael Smith
2007-09-25 16:09 0% ` J. Bruce Fields
2007-09-27 4:50 [PATCH 1/4] Add a simple option parser for use by builtin-commit.c Kristian Høgsberg
2007-09-27 4:50 ` [PATCH 2/4] This exports the update() function from builtin-add.c as Kristian Høgsberg
2007-09-27 4:50 2% ` [PATCH 3/4] Implement git commit as a builtin command Kristian Høgsberg
2007-10-04 9:12 2% Git User's Survey 2007 unfinished summary (long) Jakub Narebski
2007-10-07 21:23 Trying to use git-filter-branch to compress history by removing large, obsolete binary files Elijah Newren
2007-10-07 21:38 ` Frank Lichtenheld
2007-10-07 22:00 ` Elijah Newren
2007-10-07 23:19 ` Johannes Schindelin
2007-10-07 23:24 ` Elijah Newren
2007-10-07 23:28 ` Johannes Schindelin
2007-10-07 23:38 ` Elijah Newren
2007-10-08 0:34 ` Johannes Schindelin
2007-10-08 0:47 ` Elijah Newren
2007-10-08 2:28 2% ` Sam Vilain
2007-10-08 20:55 Git User's Survey 2007 unfinished summary continued Jakub Narebski
2007-10-12 22:08 2% ` Jakub Narebski
2007-10-10 21:13 11% [PATCH] Fixing path quoting issues Jonathan del Strother
2007-10-10 21:22 11% maillist
2007-10-12 22:07 1% Git User's Survey 2007 summary - comparison with previous survey Jakub Narebski
2007-10-13 22:36 [PATCH] Fixing path quoting issues Andreas Ericsson
2007-10-15 13:13 7% ` [PATCH 2/3] Quoting paths in tests Jonathan del Strother
2007-10-16 8:42 Is there any plan to support partial checkout or submoudule improvement? Lars Hjemli
2007-10-16 9:56 4% ` franky
2007-10-17 9:14 [PATCH 1/3] Fixing path quoting in git-rebase Jonathan del Strother
2007-10-17 9:31 ` [PATCH] Quoting paths, take 3 Jonathan del Strother
2007-10-17 9:31 ` [PATCH 1/2] Fixing path quoting in git-rebase Jonathan del Strother
2007-10-17 9:31 6% ` [PATCH 2/2] Quoting paths in tests Jonathan del Strother
2007-10-22 6:32 What's cooking in git/spearce.git (topics) Shawn O. Pearce
2007-10-24 12:51 ` What's cooking in git.git (topics) Junio C Hamano
2007-11-01 5:41 ` Junio C Hamano
2007-11-04 4:14 ` Junio C Hamano
2007-11-08 8:08 ` Junio C Hamano
2007-11-12 7:09 ` Junio C Hamano
2007-11-15 0:18 ` Junio C Hamano
2007-11-17 20:51 1% ` Junio C Hamano
2007-10-25 19:48 4% stgit restrictions on patch names Yann Dirson
2007-10-29 16:14 0% ` Catalin Marinas
2007-10-31 21:16 3% [PATCH] Updated russian translation of git-gui Alex Riesen
2007-11-01 19:09 2% [PATCH] Implement git commit as a builtin command Kristian Høgsberg
2007-11-08 16:59 2% [PATCH] Port git commit to C Kristian Høgsberg
2007-11-12 13:57 Cloning from kernel.org, then switching to another repo Jon Smirl
2007-11-12 14:13 ` Johannes Schindelin
2007-11-12 15:36 ` Jon Smirl
2007-11-12 16:16 ` Johannes Schindelin
2007-11-12 16:22 ` Jon Smirl
2007-11-12 16:36 ` Johannes Schindelin
2007-11-12 17:21 ` Jon Smirl
2007-11-12 17:28 ` Jon Smirl
2007-11-13 4:14 4% ` Jeff King
2007-11-12 21:38 [PATCH] Add a test checking if send-pack updated local tracking branches correctly Alex Riesen
2007-11-12 21:39 ` [PATCH] Update the tracking references only if they were succesfully updated on remote Alex Riesen
2007-11-13 7:52 ` Jeff King
2007-11-13 19:47 ` Alex Riesen
2007-11-13 19:49 ` [PATCH] Add a test for deleting remote branches Alex Riesen
2007-11-13 23:02 ` [PATCH] Improved and extended t5404 Alex Riesen
2007-11-13 23:10 ` Jeff King
2007-11-15 4:26 ` Jeff King
2007-11-15 20:46 3% ` [PATCH] Add test that checks diverse aspects of updating remote and tracking branches Alex Riesen
2007-11-14 21:52 3% ` [PATCH] Improved and extended t5404 Junio C Hamano
2007-11-14 22:49 3% ` [PATCH] Add test that checks diverse aspects of updating remote and tracking branches Alex Riesen
2007-11-14 21:52 3% ` [PATCH] Improved and extended t5404 Junio C Hamano
2007-11-28 22:39 Adding Git to Better SCM Initiative : Comparison Jakub Narebski
2007-11-29 1:48 3% ` Robin Rosenberg
2007-12-04 13:09 2% Building git-1.5.3.7 on HP-UX 11.00 H.Merijn Brand
2008-01-02 7:13 3% Git and securing a repository Gonzalo Garramuño
2008-01-02 6:34 2% ` Felipe Balbi
2008-01-02 16:18 1% ` Daniel Barkalow
2008-01-12 7:11 [ANNOUNCE] GIT 1.5.4-rc3 Junio C Hamano
2008-01-12 7:26 ` Ismail Dönmez
2008-01-12 7:34 ` Junio C Hamano
2008-01-12 7:47 ` Ismail Dönmez
2008-01-12 9:04 ` Jeff King
2008-01-12 11:10 ` valgrind test script integration Jeff King
2008-01-12 11:36 2% ` Jeff King
2008-01-13 19:02 [PATCH] http-push: making HTTP push more robust and more user-friendly Grégoire Barbier
2008-01-13 23:01 ` Junio C Hamano
2008-01-19 15:21 2% ` Grégoire Barbier
2008-01-15 5:24 1% Git Gui: initial french translation: fr.po Christian Couder
2008-01-30 8:32 What's in git.git (stable frozen) Junio C Hamano
2008-02-12 7:25 ` What's in git.git Junio C Hamano
2008-02-17 3:56 2% ` What's in git.git (stable) Junio C Hamano
2008-02-21 4:16 2% ` Junio C Hamano
2008-02-08 17:28 [PATCH] RFC: git lazy clone proof-of-concept Jan Holesovsky
2008-02-08 19:00 ` Jakub Narebski
2008-02-09 15:27 ` Jan Holesovsky
2008-02-11 1:20 4% ` Jakub Narebski
2008-02-08 20:16 4% ` Johannes Schindelin
2008-02-14 20:05 ` Jakub Narebski
2008-02-14 21:04 ` Johannes Schindelin
2008-02-14 21:59 5% ` Jakub Narebski
2008-02-14 23:38 4% ` Johannes Schindelin
2008-02-15 1:07 5% ` Jakub Narebski
2008-02-15 9:43 1% ` Jan Holesovsky
2008-02-10 10:47 [ANNOUNCE] GIT 1.5.4.1 Junio C Hamano
2008-02-17 9:14 2% ` [ANNOUNCE] GIT 1.5.4.2 Junio C Hamano
2008-02-20 23:59 [PATCH 0/3] solaris test results Jeff King
2008-02-21 0:34 ` Junio C Hamano
2008-02-21 0:41 ` Jeff King
2008-02-22 5:26 1% ` Junio C Hamano
2008-02-23 21:07 3% [ANNOUNCE] GIT 1.5.4.3 Junio C Hamano
2008-02-24 9:34 on subtree checkout Nguyen Thai Ngoc Duy
2008-02-24 10:03 ` Jakub Narebski
2008-02-24 15:12 ` Nguyen Thai Ngoc Duy
2008-02-24 15:45 ` Jakub Narebski
2008-02-24 15:59 5% ` Matthieu Moy
2008-02-24 17:22 2% ` Robin Rosenberg
2008-02-26 1:59 ` Johannes Schindelin
2008-02-26 2:30 3% ` David Symonds
2008-02-26 11:23 2% ` Johannes Schindelin
2008-02-26 22:56 Google Summer of Code 2008 Jakub Narebski
2008-02-28 6:36 ` Shawn O. Pearce
2008-02-28 10:27 ` Johannes Schindelin
2008-02-29 12:04 4% ` Jakub Narebski
2008-03-10 22:02 [QUESTION] Selective fetch possible? Filippo Zangheri
2008-03-10 22:53 ` Shawn O. Pearce
2008-03-10 23:34 2% ` Jakub Narebski
2008-03-11 7:26 0% ` Rogan Dawes
2008-03-11 7:50 ` Shawn O. Pearce
2008-03-11 9:07 3% ` Rogan Dawes
[not found] <cover.1205356737.git.peff@peff.net>
2008-03-12 21:36 1% ` [PATCH 06/16] add test_cmp function for test scripts Jeff King
2008-03-29 22:35 git-submodule getting submodules from the parent repository Avery Pennarun
2008-03-29 23:22 ` Sam Vilain
2008-03-30 23:00 ` Avery Pennarun
2008-04-01 23:10 3% ` Sam Vilain
2008-04-03 19:42 Achieving efficient storage of weirdly structured repos Roman Shaposhnik
2008-04-03 21:11 3% ` Linus Torvalds
2008-04-04 23:30 1% ` Roman Shaposhnik
2008-04-09 1:29 [PATCH 0/8] Fix git's test suite to pass when the path contains spaces Bryan Donlan
2008-04-09 1:29 ` [PATCH 1/8] git-rebase.sh: Fix --merge --abort failures when path contains whitespace Bryan Donlan
2008-04-09 1:29 ` [PATCH 2/8] config.c: Escape backslashes in section names properly Bryan Donlan
2008-04-09 1:29 ` [PATCH 3/8] git-send-email.perl: Handle shell metacharacters in $EDITOR properly Bryan Donlan
2008-04-09 1:30 ` [PATCH 4/8] test-lib.sh: Fix some missing path quoting Bryan Donlan
2008-04-09 1:30 ` [PATCH 5/8] test-lib.sh: Add a test_set_editor function to safely set $VISUAL Bryan Donlan
2008-04-09 1:30 ` [PATCH 6/8] lib-git-svn.sh: Fix quoting issues with paths containing shell metacharacters Bryan Donlan
2008-04-09 1:30 ` [PATCH 7/8] Use test_set_editor in t9001-send-email.sh Bryan Donlan
2008-04-09 1:30 10% ` [PATCH 8/8] Fix tests breaking when checkout path contains shell metacharacters Bryan Donlan
2008-04-10 6:50 ` [PATCH v2 00/10] Fix git's test suite to pass when the path contains spaces Bryan Donlan
2008-04-10 6:50 ` [PATCH v2 01/10] git-rebase.sh: Fix --merge --abort failures when path contains whitespace Bryan Donlan
2008-04-10 6:50 ` [PATCH v2 02/10] config.c: Escape backslashes in section names properly Bryan Donlan
2008-04-10 6:50 ` [PATCH v2 03/10] git-send-email.perl: Handle shell metacharacters in $EDITOR properly Bryan Donlan
2008-04-10 6:50 ` [PATCH v2 04/10] test-lib.sh: Add a test_set_editor function to safely set $VISUAL Bryan Donlan
2008-04-10 6:50 ` [PATCH v2 05/10] Use test_set_editor in t9001-send-email.sh Bryan Donlan
2008-04-10 6:50 ` [PATCH v2 06/10] test-lib.sh: Fix some missing path quoting Bryan Donlan
2008-04-10 6:50 ` [PATCH v2 07/10] lib-git-svn.sh: Fix quoting issues with paths containing shell metacharacters Bryan Donlan
2008-04-10 6:50 ` [PATCH v2 08/10] Don't use the export NAME=value form in the test scripts Bryan Donlan
2008-04-10 6:50 10% ` [PATCH v2 09/10] Fix tests breaking when checkout path contains shell metacharacters Bryan Donlan
2008-05-04 5:37 ` [PATCH v3 00/10] Fix git's test suite to pass when the path contains spaces Bryan Donlan
2008-05-04 5:37 ` [PATCH v3 01/10] git-rebase.sh: Fix --merge --abort failures when path contains whitespace Bryan Donlan
2008-05-04 5:37 ` [PATCH v3 02/10] config.c: Escape backslashes in section names properly Bryan Donlan
2008-05-04 5:37 ` [PATCH v3 03/10] git-send-email.perl: Handle shell metacharacters in $EDITOR properly Bryan Donlan
2008-05-04 5:37 ` [PATCH v3 04/10] test-lib.sh: Add a test_set_editor function to safely set $VISUAL Bryan Donlan
2008-05-04 5:37 ` [PATCH v3 05/10] Use test_set_editor in t9001-send-email.sh Bryan Donlan
2008-05-04 5:37 ` [PATCH v3 06/10] test-lib.sh: Fix some missing path quoting Bryan Donlan
2008-05-04 5:37 ` [PATCH v3 07/10] lib-git-svn.sh: Fix quoting issues with paths containing shell metacharacters Bryan Donlan
2008-05-04 5:37 ` [PATCH v3 08/10] Don't use the export NAME=value form in the test scripts Bryan Donlan
2008-05-04 5:37 8% ` [PATCH v3 09/10] Fix tests breaking when checkout path contains shell metacharacters Bryan Donlan
2008-04-22 21:28 9% [PATCH] Have tests and programs understand paths containing spaces Arjen Laarhoven
Code repositories for project(s) associated with this public inbox
https://80x24.org/mirrors/git.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).