* Re: Smart fetch via HTTP?
From: Matthieu Moy @ 2007-05-18 20:06 UTC (permalink / raw)
To: Joel Becker; +Cc: Linus Torvalds, git
In-Reply-To: <20070518190159.GS24644@ca-server1.us.oracle.com>
Joel Becker <Joel.Becker@oracle.com> writes:
> A normal company needs to have their firewall allow CONNECT to
> 9418. Then git proxying over HTTP is possible to a standard
> git-daemon.
443 should work too (that's HTTPS, and the proxy can't filter it,
since this would be a man-in-the-middle attack).
--
Matthieu
^ permalink raw reply
* Re: Opinions on bug fix organisation
From: Jan Hudec @ 2007-05-18 19:50 UTC (permalink / raw)
To: Andy Parkins; +Cc: git
In-Reply-To: <200705161138.30134.andyparkins@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 1149 bytes --]
On Wed, May 16, 2007 at 11:38:28 +0100, Andy Parkins wrote:
> Now, I want to make a commit that fixes that bug. These are the options:
>
> * -- * -- B -- * -- * -- * -- F
>
> or
>
> * -- * -- B -- * -- * -- * -- M
> \ /
> --------------- F
>
> That is - just commit a fix or, commit the fix, "F", directly on "B" then
> merge that fix back to HEAD with "M".
>
> I quite like option 2 because it records intent - i.e. "I wish I could have
> gone back and changed this revision, but I can't", but it makes a more
> complicated history.
>
> What do people think?
The big advantage of the later is, that if you have:
* -- B -- * -- * -- M1
\
-- * -- * -- M2
You can merge the fix done on yet another branch into how many branches you
need, so:
* -- B -- * -- * ----- M1
\ /
-- * -- * ----/- M2
\ / /
----------F---
If you had the fix on one of the branches, you could only cherry-pick it to
the other, but the history would not really reflect that.
--
Jan 'Bulb' Hudec <bulb@ucw.cz>
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* Re: Second round of support for cloning submodules
From: Sven Verdoolaege @ 2007-05-18 19:34 UTC (permalink / raw)
To: git, Junio C Hamano
In-Reply-To: <11795163053812-git-send-email-skimo@liacs.nl>
I forgot to mention that these changes go on top of next
(v1.5.2-rc3-762-g77e153b).
skimo
^ permalink raw reply
* Re: Initial support for cloning submodules
From: Sven Verdoolaege @ 2007-05-18 19:33 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7vfy6cqk0w.fsf@assigned-by-dhcp.cox.net>
On Fri, May 04, 2007 at 03:52:15PM -0700, Junio C Hamano wrote:
> (3) "git-fetch --submodules", after finishing what it would do
> without "--submodules" option, would inspect the fetched
> tree (or the index derived from it), find the tree entries
> with mode 160000 (i.e. submodule graft points), and _then_
> uses the pathnames of these tree entries to consult the
> config mechanism to see which URL(s) can be used to
> retrieve them, probably only for new submodules.
I've gone for cloning all available submodules on the remote,
even if they are not used in the HEAD.
A submodule may have been removed already and IMHO, you wouldn't
want to clone a submodule at the time you reset to an intermediate
commit.
skimo
^ permalink raw reply
* [PATCH 15/16] git-read-tree: treat null commit as empty tree
From: skimo @ 2007-05-18 19:25 UTC (permalink / raw)
To: git, Junio C Hamano
In-Reply-To: <11795163053812-git-send-email-skimo@liacs.nl>
From: Sven Verdoolaege <skimo@kotnet.org>
---
builtin-read-tree.c | 9 ++++++---
unpack-trees.c | 3 +++
2 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/builtin-read-tree.c b/builtin-read-tree.c
index 929dd95..b9fcff7 100644
--- a/builtin-read-tree.c
+++ b/builtin-read-tree.c
@@ -17,9 +17,12 @@ static struct object_list *trees;
static int list_tree(unsigned char *sha1)
{
- struct tree *tree = parse_tree_indirect(sha1);
- if (!tree)
- return -1;
+ struct tree *tree = NULL;
+ if (!is_null_sha1(sha1)) {
+ tree = parse_tree_indirect(sha1);
+ if (!tree)
+ return -1;
+ }
object_list_append(&tree->object, &trees);
return 0;
}
diff --git a/unpack-trees.c b/unpack-trees.c
index e979bc5..30c2a49 100644
--- a/unpack-trees.c
+++ b/unpack-trees.c
@@ -26,6 +26,9 @@ static struct tree_entry_list *create_tree_entry_list(struct tree *tree)
struct tree_entry_list *ret = NULL;
struct tree_entry_list **list_p = &ret;
+ if (!tree)
+ return ret;
+
if (!tree->object.parsed)
parse_tree(tree);
--
1.5.2.rc3.783.gc7476-dirty
^ permalink raw reply related
* [PATCH 14/16] git-clone: rely on git-fetch for non-bare fetching over http
From: skimo @ 2007-05-18 19:25 UTC (permalink / raw)
To: git, Junio C Hamano
In-Reply-To: <11795163053812-git-send-email-skimo@liacs.nl>
From: Sven Verdoolaege <skimo@kotnet.org>
Signed-off-by: Sven Verdoolaege <skimo@kotnet.org>
---
git-clone.sh | 6 +++---
git-fetch.sh | 20 ++++++++++++++++++++
2 files changed, 23 insertions(+), 3 deletions(-)
diff --git a/git-clone.sh b/git-clone.sh
index 44127c5..44387f4 100755
--- a/git-clone.sh
+++ b/git-clone.sh
@@ -262,8 +262,8 @@ yes,yes)
git-ls-remote "$repo" >"$GIT_DIR/CLONE_HEAD" || exit 1
;;
*)
- case "$repo" in
- rsync://*)
+ case "$bare,$repo" in
+ *,rsync://*)
case "$depth" in
"") ;;
*) die "shallow over rsync not supported" ;;
@@ -295,7 +295,7 @@ yes,yes)
fi
git-ls-remote "$repo" >"$GIT_DIR/CLONE_HEAD" || exit 1
;;
- https://*|http://*|ftp://*)
+ yes,https://*|yes,http://*|yes,ftp://*)
case "$depth" in
"") ;;
*) die "shallow over http or ftp not supported" ;;
diff --git a/git-fetch.sh b/git-fetch.sh
index e169848..84c2523 100755
--- a/git-fetch.sh
+++ b/git-fetch.sh
@@ -237,11 +237,31 @@ fetch_all_at_once () {
}
+http_fetch () {
+ if [ -n "$GIT_SSL_NO_VERIFY" ]; then
+ curl_extra_args="-k"
+ fi
+ if [ -n "$GIT_CURL_FTP_NO_EPSV" -o \
+ "`git-config --bool http.noEPSV`" = true ]; then
+ curl_extra_args="${curl_extra_args} --disable-epsv"
+ fi
+
+ # $1 = Remote, $2 = Local
+ curl -nsfL $curl_extra_args "$1" >"$2"
+}
+
fetch_per_ref () {
reflist="$1"
refs=
rref=
+ if test -n "$all"; then
+ reflist=$(canon_refs_list_for_fetch -d "$remote_nick" \
+ "+refs/heads/*:refs/remotes/$remote_nick/*")
+ http_fetch "$remote/HEAD" "$GIT_DIR/REMOTE_HEAD" ||
+ rm -f "$GIT_DIR/REMOTE_HEAD"
+ fi
+
for ref in $reflist
do
refs="$refs$LF$ref"
--
1.5.2.rc3.783.gc7476-dirty
^ permalink raw reply related
* [PATCH 16/16] git-clone: add --submodules for cloning submodules
From: skimo @ 2007-05-18 19:25 UTC (permalink / raw)
To: git, Junio C Hamano
In-Reply-To: <11795163053812-git-send-email-skimo@liacs.nl>
From: Sven Verdoolaege <skimo@kotnet.org>
When the --submodules option is specified, git-clone will search
for submodule.<submodule>.url options in the remote configuration
and clone each submodule using the first url that it can use from
the local site.
Signed-off-by: Sven Verdoolaege <skimo@kotnet.org>
---
Documentation/config.txt | 7 +++
Documentation/git-clone.txt | 6 ++-
git-clone.sh | 18 +++++++-
git-fetch.sh | 90 +++++++++++++++++++++++++++++++++++++++++++
4 files changed, 117 insertions(+), 4 deletions(-)
diff --git a/Documentation/config.txt b/Documentation/config.txt
index ee1c35e..cee9e40 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -256,6 +256,10 @@ You probably do not need to adjust this value.
+
Common unit suffixes of 'k', 'm', or 'g' are supported.
+core.submodules
+ If true, gitlink:git-checkout[1] also checks out submodules.
+ False by default.
+
alias.*::
Command aliases for the gitlink:git[1] command wrapper - e.g.
after defining "alias.last = cat-file commit HEAD", the invocation
@@ -606,6 +610,9 @@ showbranch.default::
The default set of branches for gitlink:git-show-branch[1].
See gitlink:git-show-branch[1].
+submodule.<submodule>.url
+ The URL of a submodule. See gitlink:git-clone[1].
+
tar.umask::
By default, gitlink:git-tar-tree[1] sets file and directories modes
to 0666 or 0777. While this is both useful and acceptable for projects
diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt
index 644bf12..565155b 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>] [--submodules] <repository> [<directory>]
DESCRIPTION
-----------
@@ -105,6 +105,10 @@ OPTIONS
with a long history, and would want to send in a fixes
as patches.
+--submodules::
+ Clone submodules specified in (remote) configuration parameters
+ submodule.<submodule>.url.
+
<repository>::
The (possibly remote) repository to clone from. It can
be any URL git-fetch supports.
diff --git a/git-clone.sh b/git-clone.sh
index 44387f4..f5a3548 100755
--- a/git-clone.sh
+++ b/git-clone.sh
@@ -14,7 +14,7 @@ die() {
}
usage() {
- die "Usage: $0 [--template=<template_directory>] [--reference <reference-repo>] [--bare] [-l [-s]] [-q] [-u <upload-pack>] [--origin <name>] [--depth <n>] [-n] <repo> [<dir>]"
+ die "Usage: $0 [--template=<template_directory>] [--reference <reference-repo>] [--bare] [-l [-s]] [-q] [-u <upload-pack>] [--origin <name>] [--depth <n>] [-n] [--submodules] <repo> [<dir>]"
}
get_repo_base() {
@@ -88,6 +88,7 @@ origin_override=
use_separate_remote=t
depth=
no_progress=
+submodules=
test -t 1 || no_progress=--no-progress
while
case "$#,$1" in
@@ -138,6 +139,8 @@ while
*,--depth)
shift
depth="--depth=$1";;
+ *,--su|*,--sub|*,--subm|*,--submo|*,--submod|*,--submodu|*,--submodul|\
+ *,--submodule|*,--submodules) submodules="--submodules" ;;
*,-*) usage ;;
*) break ;;
esac
@@ -156,6 +159,10 @@ then
then
die '--bare and --origin $origin options are incompatible.'
fi
+ if test -n "$submodules"
+ then
+ die '--bare and --submodules origin options are incompatible.'
+ fi
no_checkout=yes
use_separate_remote=
fi
@@ -309,7 +316,7 @@ yes,yes)
;;
*)
git-fetch --all -k $quiet "$upload_pack" $depth \
- $separate_remote_flag "$origin" ||
+ $separate_remote_flag $submodules "$origin" ||
die "fetch from '$repo' failed."
;;
esac
@@ -405,10 +412,15 @@ then
git-config branch."$head_points_at".merge "refs/heads/$head_points_at"
esac
+ if test -n "$submodules"
+ then
+ git-config core.submodules true
+ fi
+
case "$no_checkout" in
'')
test "z$quiet" = z -a "z$no_progress" = z && v=-v || v=
- git-read-tree -m -u $v HEAD HEAD
+ git-read-tree -m -u $v $submodules HEAD HEAD
esac
fi
rm -f "$GIT_DIR/CLONE_HEAD" "$GIT_DIR/REMOTE_HEAD"
diff --git a/git-fetch.sh b/git-fetch.sh
index 84c2523..b7ef0c3 100755
--- a/git-fetch.sh
+++ b/git-fetch.sh
@@ -15,6 +15,70 @@ LF='
'
IFS="$LF"
+local_URL() {
+ # tranforms a "URL" on the remote to a URL that works on the local machine
+ # $1 - remote, $2 - URL on remote
+ echo "$1 $2" >&2
+ case "$1" in
+ https://*|http://*|ftp://*)
+ case "$2" in
+ https://*|http://*|ftp://*)
+ echo $2
+ esac
+ ;;
+ ssh://*)
+ case "$2" in
+ https://*|http://*|ftp://*)
+ echo $2
+ ;;
+ /*)
+ echo $(echo $1 | sed -e 's/\(ssh:\/\/[^\/]*\)\/.*/\1/')$2
+ esac
+ ;;
+ /*)
+ echo $2
+ ;;
+ *)
+ case "$2" in
+ https://*|http://*|ftp://*)
+ echo $2
+ esac
+ esac
+}
+
+clone_submodules () {
+ # $1 - remote
+ remote=$1
+ ( : subshell because we muck with IFS
+ IFS=" $LF"
+ cd "$GIT_DIR/.."
+ git-config --remote="$remote" --get-regexp 'submodule\..*\.url' | \
+ sed -e 's/^submodule\.//' -e 's/\.url / /' |
+ while read submodule URL
+ do
+ previous=$(git-config "submodule.$submodule.url")
+ if test -n "$previous"
+ then
+ continue;
+ fi
+ URL=$(local_URL "$remote" "$URL")
+ if test -z "$URL"
+ then
+ continue;
+ fi
+ # At this point, we don't know if the submodule
+ # appears in the HEAD of the supermodule, so clone it
+ # without a checkout and overwrite HEAD so that a subsequent
+ # checkout won't assume the submodule has already been
+ # checked out.
+ git-clone --submodules -n "$URL" "$submodule"
+ z40=0000000000000000000000000000000000000000
+ GIT_DIR="$submodule/.git" git-update-ref --no-deref HEAD $z40
+ git-config "submodule.$submodule.url" "$URL"
+ done
+ )
+}
+
all=
no_tags=
tags=
@@ -27,6 +91,7 @@ keep=
shallow_depth=
no_progress=
use_separate_remote=
+submodules=
test -t 1 || no_progress=--no-progress
quiet=
while case "$#" in 0) break ;; esac
@@ -84,6 +149,15 @@ do
shift
shallow_depth="--depth=$1"
;;
+ --su|--sub|--subm|--submo|--submod|--submodu|--submodul|\
+ --submodule|--submodules)
+ submodules="yes"
+ ;;
+ --no-su|--no-sub|--no-subm|--no-submo|--no-submod|\
+ --no-submodu|--no-submodul|\
+ --no-submodule|--no-submodules)
+ submodules="no"
+ ;;
-*)
usage
;;
@@ -149,6 +223,18 @@ case "$tags$no_tags" in
esac
esac
+case "$submodules" in
+'')
+ case "$(git-config --bool core.submodules)" in
+ true)
+ submodues=yes
+ ;;
+ *)
+ submodules=no
+ ;;
+ esac
+esac
+
# If --tags (and later --heads or --all) is specified, then we are
# not talking about defaults stored in Pull: line of remotes or
# branches file, and just fetch those and refspecs explicitly given.
@@ -407,3 +493,7 @@ case "$orig_head" in
fi
;;
esac
+
+if test "$submodules" = yes; then
+ clone_submodules "$remote"
+fi
--
1.5.2.rc3.783.gc7476-dirty
^ permalink raw reply related
* [PATCH 06/16] unpack-trees.c: pass cache_entry * to verify_absent rather than just the name
From: skimo @ 2007-05-18 19:24 UTC (permalink / raw)
To: git, Junio C Hamano
In-Reply-To: <11795163053812-git-send-email-skimo@liacs.nl>
From: Sven Verdoolaege <skimo@kotnet.org>
We will need the full cache_entry later to figure out if we are dealing
with a submodule.
Signed-off-by: Sven Verdoolaege <skimo@kotnet.org>
---
unpack-trees.c | 32 ++++++++++++++++----------------
1 files changed, 16 insertions(+), 16 deletions(-)
diff --git a/unpack-trees.c b/unpack-trees.c
index cac2411..3dac150 100644
--- a/unpack-trees.c
+++ b/unpack-trees.c
@@ -487,7 +487,7 @@ static int verify_clean_subdirectory(const char *path, const char *action,
* We do not want to remove or overwrite a working tree file that
* is not tracked, unless it is ignored.
*/
-static void verify_absent(const char *path, const char *action,
+static void verify_absent(struct cache_entry *ce, const char *action,
struct unpack_trees_options *o)
{
struct stat st;
@@ -495,12 +495,12 @@ static void verify_absent(const char *path, const char *action,
if (o->index_only || o->reset || !o->update)
return;
- if (!lstat(path, &st)) {
+ if (!lstat(ce->name, &st)) {
int cnt;
- if (o->dir && excluded(o->dir, path))
+ if (o->dir && excluded(o->dir, ce->name))
/*
- * path is explicitly excluded, so it is Ok to
+ * ce->name is explicitly excluded, so it is Ok to
* overwrite it.
*/
return;
@@ -512,7 +512,7 @@ static void verify_absent(const char *path, const char *action,
* files that are in "foo/" we would lose
* it.
*/
- cnt = verify_clean_subdirectory(path, action, o);
+ cnt = verify_clean_subdirectory(ce->name, action, o);
/*
* If this removed entries from the index,
@@ -540,7 +540,7 @@ static void verify_absent(const char *path, const char *action,
* delete this path, which is in a subdirectory that
* is being replaced with a blob.
*/
- cnt = cache_name_pos(path, strlen(path));
+ cnt = cache_name_pos(ce->name, strlen(ce->name));
if (0 <= cnt) {
struct cache_entry *ce = active_cache[cnt];
if (!ce_stage(ce) && !ce->ce_mode)
@@ -548,7 +548,7 @@ static void verify_absent(const char *path, const char *action,
}
die("Untracked working tree file '%s' "
- "would be %s by merge.", path, action);
+ "would be %s by merge.", ce->name, action);
}
}
@@ -572,7 +572,7 @@ static int merged_entry(struct cache_entry *merge, struct cache_entry *old,
}
}
else {
- verify_absent(merge->name, "overwritten", o);
+ verify_absent(merge, "overwritten", o);
invalidate_ce_path(merge);
}
@@ -587,7 +587,7 @@ static int deleted_entry(struct cache_entry *ce, struct cache_entry *old,
if (old)
verify_uptodate(old, o);
else
- verify_absent(ce->name, "removed", o);
+ verify_absent(ce, "removed", o);
ce->ce_mode = 0;
add_cache_entry(ce, ADD_CACHE_OK_TO_ADD|ADD_CACHE_OK_TO_REPLACE);
invalidate_ce_path(ce);
@@ -704,18 +704,18 @@ int threeway_merge(struct cache_entry **stages,
if (o->aggressive) {
int head_deleted = !head && !df_conflict_head;
int remote_deleted = !remote && !df_conflict_remote;
- const char *path = NULL;
+ struct cache_entry *ce = NULL;
if (index)
- path = index->name;
+ ce = index;
else if (head)
- path = head->name;
+ ce = head;
else if (remote)
- path = remote->name;
+ ce = remote;
else {
for (i = 1; i < o->head_idx; i++) {
if (stages[i] && stages[i] != o->df_conflict_entry) {
- path = stages[i]->name;
+ ce = stages[i];
break;
}
}
@@ -730,8 +730,8 @@ int threeway_merge(struct cache_entry **stages,
(remote_deleted && head && head_match)) {
if (index)
return deleted_entry(index, index, o);
- else if (path && !head_deleted)
- verify_absent(path, "removed", o);
+ else if (ce && !head_deleted)
+ verify_absent(ce, "removed", o);
return 0;
}
/*
--
1.5.2.rc3.783.gc7476-dirty
^ permalink raw reply related
* [PATCH 09/16] entry.c: optionally checkout submodules
From: skimo @ 2007-05-18 19:24 UTC (permalink / raw)
To: git, Junio C Hamano
In-Reply-To: <11795163053812-git-send-email-skimo@liacs.nl>
From: Sven Verdoolaege <skimo@kotnet.org>
Signed-off-by: Sven Verdoolaege <skimo@kotnet.org>
---
entry.c | 42 ++++++++++++++++++++++++++++++++++++++++--
1 files changed, 40 insertions(+), 2 deletions(-)
diff --git a/entry.c b/entry.c
index 82bf725..96a4a60 100644
--- a/entry.c
+++ b/entry.c
@@ -1,5 +1,6 @@
#include "cache.h"
#include "blob.h"
+#include "run-command.h"
static void create_directories(const char *path, const struct checkout *state)
{
@@ -163,6 +164,44 @@ static int write_entry(struct cache_entry *ce, char *path, const struct checkout
return 0;
}
+static int checkout_submodule(const char *path, struct cache_entry *ce, const struct checkout *state)
+{
+ static char cwd[PATH_MAX];
+ const char *gitdirenv;
+ const char *args[10];
+ int argc;
+ int err;
+
+ if (!state->submodules)
+ return 0;
+
+ if (!getcwd(cwd, sizeof(cwd)) || cwd[0] != '/')
+ die("Unable to read current working directory");
+
+ if (chdir(path))
+ die("Cannot move to '%s'", path);
+
+ argc = 0;
+ args[argc++] = "checkout";
+ if (state->force)
+ args[argc++] = "-f";
+ args[argc++] = sha1_to_hex(ce->sha1);
+ args[argc] = NULL;
+
+ gitdirenv = getenv(GIT_DIR_ENVIRONMENT);
+ unsetenv(GIT_DIR_ENVIRONMENT);
+ err = run_command_v_opt(args, RUN_GIT_CMD);
+ setenv(GIT_DIR_ENVIRONMENT, gitdirenv, 1);
+
+ if (chdir(cwd))
+ die("Cannot come back to cwd");
+
+ if (err)
+ return error("failed to run git-checkout in submodule '%s'", path);
+
+ return 0;
+}
+
int checkout_entry(struct cache_entry *ce, const struct checkout *state, char *topath)
{
static char path[PATH_MAX + 1];
@@ -193,9 +232,8 @@ int checkout_entry(struct cache_entry *ce, const struct checkout *state, char *t
*/
unlink(path);
if (S_ISDIR(st.st_mode)) {
- /* If it is a gitlink, leave it alone! */
if (S_ISDIRLNK(ntohl(ce->ce_mode)))
- return 0;
+ return checkout_submodule(path, ce, state);
if (!state->force)
return error("%s is a directory", path);
remove_subtree(path);
--
1.5.2.rc3.783.gc7476-dirty
^ permalink raw reply related
* [PATCH 05/16] unpack-trees.c: verify_uptodate: remove dead code
From: skimo @ 2007-05-18 19:24 UTC (permalink / raw)
To: git, Junio C Hamano
In-Reply-To: <11795163053812-git-send-email-skimo@liacs.nl>
From: Sven Verdoolaege <skimo@kotnet.org>
This code was killed by commit fcc387db9bc453dc7e07a262873481af2ee9e5c8.
Signed-off-by: Sven Verdoolaege <skimo@kotnet.org>
---
unpack-trees.c | 4 ----
1 files changed, 0 insertions(+), 4 deletions(-)
diff --git a/unpack-trees.c b/unpack-trees.c
index 906ce69..cac2411 100644
--- a/unpack-trees.c
+++ b/unpack-trees.c
@@ -414,10 +414,6 @@ static void verify_uptodate(struct cache_entry *ce,
return;
errno = 0;
}
- if (o->reset) {
- ce->ce_flags |= htons(CE_UPDATE);
- return;
- }
if (errno == ENOENT)
return;
die("Entry '%s' not uptodate. Cannot merge.", ce->name);
--
1.5.2.rc3.783.gc7476-dirty
^ permalink raw reply related
* [PATCH 07/16] git-read-tree: take --submodules option
From: skimo @ 2007-05-18 19:24 UTC (permalink / raw)
To: git, Junio C Hamano
In-Reply-To: <11795163053812-git-send-email-skimo@liacs.nl>
From: Sven Verdoolaege <skimo@kotnet.org>
This option currently has no effect.
Signed-off-by: Sven Verdoolaege <skimo@kotnet.org>
---
builtin-read-tree.c | 25 ++++++++++++++++++++++---
cache.h | 3 ++-
unpack-trees.c | 1 +
unpack-trees.h | 1 +
4 files changed, 26 insertions(+), 4 deletions(-)
diff --git a/builtin-read-tree.c b/builtin-read-tree.c
index 316fb0f..929dd95 100644
--- a/builtin-read-tree.c
+++ b/builtin-read-tree.c
@@ -87,14 +87,23 @@ 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>] [--index-output=<file>] <sha1> [<sha2> [<sha3>]])";
static struct lock_file lock_file;
+static struct unpack_trees_options opts;
+
+static int git_read_tree_config(const char *var, const char *value)
+{
+ if (!strcmp(var, "core.submodules")) {
+ opts.submodules = git_config_bool(var, value);
+ return 0;
+ }
+
+ return git_default_config(var, value);
+}
int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)
{
int i, newfd, stage = 0;
unsigned char sha1[20];
- struct unpack_trees_options opts;
- memset(&opts, 0, sizeof(opts));
opts.head_idx = -1;
setup_git_directory();
@@ -102,7 +111,7 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)
newfd = hold_locked_index(&lock_file, 1);
- git_config(git_default_config);
+ git_config(git_read_tree_config);
for (i = 1; i < argc; i++) {
const char *arg = argv[i];
@@ -172,6 +181,16 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)
continue;
}
+ if (!strcmp(arg, "--no-submodules")) {
+ opts.submodules = 0;
+ continue;
+ }
+
+ if (!strcmp(arg, "--submodules")) {
+ opts.submodules = 1;
+ continue;
+ }
+
/* "-m" stands for "merge", meaning we start in stage 1 */
if (!strcmp(arg, "-m")) {
if (stage || opts.merge || opts.prefix)
diff --git a/cache.h b/cache.h
index 6acc330..42a275e 100644
--- a/cache.h
+++ b/cache.h
@@ -406,7 +406,8 @@ struct checkout {
unsigned force:1,
quiet:1,
not_new:1,
- refresh_cache:1;
+ refresh_cache:1,
+ submodules:1;
};
extern int checkout_entry(struct cache_entry *ce, const struct checkout *state, char *topath);
diff --git a/unpack-trees.c b/unpack-trees.c
index 3dac150..5fa637a 100644
--- a/unpack-trees.c
+++ b/unpack-trees.c
@@ -352,6 +352,7 @@ int unpack_trees(struct object_list *trees, struct unpack_trees_options *o)
state.force = 1;
state.quiet = 1;
state.refresh_cache = 1;
+ state.submodules = o->submodules;
o->merge_size = len;
diff --git a/unpack-trees.h b/unpack-trees.h
index fee7da4..21005d9 100644
--- a/unpack-trees.h
+++ b/unpack-trees.h
@@ -15,6 +15,7 @@ struct unpack_trees_options {
int trivial_merges_only;
int verbose_update;
int aggressive;
+ int submodules;
const char *prefix;
int pos;
struct dir_struct *dir;
--
1.5.2.rc3.783.gc7476-dirty
^ permalink raw reply related
* [PATCH 13/16] git-clone: rely on git-fetch for fetching for most protocols
From: skimo @ 2007-05-18 19:25 UTC (permalink / raw)
To: git, Junio C Hamano
In-Reply-To: <11795163053812-git-send-email-skimo@liacs.nl>
From: Sven Verdoolaege <skimo@kotnet.org>
Signed-off-by: Sven Verdoolaege <skimo@kotnet.org>
---
git-clone.sh | 20 ++++++++++++--------
git-fetch.sh | 28 ++++++++++++++++++++++------
2 files changed, 34 insertions(+), 14 deletions(-)
diff --git a/git-clone.sh b/git-clone.sh
index fdd354f..44127c5 100755
--- a/git-clone.sh
+++ b/git-clone.sh
@@ -159,6 +159,11 @@ then
no_checkout=yes
use_separate_remote=
fi
+if test t = "$use_separate_remote"; then
+ separate_remote_flag="--use-separate-remote"
+else
+ separate_remote_flag="--no-separate-remote"
+fi
if test -z "$origin"
then
@@ -219,6 +224,10 @@ then
fi
fi
+# Write out $origin URL
+GIT_CONFIG="$GIT_DIR/config"
+git-config remote."$origin".url "$repo" || exit
+
rm -f "$GIT_DIR/CLONE_HEAD"
# We do local magic only when the user tells us to.
@@ -299,11 +308,9 @@ yes,yes)
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" ;;
- esac >"$GIT_DIR/CLONE_HEAD" ||
- die "fetch-pack from '$repo' failed."
+ git-fetch --all -k $quiet "$upload_pack" $depth \
+ $separate_remote_flag "$origin" ||
+ die "fetch from '$repo' failed."
;;
esac
;;
@@ -387,9 +394,6 @@ then
origin_track="$remote_top/$head_points_at" &&
git-update-ref HEAD "$head_sha1" &&
- # Upstream URL
- git-config remote."$origin".url "$repo" &&
-
# Set up the mappings to track the remote branches.
git-config remote."$origin".fetch \
"+refs/heads/*:$remote_top/*" '^$' &&
diff --git a/git-fetch.sh b/git-fetch.sh
index dbeca14..e169848 100755
--- a/git-fetch.sh
+++ b/git-fetch.sh
@@ -15,6 +15,7 @@ LF='
'
IFS="$LF"
+all=
no_tags=
tags=
append=
@@ -25,6 +26,7 @@ exec=
keep=
shallow_depth=
no_progress=
+use_separate_remote=
test -t 1 || no_progress=--no-progress
quiet=
while case "$#" in 0) break ;; esac
@@ -33,6 +35,9 @@ do
-a|--a|--ap|--app|--appe|--appen|--append)
append=t
;;
+ --al|--all)
+ all=--all
+ ;;
--upl|--uplo|--uploa|--upload|--upload-|--upload-p|\
--upload-pa|--upload-pac|--upload-pack)
shift
@@ -63,6 +68,12 @@ do
-v|--verbose)
verbose=Yes
;;
+ --use-separate-remote)
+ use_separate_remote="--use-separate-remote"
+ ;;
+ --no-separate-remote)
+ use_separate_remote="--no-separate-remote"
+ ;;
-k|--k|--ke|--kee|--keep)
keep='-k -k'
;;
@@ -143,7 +154,9 @@ esac
# branches file, and just fetch those and refspecs explicitly given.
# Otherwise we do what we always did.
-reflist=$(get_remote_refs_for_fetch "$@")
+if test -z "$all"; then
+ reflist=$(get_remote_refs_for_fetch "$@")
+fi
if test "$tags"
then
taglist=`IFS=' ' &&
@@ -165,8 +178,10 @@ fi
fetch_all_at_once () {
- eval=$(echo "$1" | git-fetch--tool parse-reflist "-")
- eval "$eval"
+ if test -z "$all"; then
+ eval=$(echo "$1" | git-fetch--tool parse-reflist "-")
+ eval "$eval"
+ fi
( : subshell because we muck with IFS
IFS=" $LF"
@@ -179,7 +194,8 @@ fetch_all_at_once () {
git-bundle unbundle "$remote" $rref ||
echo failed "$remote"
else
- if test -d "$remote" &&
+ if test -z "$all" &&
+ test -d "$remote" &&
# The remote might be our alternate. With
# this optimization we will bypass fetch-pack
@@ -203,7 +219,7 @@ fetch_all_at_once () {
echo "$ls_remote_result" | \
git-fetch--tool pick-rref "$rref" "-"
else
- git-fetch-pack --thin $exec $keep $shallow_depth \
+ git-fetch-pack --thin $all $exec $keep $shallow_depth \
$quiet $no_progress "$remote" $rref ||
echo failed "$remote"
fi
@@ -214,7 +230,7 @@ fetch_all_at_once () {
test -n "$verbose" && flags="$flags -v"
test -n "$force" && flags="$flags -f"
GIT_REFLOG_ACTION="$GIT_REFLOG_ACTION" \
- git-fetch--tool $flags native-store \
+ git-fetch--tool $flags $all $use_separate_remote native-store \
"$remote" "$remote_nick" "$refs"
)
) || exit
--
1.5.2.rc3.783.gc7476-dirty
^ permalink raw reply related
* [PATCH 12/16] builtin-fetch--tool: extend "native-store" for use in cloning
From: skimo @ 2007-05-18 19:25 UTC (permalink / raw)
To: git, Junio C Hamano
In-Reply-To: <11795163053812-git-send-email-skimo@liacs.nl>
From: Sven Verdoolaege <skimo@kotnet.org>
Signed-off-by: Sven Verdoolaege <skimo@kotnet.org>
---
builtin-fetch--tool.c | 48 ++++++++++++++++++++++++++++++++++++++++++++----
1 files changed, 44 insertions(+), 4 deletions(-)
diff --git a/builtin-fetch--tool.c b/builtin-fetch--tool.c
index ed4d5de..3441a4a 100644
--- a/builtin-fetch--tool.c
+++ b/builtin-fetch--tool.c
@@ -207,6 +207,32 @@ static void remove_keep_on_signal(int signo)
raise(signo);
}
+static char *construct_local_name(const char *remote_ref, const char *remote_nick,
+ int use_separate_remote)
+{
+ static char local_ref[PATH_MAX];
+ int len = strlen(remote_ref);
+
+ if (len >= 3 && !memcmp(remote_ref+len-3, "^{}", 3))
+ return NULL;
+ if (!strcmp(remote_ref, "HEAD"))
+ return "REMOTE_HEAD";
+ if (!prefixcmp(remote_ref, "refs/heads/")) {
+ if (snprintf(local_ref, sizeof(local_ref), "refs/%s%s/%s",
+ use_separate_remote ? "remotes/" : "heads",
+ use_separate_remote ? remote_nick : "",
+ remote_ref+11) > sizeof(local_ref))
+ die("Local branchname too long");
+ } else if (!prefixcmp(remote_ref, "refs/tags/")) {
+ if (snprintf(local_ref, sizeof(local_ref), "refs/tags/%s",
+ remote_ref+10) > sizeof(local_ref))
+ die("Local branchname too long");
+ } else
+ return NULL;
+
+ return local_ref;
+}
+
static char *find_local_name(const char *remote_name, const char *refs,
int *force_p, int *not_for_merge_p)
{
@@ -261,7 +287,8 @@ static int fetch_native_store(FILE *fp,
const char *remote,
const char *remote_nick,
const char *refs,
- int verbose, int force)
+ int verbose, int force,
+ int all, int use_separate_remote)
{
char buffer[1024];
int err = 0;
@@ -294,8 +321,12 @@ static int fetch_native_store(FILE *fp,
continue;
}
- local_name = find_local_name(cp, refs,
- &single_force, ¬_for_merge);
+ if (all)
+ local_name = construct_local_name(cp, remote_nick,
+ use_separate_remote);
+ else
+ local_name = find_local_name(cp, refs,
+ &single_force, ¬_for_merge);
if (!local_name)
continue;
err |= append_fetch_head(fp,
@@ -514,6 +545,8 @@ int cmd_fetch__tool(int argc, const char **argv, const char *prefix)
int verbose = 0;
int force = 0;
int sopt = 0;
+ int all = 0;
+ int use_separate_remote = 1;
while (1 < argc) {
const char *arg = argv[1];
@@ -523,6 +556,12 @@ int cmd_fetch__tool(int argc, const char **argv, const char *prefix)
force = 1;
else if (!strcmp("-s", arg))
sopt = 1;
+ else if (!strcmp("--all", arg))
+ all = 1;
+ else if (!strcmp("--use-separate-remote", arg))
+ use_separate_remote = 1;
+ else if (!strcmp("--no-separate-remote", arg))
+ use_separate_remote = 0;
else
break;
argc--;
@@ -554,7 +593,8 @@ int cmd_fetch__tool(int argc, const char **argv, const char *prefix)
return error("fetch-native-store takes 3 args");
fp = fopen(git_path("FETCH_HEAD"), "a");
result = fetch_native_store(fp, argv[2], argv[3], argv[4],
- verbose, force);
+ verbose, force, all,
+ use_separate_remote);
fclose(fp);
return result;
}
--
1.5.2.rc3.783.gc7476-dirty
^ permalink raw reply related
* [PATCH 11/16] git-fetch: skip empty arguments
From: skimo @ 2007-05-18 19:25 UTC (permalink / raw)
To: git, Junio C Hamano
In-Reply-To: <11795163053812-git-send-email-skimo@liacs.nl>
From: Sven Verdoolaege <skimo@kotnet.org>
This makes it easier for scripts to call git-fetch with options
that may or may not be set.
Signed-off-by: Sven Verdoolaege <skimo@kotnet.org>
---
git-fetch.sh | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/git-fetch.sh b/git-fetch.sh
index 0e05cf1..dbeca14 100755
--- a/git-fetch.sh
+++ b/git-fetch.sh
@@ -76,6 +76,8 @@ do
-*)
usage
;;
+ '')
+ ;;
*)
break
;;
--
1.5.2.rc3.783.gc7476-dirty
^ permalink raw reply related
* [PATCH 08/16] unpack-trees.c: assume submodules are clean
From: skimo @ 2007-05-18 19:24 UTC (permalink / raw)
To: git, Junio C Hamano
In-Reply-To: <11795163053812-git-send-email-skimo@liacs.nl>
From: Sven Verdoolaege <skimo@kotnet.org>
If the submodules are not clean, then we will get an error
when we actally do the checkout.
Signed-off-by: Sven Verdoolaege <skimo@kotnet.org>
---
unpack-trees.c | 43 ++++++++++++++++++++++++++++++++++---------
1 files changed, 34 insertions(+), 9 deletions(-)
diff --git a/unpack-trees.c b/unpack-trees.c
index 5fa637a..e979bc5 100644
--- a/unpack-trees.c
+++ b/unpack-trees.c
@@ -5,6 +5,7 @@
#include "cache-tree.h"
#include "unpack-trees.h"
#include "progress.h"
+#include "refs.h"
#define DBRT_DEBUG 1
@@ -426,11 +427,24 @@ static void invalidate_ce_path(struct cache_entry *ce)
cache_tree_invalidate_path(active_cache_tree, ce->name);
}
-static int verify_clean_subdirectory(const char *path, const char *action,
+/* Check that checking out ce->sha1 in subdir ce->name is not
+ * going to overwrite any working files.
+ *
+ * FIXME: implement this function, so we can detect problems
+ * early, rather than waiting until we actually try to checkout
+ * the submodules.
+ */
+static int verify_clean_submodule(struct cache_entry *ce, const char *action,
+ struct unpack_trees_options *o)
+{
+ return 0;
+}
+
+static int verify_clean_subdirectory(struct cache_entry *ce, const char *action,
struct unpack_trees_options *o)
{
/*
- * we are about to extract "path"; we would not want to lose
+ * we are about to extract "ce->name"; we would not want to lose
* anything in the existing directory there.
*/
int namelen;
@@ -438,13 +452,24 @@ static int verify_clean_subdirectory(const char *path, const char *action,
struct dir_struct d;
char *pathbuf;
int cnt = 0;
+ unsigned char sha1[20];
+
+ if (S_ISDIRLNK(ntohl(ce->ce_mode)) &&
+ resolve_gitlink_ref(ce->name, "HEAD", sha1) == 0) {
+ /* If we are not going to update the submodule, then
+ * we don't care.
+ */
+ if (!o->submodules || !hashcmp(sha1, ce->sha1))
+ return 0;
+ verify_clean_submodule(ce, action, o);
+ }
/*
* First let's make sure we do not have a local modification
* in that directory.
*/
- namelen = strlen(path);
- pos = cache_name_pos(path, namelen);
+ namelen = strlen(ce->name);
+ pos = cache_name_pos(ce->name, namelen);
if (0 <= pos)
return cnt; /* we have it as nondirectory */
pos = -pos - 1;
@@ -452,7 +477,7 @@ static int verify_clean_subdirectory(const char *path, const char *action,
struct cache_entry *ce = active_cache[i];
int len = ce_namelen(ce);
if (len < namelen ||
- strncmp(path, ce->name, namelen) ||
+ strncmp(ce->name, ce->name, namelen) ||
ce->name[namelen] != '/')
break;
/*
@@ -470,16 +495,16 @@ static int verify_clean_subdirectory(const char *path, const char *action,
* present file that is not ignored.
*/
pathbuf = xmalloc(namelen + 2);
- memcpy(pathbuf, path, namelen);
+ memcpy(pathbuf, ce->name, namelen);
strcpy(pathbuf+namelen, "/");
memset(&d, 0, sizeof(d));
if (o->dir)
d.exclude_per_dir = o->dir->exclude_per_dir;
- i = read_directory(&d, path, pathbuf, namelen+1, NULL);
+ i = read_directory(&d, ce->name, pathbuf, namelen+1, NULL);
if (i)
die("Updating '%s' would lose untracked files in it",
- path);
+ ce->name);
free(pathbuf);
return cnt;
}
@@ -513,7 +538,7 @@ static void verify_absent(struct cache_entry *ce, const char *action,
* files that are in "foo/" we would lose
* it.
*/
- cnt = verify_clean_subdirectory(ce->name, action, o);
+ cnt = verify_clean_subdirectory(ce, action, o);
/*
* If this removed entries from the index,
--
1.5.2.rc3.783.gc7476-dirty
^ permalink raw reply related
* [PATCH 10/16] git-checkout: pass --submodules option to git-read-tree
From: skimo @ 2007-05-18 19:24 UTC (permalink / raw)
To: git, Junio C Hamano
In-Reply-To: <11795163053812-git-send-email-skimo@liacs.nl>
From: Sven Verdoolaege <skimo@kotnet.org>
Signed-off-by: Sven Verdoolaege <skimo@kotnet.org>
---
git-checkout.sh | 20 +++++++++++++++-----
1 files changed, 15 insertions(+), 5 deletions(-)
diff --git a/git-checkout.sh b/git-checkout.sh
index 6b6facf..cbb1f00 100755
--- a/git-checkout.sh
+++ b/git-checkout.sh
@@ -1,6 +1,6 @@
#!/bin/sh
-USAGE='[-q] [-f] [-b <new_branch>] [-m] [<branch>] [<paths>...]'
+USAGE='[-q] [-f] [--submodules] [--no-submodules] [-b <new_branch>] [-m] [<branch>] [<paths>...]'
SUBDIRECTORY_OK=Sometimes
. git-sh-setup
require_work_tree
@@ -16,6 +16,7 @@ track=
newbranch=
newbranch_log=
merge=
+submodules=
quiet=
v=-v
LF='
@@ -46,6 +47,15 @@ while [ "$#" != "0" ]; do
-m)
merge=1
;;
+ *,--su|*,--sub|*,--subm|*,--submo|*,--submod|*,--submodu|*,--submodul|\
+ *,--submodule|*,--submodules)
+ submodules="--submodules"
+ ;;
+ *,--no-su|*,--no-sub|*,--no-subm|*,--no-submo|*,--no-submod|\
+ *,--no-submodu|*,--no-submodul|\
+ *,--no-submodule|*,--no-submodules)
+ submodules="--no-submodules"
+ ;;
"-q")
quiet=1
v=
@@ -199,10 +209,10 @@ fi
if [ "$force" ]
then
- git-read-tree $v --reset -u $new
+ git-read-tree $v $submodules --reset -u $new
else
git-update-index --refresh >/dev/null
- merge_error=$(git-read-tree -m -u --exclude-per-directory=.gitignore $old $new 2>&1) || (
+ merge_error=$(git-read-tree $submodules -m -u --exclude-per-directory=.gitignore $old $new 2>&1) || (
case "$merge" in
'')
echo >&2 "$merge_error"
@@ -212,7 +222,7 @@ else
# Match the index to the working tree, and do a three-way.
git diff-files --name-only | git update-index --remove --stdin &&
work=`git write-tree` &&
- git read-tree $v --reset -u $new || exit
+ git read-tree $v $submodules --reset -u $new || exit
eval GITHEAD_$new='${new_name:-${branch:-$new}}' &&
eval GITHEAD_$work=local &&
@@ -223,7 +233,7 @@ else
# this is not a real merge before committing, but just carrying
# the working tree changes along.
unmerged=`git ls-files -u`
- git read-tree $v --reset $new
+ git read-tree $v $submodules --reset $new
case "$unmerged" in
'') ;;
*)
--
1.5.2.rc3.783.gc7476-dirty
^ permalink raw reply related
* [PATCH 03/16] http.h: make fill_active_slots a function pointer
From: skimo @ 2007-05-18 19:24 UTC (permalink / raw)
To: git, Junio C Hamano
In-Reply-To: <11795163053812-git-send-email-skimo@liacs.nl>
From: Sven Verdoolaege <skimo@kotnet.org>
This allows us to use the methods provided by http.c
from within libgit, in particular config.c.
Signed-off-by: Sven Verdoolaege <skimo@kotnet.org>
---
http-fetch.c | 5 ++++-
http-push.c | 5 ++++-
http.h | 2 +-
3 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/http-fetch.c b/http-fetch.c
index 09baedc..53fb2a9 100644
--- a/http-fetch.c
+++ b/http-fetch.c
@@ -317,7 +317,7 @@ static void release_object_request(struct object_request *obj_req)
}
#ifdef USE_CURL_MULTI
-void fill_active_slots(void)
+static void fetch_fill_active_slots(void)
{
struct object_request *obj_req = object_queue_head;
struct active_request_slot *slot = active_queue_head;
@@ -1031,6 +1031,9 @@ int main(int argc, const char **argv)
}
url = argv[arg];
+#ifdef USE_CURL_MULTI
+ fill_active_slots = fetch_fill_active_slots;
+#endif
http_init();
no_pragma_header = curl_slist_append(no_pragma_header, "Pragma:");
diff --git a/http-push.c b/http-push.c
index e3f7675..d4c850b 100644
--- a/http-push.c
+++ b/http-push.c
@@ -794,7 +794,7 @@ static void finish_request(struct transfer_request *request)
}
#ifdef USE_CURL_MULTI
-void fill_active_slots(void)
+static void push_fill_active_slots(void)
{
struct transfer_request *request = request_queue_head;
struct transfer_request *next;
@@ -2355,6 +2355,9 @@ int main(int argc, char **argv)
memset(remote_dir_exists, -1, 256);
+#ifdef USE_CURL_MULTI
+ fill_active_slots = push_fill_active_slots;
+#endif
http_init();
no_pragma_header = curl_slist_append(no_pragma_header, "Pragma:");
diff --git a/http.h b/http.h
index 69b6b66..7a41cde 100644
--- a/http.h
+++ b/http.h
@@ -69,7 +69,7 @@ extern void finish_all_active_slots(void);
extern void release_active_slot(struct active_request_slot *slot);
#ifdef USE_CURL_MULTI
-extern void fill_active_slots(void);
+extern void (*fill_active_slots)(void);
extern void step_active_slots(void);
#endif
--
1.5.2.rc3.783.gc7476-dirty
^ permalink raw reply related
* Second round of support for cloning submodules
From: skimo @ 2007-05-18 19:24 UTC (permalink / raw)
To: git, Junio C Hamano
From: Sven Verdoolaege <skimo@kotnet.org>
This patch series implements a mechanism for cloning submodules.
Each submodule is specified by a 'submodule.<submodule>.url'
configuration option, e.g.,
bash-3.00$ ./git-config --remote=http://www.liacs.nl/~sverdool/isa.git --get-regexp 'submodule\..*\.url'
submodule.cloog.url /home/sverdool/public_html/cloog.git
submodule.cloog.url http://www.liacs.nl/~sverdool/cloog.git
git-clone will use the first url that works.
E.g., a
git clone --submodules ssh://liacs/~/public_html/isa.git
(which only works for me), will use the first url, while a
git clone --submodules http://www.liacs.nl/~sverdool/isa.git
will use the second.
The cloning of submodules is now handled inside git-fetch.
skimo
^ permalink raw reply
* [PATCH 02/16] git-config: add --remote option for reading config from remote repo
From: skimo @ 2007-05-18 19:24 UTC (permalink / raw)
To: git, Junio C Hamano
In-Reply-To: <11795163053812-git-send-email-skimo@liacs.nl>
From: Sven Verdoolaege <skimo@kotnet.org>
Signed-off-by: Sven Verdoolaege <skimo@kotnet.org>
---
Documentation/git-config.txt | 33 +++++++++++++++++++++---------
builtin-config.c | 44 ++++++++++++++++++++++++++++++++---------
cache.h | 1 +
config.c | 26 ++++++++++++++++++++++++
4 files changed, 84 insertions(+), 20 deletions(-)
diff --git a/Documentation/git-config.txt b/Documentation/git-config.txt
index 280ef20..76398ab 100644
--- a/Documentation/git-config.txt
+++ b/Documentation/git-config.txt
@@ -9,16 +9,25 @@ git-config - Get and set repository or global options
SYNOPSIS
--------
[verse]
-'git-config' [--system | --global] [type] name [value [value_regex]]
-'git-config' [--system | --global] [type] --add name value
-'git-config' [--system | --global] [type] --replace-all name [value [value_regex]]
-'git-config' [--system | --global] [type] --get name [value_regex]
-'git-config' [--system | --global] [type] --get-all name [value_regex]
-'git-config' [--system | --global] [type] --unset name [value_regex]
-'git-config' [--system | --global] [type] --unset-all name [value_regex]
-'git-config' [--system | --global] [type] --rename-section old_name new_name
-'git-config' [--system | --global] [type] --remove-section name
-'git-config' [--system | --global] -l | --list
+'git-config' [--system | --global | --remote=[<host>:]<directory ]
+ [type] name [value [value_regex]]
+'git-config' [--system | --global | --remote=[<host>:]<directory ]
+ [type] --add name value
+'git-config' [--system | --global | --remote=[<host>:]<directory ]
+ [type] --replace-all name [value [value_regex]]
+'git-config' [--system | --global | --remote=[<host>:]<directory ]
+ [type] --get name [value_regex]
+'git-config' [--system | --global | --remote=[<host>:]<directory ]
+ [type] --get-all name [value_regex]
+'git-config' [--system | --global | --remote=[<host>:]<directory ]
+ [type] --unset name [value_regex]
+'git-config' [--system | --global | --remote=[<host>:]<directory ]
+ [type] --unset-all name [value_regex]
+'git-config' [--system | --global | --remote=[<host>:]<directory ]
+ [type] --rename-section old_name new_name
+'git-config' [--system | --global | --remote=[<host>:]<directory ]
+ [type] --remove-section name
+'git-config' [--system | --global | --remote=[<host>:]<directory ] -l | --list
DESCRIPTION
-----------
@@ -80,6 +89,10 @@ OPTIONS
Use system-wide $(prefix)/etc/gitconfig rather than the repository
.git/config.
+--remote=[<host>:]<directory
+ Use remote config instead of the repository .git/config.
+ Only available for reading options.
+
--remove-section::
Remove the given section from the configuration file.
diff --git a/builtin-config.c b/builtin-config.c
index b2515f7..3a1e86c 100644
--- a/builtin-config.c
+++ b/builtin-config.c
@@ -2,8 +2,10 @@
#include "cache.h"
static const char git_config_set_usage[] =
-"git-config [ --global | --system ] [ --bool | --int ] [--get | --get-all | --get-regexp | --replace-all | --add | --unset | --unset-all] name [value [value_regex]] | --rename-section old_name new_name | --remove-section name | --list";
+"git-config [ --global | --system | --remote=[<host>:]<directory ] "
+"[ --bool | --int ] [--get | --get-all | --get-regexp | --replace-all | --add | --unset | --unset-all] name [value [value_regex]] | --rename-section old_name new_name | --remove-section name | --list";
+static char *dest;
static char *key;
static regex_t *key_regexp;
static regex_t *regexp;
@@ -104,15 +106,19 @@ static int get_value(const char* key_, const char* regex_)
}
}
- if (do_all && system_wide)
- git_config_from_file(show_config, system_wide);
- 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);
- if (!do_all && !seen && system_wide)
- git_config_from_file(show_config, system_wide);
+ if (dest)
+ git_config_from_remote(show_config, dest);
+ else {
+ if (do_all && system_wide)
+ git_config_from_file(show_config, system_wide);
+ 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);
+ if (!do_all && !seen && system_wide)
+ git_config_from_file(show_config, system_wide);
+ }
free(key);
if (regexp) {
@@ -155,8 +161,14 @@ int cmd_config(int argc, const char **argv, const char *prefix)
}
else if (!strcmp(argv[1], "--system"))
setenv("GIT_CONFIG", ETC_GITCONFIG, 1);
+ else if (!prefixcmp(argv[1], "--remote="))
+ dest = xstrdup(argv[1]+9);
else if (!strcmp(argv[1], "--rename-section")) {
int ret;
+ if (dest) {
+ fprintf(stderr, "Cannot rename on remote\n");
+ return 1;
+ }
if (argc != 4)
usage(git_config_set_usage);
ret = git_config_rename_section(argv[2], argv[3]);
@@ -170,6 +182,10 @@ int cmd_config(int argc, const char **argv, const char *prefix)
}
else if (!strcmp(argv[1], "--remove-section")) {
int ret;
+ if (dest) {
+ fprintf(stderr, "Cannot remove on remote\n");
+ return 1;
+ }
if (argc != 3)
usage(git_config_set_usage);
ret = git_config_rename_section(argv[2], NULL);
@@ -191,6 +207,10 @@ int cmd_config(int argc, const char **argv, const char *prefix)
case 2:
return get_value(argv[1], NULL);
case 3:
+ if (dest && prefixcmp(argv[1], "--get")) {
+ fprintf(stderr, "Cannot (un)set on remote\n");
+ return 1;
+ }
if (!strcmp(argv[1], "--unset"))
return git_config_set(argv[2], NULL);
else if (!strcmp(argv[1], "--unset-all"))
@@ -209,6 +229,10 @@ int cmd_config(int argc, const char **argv, const char *prefix)
return git_config_set(argv[1], argv[2]);
case 4:
+ if (dest && prefixcmp(argv[1], "--get")) {
+ fprintf(stderr, "Cannot (un)set on remote\n");
+ return 1;
+ }
if (!strcmp(argv[1], "--unset"))
return git_config_set_multivar(argv[2], NULL, argv[3], 0);
else if (!strcmp(argv[1], "--unset-all"))
diff --git a/cache.h b/cache.h
index e34958b..6acc330 100644
--- a/cache.h
+++ b/cache.h
@@ -501,6 +501,7 @@ extern int update_server_info(int);
typedef int (*config_fn_t)(const char *, const char *);
extern int git_default_config(const char *, const char *);
extern int git_config_from_file(config_fn_t fn, const char *);
+extern int git_config_from_remote(config_fn_t fn, char *dest);
extern int git_config(config_fn_t fn);
extern int git_config_int(const char *, const char *);
extern int git_config_bool(const char *, const char *);
diff --git a/config.c b/config.c
index 0614c2b..dbfae3f 100644
--- a/config.c
+++ b/config.c
@@ -6,9 +6,12 @@
*
*/
#include "cache.h"
+#include "pkt-line.h"
#define MAXNAME (256)
+static const char *dumpconfig = "git-dump-config";
+
static FILE *config_file;
static const char *config_file_name;
static int config_linenr;
@@ -403,6 +406,29 @@ int git_config_from_file(config_fn_t fn, const char *filename)
return ret;
}
+int git_config_from_remote(config_fn_t fn, char *dest)
+{
+ int ret;
+ int fd[2];
+ pid_t pid;
+ static char var[MAXNAME];
+ static char value[1024];
+
+ pid = git_connect(fd, dest, dumpconfig);
+ if (pid < 0)
+ return 1;
+ ret = 0;
+ while (packet_read_line(fd[0], var, sizeof(var))) {
+ if (!packet_read_line(fd[0], value, sizeof(value)))
+ die("Missing value");
+ fn(var, value);
+ }
+ close(fd[0]);
+ close(fd[1]);
+ ret |= finish_connect(pid);
+ return !!ret;
+}
+
int git_config(config_fn_t fn)
{
int ret = 0;
--
1.5.2.rc3.783.gc7476-dirty
^ permalink raw reply related
* [PATCH 01/16] Add dump-config
From: skimo @ 2007-05-18 19:24 UTC (permalink / raw)
To: git, Junio C Hamano
In-Reply-To: <11795163053812-git-send-email-skimo@liacs.nl>
From: Sven Verdoolaege <skimo@kotnet.org>
This command dumps the config of a repository and will be used
to read config options from a remote site.
Signed-off-by: Sven Verdoolaege <skimo@kotnet.org>
---
.gitignore | 1 +
Documentation/cmd-list.perl | 1 +
Documentation/git-dump-config.txt | 37 +++++++++++++++++++++++++++++++++++++
Makefile | 1 +
daemon.c | 7 +++++++
dump-config.c | 29 +++++++++++++++++++++++++++++
6 files changed, 76 insertions(+), 0 deletions(-)
create mode 100644 Documentation/git-dump-config.txt
create mode 100644 dump-config.c
diff --git a/.gitignore b/.gitignore
index 4dc0c39..d4e5492 100644
--- a/.gitignore
+++ b/.gitignore
@@ -38,6 +38,7 @@ git-diff-files
git-diff-index
git-diff-tree
git-describe
+git-dump-config
git-fast-import
git-fetch
git-fetch--tool
diff --git a/Documentation/cmd-list.perl b/Documentation/cmd-list.perl
index 443802a..fa04615 100755
--- a/Documentation/cmd-list.perl
+++ b/Documentation/cmd-list.perl
@@ -103,6 +103,7 @@ git-diff-files plumbinginterrogators
git-diff-index plumbinginterrogators
git-diff mainporcelain
git-diff-tree plumbinginterrogators
+git-dump-config synchelpers
git-fast-import ancillarymanipulators
git-fetch mainporcelain
git-fetch-pack synchingrepositories
diff --git a/Documentation/git-dump-config.txt b/Documentation/git-dump-config.txt
new file mode 100644
index 0000000..370781c
--- /dev/null
+++ b/Documentation/git-dump-config.txt
@@ -0,0 +1,37 @@
+git-dump-config(1)
+====================
+
+NAME
+----
+git-dump-config - Dump config options
+
+
+SYNOPSIS
+--------
+'git-dump-config' <directory>
+
+DESCRIPTION
+-----------
+Invoked by 'git-config --remote' and dumps the config file to the
+other end over the git protocol.
+
+This command is usually not invoked directly by the end user. The UI
+for the protocol is on the 'git-config' side, where it is used to get
+options from a remote repository.
+
+OPTIONS
+-------
+<directory>::
+ The repository to get the config options from.
+
+Author
+------
+Written by Sven Verdoolaege.
+
+Documentation
+--------------
+Documentation by Sven Verdoolaege.
+
+GIT
+---
+Part of the gitlink:git[7] suite
diff --git a/Makefile b/Makefile
index 29243c6..37eb861 100644
--- a/Makefile
+++ b/Makefile
@@ -240,6 +240,7 @@ PROGRAMS = \
git-fast-import$X \
git-merge-base$X \
git-daemon$X \
+ git-dump-config$X \
git-merge-index$X git-mktag$X git-mktree$X git-patch-id$X \
git-peek-remote$X git-receive-pack$X \
git-send-pack$X git-shell$X \
diff --git a/daemon.c b/daemon.c
index e74ecac..3e5ebf3 100644
--- a/daemon.c
+++ b/daemon.c
@@ -378,10 +378,17 @@ static int receive_pack(void)
return -1;
}
+static int dump_config(void)
+{
+ execl_git_cmd("dump-config", ".", NULL);
+ return -1;
+}
+
static struct daemon_service daemon_service[] = {
{ "upload-archive", "uploadarch", upload_archive, 0, 1 },
{ "upload-pack", "uploadpack", upload_pack, 1, 1 },
{ "receive-pack", "receivepack", receive_pack, 0, 1 },
+ { "dump-config", "dumpconfig", dump_config, 0, 1 },
};
static void enable_service(const char *name, int ena) {
diff --git a/dump-config.c b/dump-config.c
new file mode 100644
index 0000000..355920d
--- /dev/null
+++ b/dump-config.c
@@ -0,0 +1,29 @@
+#include "git-compat-util.h"
+#include "cache.h"
+#include "pkt-line.h"
+
+static const char dump_config_usage[] = "git-dump-config <dir>";
+
+static int dump_config(const char *var, const char *value)
+{
+ packet_write(1, "%s", var);
+ packet_write(1, "%s", value);
+ return 0;
+}
+
+int main(int argc, char **argv)
+{
+ char *dir;
+
+ if (argc != 2)
+ usage(dump_config_usage);
+
+ dir = argv[1];
+ if (!enter_repo(dir, 0))
+ die("'%s': unable to chdir or not a git archive", dir);
+
+ git_config(dump_config);
+ packet_flush(1);
+
+ return 0;
+}
--
1.5.2.rc3.783.gc7476-dirty
^ permalink raw reply related
* [PATCH 04/16] git-config: read remote config files over HTTP
From: skimo @ 2007-05-18 19:24 UTC (permalink / raw)
To: git, Junio C Hamano
In-Reply-To: <11795163053812-git-send-email-skimo@liacs.nl>
From: Sven Verdoolaege <skimo@kotnet.org>
Signed-off-by: Sven Verdoolaege <skimo@kotnet.org>
---
Makefile | 7 ++++++-
builtin-config.c | 8 ++++++--
config.c | 16 +++++++++++++++-
http.c | 10 ++++++----
http.h | 2 +-
http_config.h | 1 +
http_config_curl.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++
http_config_none.c | 6 ++++++
8 files changed, 93 insertions(+), 9 deletions(-)
create mode 100644 http_config.h
create mode 100644 http_config_curl.c
create mode 100644 http_config_none.c
diff --git a/Makefile b/Makefile
index 37eb861..bce8514 100644
--- a/Makefile
+++ b/Makefile
@@ -319,7 +319,8 @@ LIB_OBJS = \
write_or_die.o trace.o list-objects.o grep.o match-trees.o \
alloc.o merge-file.o path-list.o help.o unpack-trees.o $(DIFF_OBJS) \
color.o wt-status.o archive-zip.o archive-tar.o shallow.o utf8.o \
- convert.o attr.o decorate.o progress.o mailmap.o symlinks.o
+ convert.o attr.o decorate.o progress.o mailmap.o symlinks.o \
+ $(HTTP_CONFIG_OBJ)
BUILTIN_OBJS = \
builtin-add.o \
@@ -526,6 +527,10 @@ ifndef NO_CURL
ifndef NO_EXPAT
EXPAT_LIBEXPAT = -lexpat
endif
+ HTTP_CONFIG_OBJ = http_config_curl.o http.o
+ EXTLIBS += $(CURL_LIBCURL)
+else
+ HTTP_CONFIG_OBJ = http_config_none.o
endif
ifndef NO_OPENSSL
diff --git a/builtin-config.c b/builtin-config.c
index 3a1e86c..7e18f73 100644
--- a/builtin-config.c
+++ b/builtin-config.c
@@ -147,8 +147,12 @@ int cmd_config(int argc, const char **argv, const char *prefix)
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], "--list") || !strcmp(argv[1], "-l")) {
+ if (dest)
+ return git_config_from_remote(show_all_config, dest);
+ else
+ return git_config(show_all_config);
+ }
else if (!strcmp(argv[1], "--global")) {
char *home = getenv("HOME");
if (home) {
diff --git a/config.c b/config.c
index dbfae3f..fc2162b 100644
--- a/config.c
+++ b/config.c
@@ -7,6 +7,7 @@
*/
#include "cache.h"
#include "pkt-line.h"
+#include "http_config.h"
#define MAXNAME (256)
@@ -406,6 +407,16 @@ int git_config_from_file(config_fn_t fn, const char *filename)
return ret;
}
+static int config_from_http(config_fn_t fn, char *dest)
+{
+ char config_temp[50];
+ if (git_http_fetch_config(dest, config_temp, sizeof(config_temp)))
+ return 1;
+ git_config_from_file(fn, config_temp);
+ unlink(config_temp);
+ return 0;
+}
+
int git_config_from_remote(config_fn_t fn, char *dest)
{
int ret;
@@ -414,7 +425,10 @@ int git_config_from_remote(config_fn_t fn, char *dest)
static char var[MAXNAME];
static char value[1024];
- pid = git_connect(fd, dest, dumpconfig);
+ if (!prefixcmp(dest, "http://"))
+ return config_from_http(fn, dest);
+
+ pid = git_connect(fd, dest, dumpconfig, 0);
if (pid < 0)
return 1;
ret = 0;
diff --git a/http.c b/http.c
index ae27e0c..c8237cb 100644
--- a/http.c
+++ b/http.c
@@ -25,6 +25,8 @@ long curl_low_speed_limit = -1;
long curl_low_speed_time = -1;
int curl_ftp_no_epsv = 0;
+void (*fill_active_slots)(void) = NULL;
+
struct curl_slist *pragma_header;
struct active_request_slot *active_queue_head = NULL;
@@ -394,7 +396,8 @@ void step_active_slots(void)
} while (curlm_result == CURLM_CALL_MULTI_PERFORM);
if (num_transfers < active_requests) {
process_curl_messages();
- fill_active_slots();
+ if (fill_active_slots)
+ fill_active_slots();
}
}
#endif
@@ -458,9 +461,8 @@ void release_active_slot(struct active_request_slot *slot)
curl_easy_cleanup(slot->curl);
slot->curl = NULL;
}
-#ifdef USE_CURL_MULTI
- fill_active_slots();
-#endif
+ if (fill_active_slots)
+ fill_active_slots();
}
static void finish_active_slot(struct active_request_slot *slot)
diff --git a/http.h b/http.h
index 7a41cde..7f29ff8 100644
--- a/http.h
+++ b/http.h
@@ -68,8 +68,8 @@ extern void run_active_slot(struct active_request_slot *slot);
extern void finish_all_active_slots(void);
extern void release_active_slot(struct active_request_slot *slot);
-#ifdef USE_CURL_MULTI
extern void (*fill_active_slots)(void);
+#ifdef USE_CURL_MULTI
extern void step_active_slots(void);
#endif
diff --git a/http_config.h b/http_config.h
new file mode 100644
index 0000000..25f5c19
--- /dev/null
+++ b/http_config.h
@@ -0,0 +1 @@
+int git_http_fetch_config(const char *repo, char *config_file, int len);
diff --git a/http_config_curl.c b/http_config_curl.c
new file mode 100644
index 0000000..88317cf
--- /dev/null
+++ b/http_config_curl.c
@@ -0,0 +1,52 @@
+#include "http_config.h"
+#include "http.h"
+
+int git_http_fetch_config(const char *repo, char *config, int config_len)
+{
+ char url[PATH_MAX];
+ int len = strlen(repo);
+
+ int fd;
+ FILE *configfile;
+ struct active_request_slot *slot;
+ struct slot_results results;
+
+ strcpy(url, repo);
+ while (len > 0 && url[len-1] == '/')
+ --len;
+ snprintf(url+len, sizeof(url)-len, "/config");
+
+ fd = git_mkstemp(config, config_len, ".config_XXXXXX");
+ if (fd >= 0)
+ configfile = fdopen(fd, "w");
+ if (fd < 0 || !configfile)
+ return error("Unable to open local file %s for config",
+ config);
+
+ http_init();
+
+ slot = get_active_slot();
+ slot->results = &results;
+ curl_easy_setopt(slot->curl, CURLOPT_FILE, configfile);
+ curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite);
+ curl_easy_setopt(slot->curl, CURLOPT_URL, url);
+ slot->local = configfile;
+
+ if (start_active_slot(slot)) {
+ run_active_slot(slot);
+ if (results.curl_result != CURLE_OK) {
+ fclose(configfile);
+ warning("Unable to get config %s\n%s", url,
+ curl_errorstr);
+ }
+ } else {
+ fclose(configfile);
+ return error("Unable to start request");
+ }
+
+ http_cleanup();
+
+ fclose(configfile);
+
+ return 0;
+}
diff --git a/http_config_none.c b/http_config_none.c
new file mode 100644
index 0000000..860ae84
--- /dev/null
+++ b/http_config_none.c
@@ -0,0 +1,6 @@
+#include "http_config.h"
+
+int git_http_fetch_config(const char *repo, char *config_file, int len)
+{
+ return error("Reading http config files not supported");
+}
--
1.5.2.rc3.783.gc7476-dirty
^ permalink raw reply related
* [PATCH] gitweb: Remove git_blame (superseded by git_blame2)
From: Petr Baudis @ 2007-05-18 19:22 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
This patch definitely removes git_blame() from the source and renames
git_blame2() to git_blame(); it was already the default handler for the
blame action for a long time and it has been actually broken for some time
now (I'm not sure how long), so noone probably cares about it much (I have
an alternative trivial patch to fix it too). All the information listing is
already included in git_blame2() output now.
Signed-off-by: Petr Baudis <pasky@suse.cz>
---
gitweb/gitweb.perl | 101 +---------------------------------------------------
1 files changed, 2 insertions(+), 99 deletions(-)
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index 2dc7be8..f67ba22 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -473,7 +473,7 @@ $git_dir = "$projectroot/$project" if $project;
# dispatch
my %actions = (
- "blame" => \&git_blame2,
+ "blame" => \&git_blame,
"blame_incremental" => \&git_blame_incremental,
"blame_data" => \&git_blame_data,
"blobdiff" => \&git_blobdiff,
@@ -3704,7 +3704,7 @@ HTML
}
-sub git_blame2 {
+sub git_blame {
my $fd;
my $ftype;
@@ -3820,103 +3820,6 @@ HTML
git_footer_html();
}
-sub git_blame {
- my $fd;
-
- my ($have_blame) = gitweb_check_feature('blame');
- if (!$have_blame) {
- die_error('403 Permission denied', "Permission denied");
- }
- die_error('404 Not Found', "File name not defined") if (!$file_name);
- $hash_base ||= git_get_head_hash($project);
- die_error(undef, "Couldn't find base commit") unless ($hash_base);
- my %co = parse_commit($hash_base)
- or die_error(undef, "Reading commit failed");
- if (!defined $hash) {
- $hash = git_get_hash_by_path($hash_base, $file_name, "blob")
- or die_error(undef, "Error lookup file");
- }
- open ($fd, "-|", git_cmd(), "annotate", '-l', '-t', '-r', $file_name, $hash_base)
- or die_error(undef, "Open git-annotate failed");
- git_header_html();
- my $formats_nav =
- $cgi->a({-href => href(action=>"blob", hash=>$hash, hash_base=>$hash_base, file_name=>$file_name)},
- "blob") .
- " | " .
- $cgi->a({-href => href(action=>"history", hash=>$hash, hash_base=>$hash_base, file_name=>$file_name)},
- "history") .
- " | " .
- $cgi->a({-href => href(action=>"blame", file_name=>$file_name), -class => "blamelink"},
- "HEAD");
- git_print_page_nav('','', $hash_base,$co{'tree'},$hash_base, $formats_nav);
- git_print_header_div('commit', esc_html($co{'title'}), $hash_base);
- git_print_page_path($file_name, 'blob', $hash_base);
- print "<div class=\"page_body\">\n";
- print <<HTML;
-<table class="blame">
- <tr>
- <th>Commit</th>
- <th>Age</th>
- <th>Author</th>
- <th>Line</th>
- <th>Data</th>
- </tr>
-HTML
- my @line_class = (qw(light dark));
- my $line_class_len = scalar (@line_class);
- my $line_class_num = $#line_class;
- while (my $line = <$fd>) {
- my $long_rev;
- my $short_rev;
- my $author;
- my $time;
- my $lineno;
- my $data;
- my $age;
- my $age_str;
- my $age_class;
-
- chomp $line;
- $line_class_num = ($line_class_num + 1) % $line_class_len;
-
- if ($line =~ m/^([0-9a-fA-F]{40})\t\(\s*([^\t]+)\t(\d+) [+-]\d\d\d\d\t(\d+)\)(.*)$/) {
- $long_rev = $1;
- $author = $2;
- $time = $3;
- $lineno = $4;
- $data = $5;
- } else {
- print qq( <tr><td colspan="5" class="error">Unable to parse: $line</td></tr>\n);
- next;
- }
- $short_rev = substr ($long_rev, 0, 8);
- $age = time () - $time;
- $age_str = age_string ($age);
- $age_str =~ s/ / /g;
- $age_class = age_class($age);
- $author = esc_html ($author);
- $author =~ s/ / /g;
-
- $data = untabify($data);
- $data = esc_html ($data);
-
- print <<HTML;
- <tr class="$line_class[$line_class_num]">
- <td class="sha1"><a href="${\href (action=>"commit", hash=>$long_rev)}" class="text">$short_rev..</a></td>
- <td class="$age_class">$age_str</td>
- <td>$author</td>
- <td class="linenr"><a id="$lineno" href="#$lineno" class="linenr">$lineno</a></td>
- <td class="pre">$data</td>
- </tr>
-HTML
- } # while (my $line = <$fd>)
- print "</table>\n\n";
- close $fd
- or print "Reading blob failed.\n";
- print "</div>";
- git_footer_html();
-}
-
sub git_tags {
my $head = git_get_head_hash($project);
git_header_html();
^ permalink raw reply related
* [PATCH] gitweb: Extra columns in blame
From: Petr Baudis @ 2007-05-18 19:17 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
This patch adds extra columns to blame output, containing
line author and creation date. These columns are by default hidden by
display: none but by clicking on the expansion "button" you can display
them (and hide again). I think seeing this information without tooltips
fishing can give much better overview of the content evolution.
This patch depends on the interactive blame patch (but can be factored out;
the common required parts are just the blame.js infrastructure).
Signed-off-by: Petr Baudis <pasky@suse.cz>
---
gitweb/blame.js | 45 ++++++++++++++++++++++++++++++++++++++++++++-
gitweb/gitweb.css | 5 +++++
gitweb/gitweb.perl | 23 +++++++++++++++++++----
3 files changed, 68 insertions(+), 5 deletions(-)
diff --git a/gitweb/blame.js b/gitweb/blame.js
index 88b6499..438bc9c 100644
--- a/gitweb/blame.js
+++ b/gitweb/blame.js
@@ -1,4 +1,41 @@
// Copyright (C) 2007, Fredrik Kuivinen <frekui@gmail.com>
+// Copyright (C) 2007, Petr Baudis <pasky@suse.cz>
+
+
+// blame extra columns
+
+// I would like to note here that JavaScript is utterly stupid.
+function findStyleRule(styleName) {
+ for (i = 0; i < document.styleSheets.length; i++) {
+ for (j = 0; j < document.styleSheets[i].cssRules.length; j++) {
+ var rule = document.styleSheets[i].cssRules[j];
+ if (rule.selectorText == styleName) {
+ return rule;
+ }
+ }
+ }
+}
+var extra_column_rule;
+
+var extra_columns = 0;
+function extra_blame_columns() {
+ if (!extra_column_rule)
+ extra_column_rule = findStyleRule("th.extra_column, td.extra_column");
+
+ if (!extra_columns) {
+ document.getElementById("columns_expander").innerHTML = "[-]";
+ extra_column_rule.style.cssText = extra_column_rule.style.cssText.replace("none", "table-cell");
+ extra_columns = 1;
+ } else {
+ document.getElementById("columns_expander").innerHTML = "[+]";
+ extra_column_rule.style.cssText = extra_column_rule.style.cssText.replace("table-cell", "none");
+ extra_columns = 0;
+ }
+}
+
+
+// blame_interactive
+
var DEBUG = 0;
function debug(str)
@@ -72,14 +109,20 @@ function handleLine(commit)
zeroPad(date.getUTCSeconds());
tr.firstChild.title = commit.author + ', ' + dateStr + ' ' + timeStr;
var shaAnchor = tr.firstChild.firstChild;
+ var authorField = tr.firstChild.nextSibling;
+ var dateField = tr.firstChild.nextSibling.nextSibling;
if (i == 0) {
shaAnchor.href = baseUrl + ';a=commit;h=' + commit.sha1;
shaAnchor.innerHTML = commit.sha1.substr(0, 8);
+ authorField.innerHTML = commit.author;
+ dateField.innerHTML = dateStr + ' ' + timeStr;
} else {
shaAnchor.innerHTML = '';
+ authorField.innerHTML = '';
+ dateField.innerHTML = '';
}
- var lineAnchor = tr.firstChild.nextSibling.firstChild;
+ var lineAnchor = tr.firstChild.nextSibling.nextSibling.nextSibling.firstChild;
lineAnchor.href = baseUrl + ';a=blame;hb=' + commit.sha1 +
';f=' + commit.filename + '#l' + commit.srcline;
resline++;
diff --git a/gitweb/gitweb.css b/gitweb/gitweb.css
index 9f0822f..b76e839 100644
--- a/gitweb/gitweb.css
+++ b/gitweb/gitweb.css
@@ -488,3 +488,8 @@ span.match {
div.binary {
font-style: italic;
}
+
+/* This selector is hardcoded in gitweb.perl */
+th.extra_column, td.extra_column {
+ display: none;
+}
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index cc671b1..2dc7be8 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -3671,9 +3671,14 @@ sub git_blame_incremental {
my $last_rev;
print "<script type=\"text/javascript\" src=\"$blamejs\"></script>\n";
print <<HTML;
+
<div class="page_body">
<table class="blame">
-<tr><th>Commit</th><th>Line</th><th>Data</th></tr>
+<tr><th>Commit <a href="javascript:extra_blame_columns()" id="columns_expander">[+]</a></th>
+<th class="extra_column">Author</th>
+<th class="extra_column">Date</th>
+<th>Line</th>
+<th>Data</th></tr>
HTML
my %metainfo = ();
my $linenr = 0;
@@ -3682,6 +3687,8 @@ HTML
$linenr += 1;
print "<tr id=\"l$linenr\" class=\"light2\">";
print '<td class="sha1"><a href=""></a></td>';
+ print "<td class=\"extra_column\"></td>";
+ print "<td class=\"extra_column\"></td>";
print "<td class=\"linenr\"><a class=\"linenr\" href=\"\">$linenr</a></td><td class=\"pre\">" . esc_html($_) . "</td>\n";
print "</tr>\n"
}
@@ -3738,10 +3745,16 @@ sub git_blame2 {
my $num_colors = scalar(@rev_color);
my $current_color = 0;
my $last_rev;
+ print "<script type=\"text/javascript\" src=\"$blamejs\"></script>\n";
print <<HTML;
+
<div class="page_body">
<table class="blame">
-<tr><th>Commit</th><th>Line</th><th>Data</th></tr>
+<tr><th>Commit <a href="javascript:extra_blame_columns()" id="columns_expander">[+]</a></th>
+<th class="extra_column">Author</th>
+<th class="extra_column">Date</th>
+<th>Line</th>
+<th>Data</th></tr>
HTML
my %metainfo = ();
while (1) {
@@ -3771,15 +3784,17 @@ HTML
}
print "<tr class=\"$rev_color[$current_color]\">\n";
if ($group_size) {
+ my $rowspan = $group_size > 1 ? " rowspan=\"$group_size\"" : "";
print "<td class=\"sha1\"";
print " title=\"". esc_html($author) . ", $date\"";
- print " rowspan=\"$group_size\"" if ($group_size > 1);
- print ">";
+ print "$rowspan>";
print $cgi->a({-href => href(action=>"commit",
hash=>$full_rev,
file_name=>$file_name)},
esc_html($rev));
print "</td>\n";
+ print "<td class=\"extra_column\" $rowspan>". esc_html($author) . "</td>";
+ print "<td class=\"extra_column\" $rowspan>". $date . "</td>";
}
open (my $dd, "-|", git_cmd(), "rev-parse", "$full_rev^")
or die_error(undef, "Open git-rev-parse failed");
^ permalink raw reply related
* Re: merge summaries
From: Linus Torvalds @ 2007-05-18 19:13 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Steffen Prohaska, Git Mailing List
In-Reply-To: <7vodki55px.fsf@assigned-by-dhcp.cox.net>
On Fri, 18 May 2007, Junio C Hamano wrote:
>
> This does not necessarily mean that your lieutenants should not
> use merge.summary when they pull from other trees (or inside
> their own repository to merge in the topics). They need to
> however disable it with --no-summary when they pull from you
> when they choose to merge instead of rebase to adjust to the
> updated infrastructure in your tree.
Yes, the problem is that people *will* get it wrong, so right now I'd
discourage people from even trying to enable merge summaries unless they
are the top-level maintainer.
Of course, we could have some heuristics to make it possibly work well
enough in practice that we could make it useful to more people:
- take the "merge.summary" field from the "remote" description for any
shorthand cases, always defaulting to "off" (regardless of what the
"merge.summary" config value is)
End result: "git pull origin" would never generate a merge summary,
unless somebody explicitly sets
[remote "origin"]
mergesummary = true
- use the "merge.summary" flag only for explicitly named remotes (and
possibly add "--summary" so that people can choose to never do it by
default, but do it explicitly for when they pull from a sublieutenant)
Hmm?
Linus
^ permalink raw reply
* Re: Smart fetch via HTTP?
From: Joel Becker @ 2007-05-18 19:01 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Matthieu Moy, git
In-Reply-To: <alpine.LFD.0.98.0705181123590.3890@woody.linux-foundation.org>
On Fri, May 18, 2007 at 11:27:22AM -0700, Linus Torvalds wrote:
> Well, we could try to support the git protocol over port 80..
>
> IOW, it's probably easier to try to get people to use
>
> git clone git://some.host:80/project
>
> and just run git-daemon on port 80, than it is to try to set of magic cgi
> scripts etc.
Can we tech the git-daemon to parse the HTTP headers
(specifically, the URL) and return the appropriate HTTP response?
> And yes, I do realize that in theory you can have http-aware firewalls
> that expect to see the normal http sequences in the first few packets in
> order to pass things through, but I seriously doubt it's very common.
It's not about packet scanning, it's about GET vs CONNECT. If
the proxy allows GET but not CONNECT, it's going to forward the HTTP
protocol to the server, and git-daemon is going to see "GET /project
HTTP/1.1" as its first input. Now, perhaps we can cook that up behind
some apache so that apache handles vhosting the URL, then calls
git-daemon which can take the stdin. So we'd be doing POST, not GET.
On the other hand, if the proxy allows CONNECT, there is no
scanning for HTTP sequences done by the proxy. It just allows all raw
data (as it figures you're doing SSL).
A normal company needs to have their firewall allow CONNECT to
9418. Then git proxying over HTTP is possible to a standard git-daemon.
Joel
--
"The first requisite of a good citizen in this republic of ours
is that he shall be able and willing to pull his weight."
- Theodore Roosevelt
Joel Becker
Principal Software Developer
Oracle
E-mail: joel.becker@oracle.com
Phone: (650) 506-8127
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox