adding gitAttr

now containing qgit, stgit, topGit, hg2git
updating gitGit (git dev version), adding qgit-git (dev version)

svn path=/nixpkgs/trunk/; revision=13816
This commit is contained in:
Marc Weber
2009-01-20 22:15:42 +00:00
parent 269f914ab7
commit 0ad62a0edb
12 changed files with 140 additions and 42 deletions
@@ -0,0 +1,71 @@
/* moving all git tools into one attribute set because git is unlikely to be
* referenced by other packages and you can get a fast overview.
*/
args: with args; with pkgs;
let
inherit (pkgs) stdenv fetchurl getConfig;
inherit (pkgs.bleedingEdgeRepos) sourceByName;
in
rec {
git = import ./git {
inherit fetchurl stdenv curl openssl zlib expat perl gettext
asciidoc texinfo xmlto docbook2x
docbook_xsl docbook_xml_dtd_42 libxslt
cpio tcl tk makeWrapper subversion;
svnSupport = getConfig ["git" "svnSupport"] false; # for git-svn support
guiSupport = getConfig ["git" "guiSupport"] false;
perlLibs = [perlLWP perlURI perlTermReadKey subversion];
};
gitGit = import ./git/git-git.nix {
inherit fetchurl stdenv curl openssl zlib expat perl gettext
asciidoc texinfo xmlto docbook2x
docbook_xsl docbook_xml_dtd_42 libxslt
cpio tcl tk makeWrapper subversion autoconf;
inherit (bleedingEdgeRepos) sourceByName;
svnSupport = getConfig ["git" "svnSupport"] false; # for git-svn support
guiSupport = getConfig ["git" "guiSupport"] false;
perlLibs = [perlLWP perlURI perlTermReadKey subversion];
};
qgit = import ./qgit {
inherit fetchurl stdenv;
inherit (xlibs) libXext libX11;
qt = qt3;
};
qgitGit = import ./qgit/qgit-git.nix {
inherit fetchurl stdenv;
inherit (xlibs) libXext libX11;
inherit (bleedingEdgeRepos) sourceByName;
qt = qt4;
};
stgit = import ./stgit {
inherit fetchurl stdenv python git;
};
topGit = stdenv.mkDerivation {
name = "TopGit-git-patched";
src = sourceByName "topGit"; # destination directory is patched
installPhase = ''
mkdir -p $out/etc/bash_completion.d
make install
mv contrib/tg-completion.bash $out/etc/bash_completion.d
'';
dontPatchELF = 1;
meta = {
description = "TopGit aims to make handling of large amount of interdependent topic branches easier";
homepage = http://repo.or.cz/w/topgit.git; # maybe there is also another one, I haven't checked
license = "GPLv2";
};
};
hg2git = import ./hg2git {
inherit fetchurl stdenv mercurial coreutils git makeWrapper;
inherit (bleedingEdgeRepos) sourceByName;
};
}
@@ -0,0 +1,98 @@
{ fetchurl, stdenv, curl, openssl, zlib, expat, perl, gettext, cpio
, asciidoc, texinfo, xmlto, docbook2x, docbook_xsl, docbook_xml_dtd_42
, libxslt, tcl, tk, makeWrapper
, svnSupport, subversion, perlLibs
, guiSupport
}:
# `git-svn' support requires Subversion and various Perl libraries.
assert svnSupport -> (subversion != null && perlLibs != [] && subversion.perlBindings);
stdenv.mkDerivation rec {
name = "git-1.6.0.4";
src = fetchurl {
url = "mirror://kernel/software/scm/git/${name}.tar.bz2";
sha256 = "0q5jnix65zn58dhd9xc3sjpamli0lh1bnsz1b9riwwicgwssrk7q";
};
patches = [ ./docbook2texi.patch ];
buildInputs = [curl openssl zlib expat gettext cpio makeWrapper]
++ # documentation tools
[ asciidoc texinfo xmlto docbook2x
docbook_xsl docbook_xml_dtd_42 libxslt ]
++ stdenv.lib.optionals guiSupport [tcl tk];
makeFlags = "prefix=\${out} PERL_PATH=${perl}/bin/perl SHELL_PATH=${stdenv.shell}";
# FIXME: "make check" requires Sparse; the Makefile must be tweaked
# so that `SPARSE_FLAGS' corresponds to the current architecture...
#doCheck = true;
postInstall =
''
notSupported(){
echo -e "#\!/bin/sh\necho '`basename $1` not supported, $2'\nexit 1" > "$1"
chmod +x $1
}
# Install Emacs mode.
echo "installing Emacs mode..."
ensureDir $out/share/emacs/site-lisp
cp -p contrib/emacs/*.el $out/share/emacs/site-lisp
'' # */
+ (if svnSupport then
''# wrap git-svn
gitperllib=$out/lib/site_perl
for i in ${builtins.toString perlLibs}; do
gitperllib=$gitperllib:$i/lib/site_perl
done
wrapProgram "$out/libexec/git-core/git-svn" \
--set GITPERLLIB "$gitperllib" \
--prefix PATH : "${subversion}/bin" ''
else '' # replace git-svn by notification script
notSupported $out/bin/git-svn "reinstall with config git = { svnSupport = true } set"
'')
+ ''# Install man pages and Info manual
make PERL_PATH="${perl}/bin/perl" cmd-list.made install install-info \
-C Documentation ''
+ (if guiSupport then ''
# Wrap Tcl/Tk programs
for prog in bin/gitk libexec/git-core/git-gui
do
wrapProgram "$out/$prog" \
--set TK_LIBRARY "${tk}/lib/tk8.4" \
--prefix PATH : "${tk}/bin"
done
'' else ''
# Don't wrap Tcl/Tk, replace them by notification scripts
for prog in bin/gitk libexec/git-core/git-gui
do
notSupported "$out/$prog" \
"reinstall with config git = { guiSupport = true; } set"
done
'')
+ ''# install bash completion script
d="$out/etc/bash_completion.d"
ensureDir $d; cp contrib/completion/git-completion.bash "$d"
'';
meta = {
license = "GPLv2";
homepage = http://git.or.cz;
description = "Git, a popular distributed version control system";
longDescription = ''
Git, a popular distributed version control system designed to
handle very large projects with speed and efficiency.
'';
};
}
@@ -0,0 +1,28 @@
make sure `gitman.info' isn't produced since it's broken (duplicate
node names).
diff --git a/Documentation/Makefile b/Documentation/Makefile
--- a/Documentation/Makefile
+++ b/Documentation/Makefile
@@ -84,7 +84,7 @@ man1: $(DOC_MAN1)
man5: $(DOC_MAN5)
man7: $(DOC_MAN7)
-info: git.info gitman.info
+info: git.info
install: man
$(INSTALL) -d -m 755 $(DESTDIR)$(man1dir)
@@ -96,10 +96,9 @@ install: man
install-info: info
$(INSTALL) -d -m 755 $(DESTDIR)$(infodir)
- $(INSTALL) -m 644 git.info gitman.info $(DESTDIR)$(infodir)
+ $(INSTALL) -m 644 git.info $(DESTDIR)$(infodir)
if test -r $(DESTDIR)$(infodir)/dir; then \
$(INSTALL_INFO) --info-dir=$(DESTDIR)$(infodir) git.info ;\
- $(INSTALL_INFO) --info-dir=$(DESTDIR)$(infodir) gitman.info ;\
else \
echo "No directory found in $(DESTDIR)$(infodir)" >&2 ; \
fi
@@ -0,0 +1,37 @@
This patch does two things: (1) use the right name for `docbook2texi',
and (2) make sure `gitman.info' isn't produced since it's broken (duplicate
node names).
diff --git a/Documentation/Makefile b/Documentation/Makefile
--- a/Documentation/Makefile
+++ b/Documentation/Makefile
@@ -48,7 +48,7 @@ DOC_REF = origin/man
infodir?=$(prefix)/share/info
MAKEINFO=makeinfo
INSTALL_INFO=install-info
-DOCBOOK2X_TEXI=docbook2x-texi
+DOCBOOK2X_TEXI=docbook2texi
ifndef PERL_PATH
PERL_PATH = /usr/bin/perl
endif
@@ -84,7 +84,7 @@ man1: $(DOC_MAN1)
man5: $(DOC_MAN5)
man7: $(DOC_MAN7)
-info: git.info gitman.info
+info: git.info
install: man
$(INSTALL) -d -m 755 $(DESTDIR)$(man1dir)
@@ -96,10 +96,9 @@ install: man
install-info: info
$(INSTALL) -d -m 755 $(DESTDIR)$(infodir)
- $(INSTALL) -m 644 git.info gitman.info $(DESTDIR)$(infodir)
+ $(INSTALL) -m 644 git.info $(DESTDIR)$(infodir)
if test -r $(DESTDIR)$(infodir)/dir; then \
$(INSTALL_INFO) --info-dir=$(DESTDIR)$(infodir) git.info ;\
- $(INSTALL_INFO) --info-dir=$(DESTDIR)$(infodir) gitman.info ;\
else \
echo "No directory found in $(DESTDIR)$(infodir)" >&2 ; \
fi
@@ -0,0 +1,100 @@
{ fetchurl, stdenv, curl, openssl, zlib, expat, perl, gettext, cpio
, asciidoc, texinfo, xmlto, docbook2x, docbook_xsl, docbook_xml_dtd_42
, libxslt, tcl, tk, makeWrapper
, svnSupport, subversion, perlLibs
, guiSupport
, sourceByName
, autoconf
}:
# `git-svn' support requires Subversion and various Perl libraries.
# FIXME: We should make sure Subversion comes with its Perl bindings.
assert svnSupport -> (subversion != null && perlLibs != [] && subversion.perlBindings);
assert svnSupport -> subversion.perlBindings;
stdenv.mkDerivation rec {
# the glob patch adds the filter [touching paths (glob)] to gitk
# contact marco-oweber@gmx.de if you want to know more details
name = "git-git-with-glob-patch";
src = sourceByName "git";
patchePhase = ''
patch -p1 < ${./docbook2texi-2.patch}
sed -i 's/docbook2x-texi/docbook2texi/gc' Documentation/Makefile
'';
# maybe this introduces unneccessary dependencies ?
patchPhase = "
unset patchPhase; patchPhase;
sed -i 's=/usr/bin/perl=$perl/bin/perl=g' `find -type f`
sed -i 's=/bin/pwd=pwd=g' `find -type f`
";
inherit perl;
buildInputs = [curl openssl zlib expat gettext cpio makeWrapper autoconf]
++ # documentation tools
[ asciidoc texinfo xmlto docbook2x
docbook_xsl docbook_xml_dtd_42 libxslt ]
++ stdenv.lib.optionals guiSupport [tcl tk];
preConfigure = "autoconf";
makeFlags = "install install-doc prefix=\${out} PERL_PATH=${perl}/bin/perl SHELL_PATH=${stdenv.shell}";
postInstall =
''
# Install Emacs mode.
echo "installing Emacs mode..."
ensureDir $out/share/emacs/site-lisp
cp -p contrib/emacs/*.el $out/share/emacs/site-lisp
wrapArgs=
'' # */
+ (if svnSupport then
''# wrap git-svn
gitperllib=$out/lib/site_perl
for i in ${builtins.toString perlLibs}; do
gitperllib=$gitperllib:$i/lib/site_perl
done
#cp git-svn "$out/bin"
wrapArgs="$wrapArgs --set GITPERLLIB $gitperllib"
wrapArgs="$wrapArgs --prefix PATH : ${subversion}/bin"
'' else "")
+ ''# Install man pages and Info manual
make PERL_PATH="${perl}/bin/perl" cmd-list.made install install-info \
-C Documentation ''
+ (if guiSupport then ''
# Wrap Tcl/Tk programs
wrapArgs="$wrapArgs --set TK_LIBRARY ${tk}/lib/tk8.4"
wrapArgs="$wrapArgs --prefix PATH : ${tk}/bin"
'' else "")
+ ''# Wrap `git-clone'
wrapArgs="$wrapArgs --prefix PATH : ${cpio}/bin"
for b in $out/bin/{git,gitk}; do
[ -f "$b" ] && eval "wrapProgram $b $wrapArgs"
done
''
+ ''# install bash completion script
d="$out/etc/bash_completion.d"
ensureDir $d; cp contrib/completion/git-completion.bash "$d"
'';
meta = {
license = "GPLv2";
homepage = http://git.or.cz;
description = "Git, a popular distributed version control system";
longDescription = ''
Git, a popular distributed version control system designed to
handle very large projects with speed and efficiency.
'';
};
}
@@ -0,0 +1,529 @@
diff --git a/builtin-add.c b/builtin-add.c
index bf13aa3..02c6751 100644
--- a/builtin-add.c
+++ b/builtin-add.c
@@ -123,6 +123,7 @@ int add_files_to_cache(const char *prefix, const char **pathspec, int flags)
init_revisions(&rev, prefix);
setup_revisions(0, NULL, &rev, NULL);
rev.prune_data = pathspec;
+ rev.glob_paths = 0; /* git-add has its own filename matching machinery */
rev.diffopt.output_format = DIFF_FORMAT_CALLBACK;
rev.diffopt.format_callback = update_callback;
data.flags = flags;
diff --git a/builtin-blame.c b/builtin-blame.c
index 9bced3b..237d1fe 100644
--- a/builtin-blame.c
+++ b/builtin-blame.c
@@ -343,7 +343,7 @@ static struct origin *find_origin(struct scoreboard *sb,
paths[0] = origin->path;
paths[1] = NULL;
- diff_tree_setup_paths(paths, &diff_opts);
+ diff_tree_setup_paths(paths, &diff_opts, 0);
if (diff_setup_done(&diff_opts) < 0)
die("diff-setup");
@@ -417,7 +417,7 @@ static struct origin *find_rename(struct scoreboard *sb,
diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT;
diff_opts.single_follow = origin->path;
paths[0] = NULL;
- diff_tree_setup_paths(paths, &diff_opts);
+ diff_tree_setup_paths(paths, &diff_opts, 0);
if (diff_setup_done(&diff_opts) < 0)
die("diff-setup");
@@ -1099,7 +1099,7 @@ static int find_copy_in_parent(struct scoreboard *sb,
diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT;
paths[0] = NULL;
- diff_tree_setup_paths(paths, &diff_opts);
+ diff_tree_setup_paths(paths, &diff_opts, 0);
if (diff_setup_done(&diff_opts) < 0)
die("diff-setup");
@@ -2346,6 +2346,11 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
parse_done:
argc = parse_options_end(&ctx);
+ if (revs.glob_paths) {
+ error("git blame does not support `--glob-paths'");
+ usage_with_options(blame_opt_usage, options);
+ }
+
if (!blame_move_score)
blame_move_score = BLAME_DEFAULT_MOVE_SCORE;
if (!blame_copy_score)
diff --git a/builtin-reset.c b/builtin-reset.c
index 2e5a886..6026b34 100644
--- a/builtin-reset.c
+++ b/builtin-reset.c
@@ -128,14 +128,15 @@ static void update_index_from_diff(struct diff_queue_struct *q,
}
static int read_from_tree(const char *prefix, const char **argv,
- unsigned char *tree_sha1)
+ unsigned char *tree_sha1, int glob_paths)
{
struct lock_file *lock = xcalloc(1, sizeof(struct lock_file));
int index_fd, index_was_discarded = 0;
struct diff_options opt;
memset(&opt, 0, sizeof(opt));
- diff_tree_setup_paths(get_pathspec(prefix, (const char **)argv), &opt);
+ diff_tree_setup_paths(get_pathspec(prefix, (const char **)argv),
+ &opt, glob_paths);
opt.output_format = DIFF_FORMAT_CALLBACK;
opt.format_callback = update_index_from_diff;
opt.format_callback_data = &index_was_discarded;
@@ -171,6 +172,7 @@ static const char *reset_type_names[] = { "mixed", "soft", "hard", NULL };
int cmd_reset(int argc, const char **argv, const char *prefix)
{
int i = 0, reset_type = NONE, update_ref_status = 0, quiet = 0;
+ int glob_paths = 0;
const char *rev = "HEAD";
unsigned char sha1[20], *orig = NULL, sha1_orig[20],
*old_orig = NULL, sha1_old_orig[20];
@@ -182,6 +184,8 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
OPT_SET_INT(0, "soft", &reset_type, "reset only HEAD", SOFT),
OPT_SET_INT(0, "hard", &reset_type,
"reset HEAD, index and working tree", HARD),
+ OPT_BOOLEAN(0, "glob-paths", &glob_paths,
+ "match paths with fnmatch"),
OPT_BOOLEAN('q', NULL, &quiet,
"disable showing new HEAD in hard reset and progress message"),
OPT_END()
@@ -246,7 +250,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
else if (reset_type != NONE)
die("Cannot do %s reset with paths.",
reset_type_names[reset_type]);
- return read_from_tree(prefix, argv + i, sha1);
+ return read_from_tree(prefix, argv + i, sha1, glob_paths);
}
if (reset_type == NONE)
reset_type = MIXED; /* by default */
diff --git a/builtin-update-index.c b/builtin-update-index.c
index 38eb53c..28b09a3 100644
--- a/builtin-update-index.c
+++ b/builtin-update-index.c
@@ -23,6 +23,7 @@ static int allow_replace;
static int info_only;
static int force_remove;
static int verbose;
+static int glob_paths;
static int mark_valid_only;
#define MARK_VALID 1
#define UNMARK_VALID 2
@@ -534,7 +535,7 @@ static int do_reupdate(int ac, const char **av,
struct cache_entry *old = NULL;
int save_nr;
- if (ce_stage(ce) || !ce_path_match(ce, pathspec))
+ if (ce_stage(ce) || !ce_path_match(ce, pathspec, glob_paths))
continue;
if (has_head)
old = read_one_ent(NULL, head_sha1,
@@ -659,6 +660,10 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
force_remove = 1;
continue;
}
+ if (!strcmp(path, "--glob-paths")) {
+ glob_paths = 1;
+ continue;
+ }
if (!strcmp(path, "-z")) {
line_termination = 0;
continue;
@@ -702,6 +707,8 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
usage(update_index_usage);
die("unknown option %s", path);
}
+ if (glob_paths)
+ die("--glob-paths without -g");
p = prefix_path(prefix, prefix_length, path);
update_one(p, NULL, 0);
if (set_executable_bit)
@@ -712,6 +719,8 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
if (read_from_stdin) {
struct strbuf buf, nbuf;
+ if (glob_paths)
+ die("--glob-paths without -g");
strbuf_init(&buf, 0);
strbuf_init(&nbuf, 0);
while (strbuf_getline(&buf, stdin, line_termination) != EOF) {
diff --git a/cache.h b/cache.h
index a779d92..5560195 100644
--- a/cache.h
+++ b/cache.h
@@ -387,7 +387,8 @@ extern int ce_same_name(struct cache_entry *a, struct cache_entry *b);
extern int ie_match_stat(const struct index_state *, struct cache_entry *, struct stat *, unsigned int);
extern int ie_modified(const struct index_state *, struct cache_entry *, struct stat *, unsigned int);
-extern int ce_path_match(const struct cache_entry *ce, const char **pathspec);
+extern int ce_path_match(const struct cache_entry *ce, const char **pathspec,
+ int glob_paths);
extern int index_fd(unsigned char *sha1, int fd, struct stat *st, int write_object, enum object_type type, const char *path);
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);
diff --git a/diff-lib.c b/diff-lib.c
index e7eaff9..87925a2 100644
--- a/diff-lib.c
+++ b/diff-lib.c
@@ -77,7 +77,7 @@ int run_diff_files(struct rev_info *revs, unsigned int option)
DIFF_OPT_TST(&revs->diffopt, HAS_CHANGES))
break;
- if (!ce_path_match(ce, revs->prune_data))
+ if (!ce_path_match(ce, revs->prune_data, revs->glob_paths))
continue;
if (ce_stage(ce)) {
@@ -431,7 +431,7 @@ static int oneway_diff(struct cache_entry **src, struct unpack_trees_options *o)
if (tree == o->df_conflict_entry)
tree = NULL;
- if (ce_path_match(idx ? idx : tree, revs->prune_data))
+ if (ce_path_match(idx ? idx : tree, revs->prune_data, revs->glob_paths))
do_oneway_diff(o, idx, tree);
return 0;
@@ -508,6 +508,7 @@ int do_diff_cache(const unsigned char *tree_sha1, struct diff_options *opt)
init_revisions(&revs, NULL);
revs.prune_data = opt->paths;
+ revs.glob_paths = opt->glob_paths;
tree = parse_tree_indirect(tree_sha1);
if (!tree)
die("bad tree object %s", sha1_to_hex(tree_sha1));
diff --git a/diff-no-index.c b/diff-no-index.c
index f6994cf..ec549a7 100644
--- a/diff-no-index.c
+++ b/diff-no-index.c
@@ -240,6 +240,7 @@ void diff_no_index(struct rev_info *revs,
}
else
revs->diffopt.paths = argv + argc - 2;
+ revs->diffopt.glob_paths = 0;
revs->diffopt.nr_paths = 2;
DIFF_OPT_SET(&revs->diffopt, EXIT_WITH_STATUS);
diff --git a/diff.h b/diff.h
index 50fb5dd..56f0857 100644
--- a/diff.h
+++ b/diff.h
@@ -102,6 +102,7 @@ struct diff_options {
FILE *file;
int close_file;
+ int glob_paths;
int nr_paths;
const char **paths;
int *pathlens;
@@ -128,7 +129,8 @@ const char *diff_get_color(int diff_use_color, enum color_diff ix);
extern const char mime_boundary_leader[];
-extern void diff_tree_setup_paths(const char **paths, struct diff_options *);
+extern void diff_tree_setup_paths(const char **paths, struct diff_options *opt,
+ int glob_paths);
extern void diff_tree_release_paths(struct diff_options *);
extern int diff_tree(struct tree_desc *t1, struct tree_desc *t2,
const char *base, struct diff_options *opt);
diff --git a/gitk-git/gitk b/gitk-git/gitk
index fddcb45..18c5cbc 100644
--- a/gitk-git/gitk
+++ b/gitk-git/gitk
@@ -1866,6 +1866,7 @@ proc makewindow {} {
set gm [tk_optionMenu .tf.lbar.gdttype gdttype \
[mc "containing:"] \
[mc "touching paths:"] \
+ [mc "touching paths (glob):"] \
[mc "adding/removing string:"]]
trace add variable gdttype write gdttype_change
pack .tf.lbar.gdttype -side left -fill y
@@ -3588,6 +3589,11 @@ proc do_file_hl {serial} {
set highlight_paths [makepatterns $paths]
highlight_filelist
set gdtargs [concat -- $paths]
+ } elseif {$gdttype eq [mc "touching paths (glob):"]} {
+ if {[catch {set paths [shellsplit $highlight_files]}]} return
+ set highlight_paths $paths
+ highlight_filelist
+ set gdtargs [concat --glob-paths -- $paths]
} elseif {$gdttype eq [mc "adding/removing string:"]} {
set gdtargs [list "-S$highlight_files"]
} else {
diff --git a/read-cache.c b/read-cache.c
index 1648428..c11ded9 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -582,7 +582,8 @@ int ce_same_name(struct cache_entry *a, struct cache_entry *b)
return ce_namelen(b) == len && !memcmp(a->name, b->name, len);
}
-int ce_path_match(const struct cache_entry *ce, const char **pathspec)
+static int ce_path_match_standard(const struct cache_entry *ce,
+ const char **pathspec)
{
const char *match, *name;
int len;
@@ -608,6 +609,31 @@ int ce_path_match(const struct cache_entry *ce, const char **pathspec)
return 0;
}
+static int ce_path_match_globbed(const struct cache_entry *ce,
+ const char **pathspec)
+{
+ const char *match, *name;
+
+ if (!pathspec)
+ return 1;
+
+ name = ce->name;
+ while ((match = *pathspec++) != NULL) {
+ if (!fnmatch(match, name, 0))
+ return 1;
+ }
+ return 0;
+}
+
+int ce_path_match(const struct cache_entry *ce,
+ const char **pathspec, int glob_paths)
+{
+ if (glob_paths)
+ return ce_path_match_globbed(ce, pathspec);
+ else
+ return ce_path_match_standard(ce, pathspec);
+}
+
/*
* We fundamentally don't like some paths: we don't want
* dot or dot-dot anywhere, and for obvious reasons don't
diff --git a/revision.c b/revision.c
index 3897fec..0dd1091 100644
--- a/revision.c
+++ b/revision.c
@@ -519,6 +519,7 @@ static void cherry_pick_list(struct commit_list *list, struct rev_info *revs)
if (revs->diffopt.nr_paths) {
ids.diffopts.nr_paths = revs->diffopt.nr_paths;
ids.diffopts.paths = revs->diffopt.paths;
+ ids.diffopts.glob_paths = revs->diffopt.glob_paths; /* CHECKME */
ids.diffopts.pathlens = revs->diffopt.pathlens;
}
@@ -826,7 +827,7 @@ static void prepare_show_merge(struct rev_info *revs)
struct cache_entry *ce = active_cache[i];
if (!ce_stage(ce))
continue;
- if (ce_path_match(ce, revs->prune_data)) {
+ if (ce_path_match(ce, revs->prune_data, revs->glob_paths)) {
prune_num++;
prune = xrealloc(prune, sizeof(*prune) * prune_num);
prune[prune_num-2] = ce->name;
@@ -837,6 +838,7 @@ static void prepare_show_merge(struct rev_info *revs)
i++;
}
revs->prune_data = prune;
+ revs->glob_paths = 0;
revs->limited = 1;
}
@@ -1033,6 +1035,8 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
revs->min_age = approxidate(arg + 8);
} else if (!strcmp(arg, "--first-parent")) {
revs->first_parent_only = 1;
+ } else if (!strcmp(arg, "--glob-paths")) {
+ revs->glob_paths = 1;
} else if (!strcmp(arg, "-g") || !strcmp(arg, "--walk-reflogs")) {
init_reflog_walk(&revs->reflog_info);
} else if (!strcmp(arg, "--default")) {
@@ -1220,6 +1224,7 @@ void parse_revision_opt(struct rev_info *revs, struct parse_opt_ctx_t *ctx,
int setup_revisions(int argc, const char **argv, struct rev_info *revs, const char *def)
{
int i, flags, left, seen_dashdash;
+ const char **paths = NULL;
/* First, search for "--" */
seen_dashdash = 0;
@@ -1230,7 +1235,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
argv[i] = NULL;
argc = i;
if (argv[i + 1])
- revs->prune_data = get_pathspec(revs->prefix, argv + i + 1);
+ paths = argv + i + 1;
seen_dashdash = 1;
break;
}
@@ -1290,6 +1295,9 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
if (seen_dashdash || *arg == '^')
die("bad revision '%s'", arg);
+ if (revs->glob_paths)
+ die("--glob-paths without --");
+
/* If we didn't have a "--":
* (1) all filenames must exist;
* (2) all rev-args must not be interpretable
@@ -1301,10 +1309,19 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
revs->prune_data = get_pathspec(revs->prefix,
argv + i);
+ revs->glob_paths = 0;
break;
}
}
+ /* Third, handle paths listed after -- */
+ if (paths != NULL) {
+ if (revs->glob_paths)
+ revs->prune_data = paths;
+ else
+ revs->prune_data = get_pathspec(revs->prefix, paths);
+ }
+
if (revs->def == NULL)
revs->def = def;
if (revs->show_merge)
@@ -1333,12 +1350,14 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
revs->limited = 1;
if (revs->prune_data) {
- diff_tree_setup_paths(revs->prune_data, &revs->pruning);
+ diff_tree_setup_paths(revs->prune_data, &revs->pruning,
+ revs->glob_paths);
/* Can't prune commits with rename following: the paths change.. */
if (!DIFF_OPT_TST(&revs->diffopt, FOLLOW_RENAMES))
revs->prune = 1;
if (!revs->full_diff)
- diff_tree_setup_paths(revs->prune_data, &revs->diffopt);
+ diff_tree_setup_paths(revs->prune_data, &revs->diffopt,
+ revs->glob_paths);
}
if (revs->combine_merges) {
revs->ignore_merges = 0;
diff --git a/revision.h b/revision.h
index fa68c65..a68cdb8 100644
--- a/revision.h
+++ b/revision.h
@@ -32,6 +32,9 @@ struct rev_info {
void *prune_data;
unsigned int early_output;
+ /* whether prune_data contains fnmatch() patterns */
+ unsigned int glob_paths:1;
+
/* Traversal flags */
unsigned int dense:1,
prune:1,
diff --git a/tree-diff.c b/tree-diff.c
index bbb126f..0aa1e9b 100644
--- a/tree-diff.c
+++ b/tree-diff.c
@@ -82,6 +82,11 @@ static int compare_tree_entry(struct tree_desc *t1, struct tree_desc *t2, const
return 0;
}
+static int tree_entry_interesting_globbed(struct tree_desc *, const char *,
+ int, struct diff_options *);
+static int tree_entry_interesting_standard(struct tree_desc *, const char *,
+ int, struct diff_options *);
+
/*
* Is a tree entry interesting given the pathspec we have?
*
@@ -91,7 +96,19 @@ static int compare_tree_entry(struct tree_desc *t1, struct tree_desc *t2, const
* - zero for no
* - negative for "no, and no subsequent entries will be either"
*/
-static int tree_entry_interesting(struct tree_desc *desc, const char *base, int baselen, struct diff_options *opt)
+static int tree_entry_interesting(struct tree_desc *desc,
+ const char *base, int baselen, struct diff_options *opt)
+{
+ if (opt->glob_paths)
+ return tree_entry_interesting_globbed(desc, base,
+ baselen, opt);
+ else
+ return tree_entry_interesting_standard(desc, base,
+ baselen, opt);
+}
+
+static int tree_entry_interesting_standard(struct tree_desc *desc,
+ const char *base, int baselen, struct diff_options *opt)
{
const char *path;
const unsigned char *sha1;
@@ -190,6 +207,41 @@ static int tree_entry_interesting(struct tree_desc *desc, const char *base, int
return never_interesting; /* No matches */
}
+static int tree_entry_interesting_globbed(struct tree_desc *desc,
+ const char *base, int baselen, struct diff_options *opt)
+{
+ const char *path;
+ char *fullpath;
+ const unsigned char *sha1;
+ unsigned mode;
+ int i;
+ int pathlen;
+ int result;
+
+ if (!opt->nr_paths)
+ return 1;
+ sha1 = tree_entry_extract(desc, &path, &mode);
+ if (S_ISDIR(mode))
+ return 1;
+ pathlen = tree_entry_len(path, sha1);
+
+ fullpath = xmalloc(pathlen + baselen + 1);
+ memcpy(fullpath, base, baselen);
+ memcpy(fullpath + baselen, path, pathlen + 1);
+
+ result = 0;
+ for (i = 0; i < opt->nr_paths; i++) {
+ const char *match = opt->paths[i];
+ if (!fnmatch(match, fullpath, 0)) {
+ result = 1;
+ break;
+ }
+ }
+
+ free(fullpath);
+ return result;
+}
+
/* A whole sub-tree went away or appeared */
static void show_tree(struct diff_options *opt, const char *prefix, struct tree_desc *desc, const char *base, int baselen)
{
@@ -338,7 +390,7 @@ static void try_to_follow_renames(struct tree_desc *t1, struct tree_desc *t2, co
diff_opts.single_follow = opt->paths[0];
diff_opts.break_opt = opt->break_opt;
paths[0] = NULL;
- diff_tree_setup_paths(paths, &diff_opts);
+ diff_tree_setup_paths(paths, &diff_opts, 0);
if (diff_setup_done(&diff_opts) < 0)
die("unable to set up diff options to follow renames");
diff_tree(t1, t2, base, &diff_opts);
@@ -362,7 +414,7 @@ static void try_to_follow_renames(struct tree_desc *t1, struct tree_desc *t2, co
/* Update the path we use from now on.. */
diff_tree_release_paths(opt);
opt->paths[0] = xstrdup(p->one->path);
- diff_tree_setup_paths(opt->paths, opt);
+ diff_tree_setup_paths(opt->paths, opt, 0);
break;
}
}
@@ -440,11 +492,13 @@ void diff_tree_release_paths(struct diff_options *opt)
free(opt->pathlens);
}
-void diff_tree_setup_paths(const char **p, struct diff_options *opt)
+void diff_tree_setup_paths(const char **p, struct diff_options *opt,
+ int glob_paths)
{
opt->nr_paths = 0;
opt->pathlens = NULL;
opt->paths = NULL;
+ opt->glob_paths = glob_paths;
if (p) {
int i;
@@ -0,0 +1,26 @@
args: with args;
stdenv.mkDerivation {
name = "hg2git";
src = sourceByName "hg2git";
buildInputs =([mercurial.python mercurial makeWrapper]);
installPhase = ''
ensureDir $out/bin;
cp hg2git.sh hg2git.py $out/bin
cat >> $out/bin/hg2git-doc << EOF
#!${coreutils}/bin/cat
$(cat hg2git.txt)
EOF
chmod +x $out/bin/hg2git-doc
wrapProgram $out/bin/hg2git.sh \
--set PYTHONPATH "$(echo ${mercurial}/lib/python*/site-packages)"
'';
meta = {
description = "mercurial to git one way conversion";
homepage = "http://git.grml.org/?p=hg-to-git.git;a=summary";
license = "?"; # the .py file is GPLv2
};
}
@@ -0,0 +1,18 @@
{stdenv, fetchurl, qt, libXext, libX11}:
stdenv.mkDerivation rec {
name = "qgit-1.5.8";
meta =
{
license = "GPLv2";
homepage = "http://digilander.libero.it/mcostalba/";
description = "Graphical front-end to Git";
};
src = fetchurl
{
url = "mirror://sourceforge/qgit/${name}.tar.bz2";
sha256 = "0qmgd1cjny5aciljpvn2bczgdvlpgd2f7wzafda24zj4mzqnppsq";
};
buildInputs = [qt libXext libX11];
configureFlags = "CXXFLAGS=-O3";
}
@@ -0,0 +1,17 @@
{stdenv, fetchurl, qt, libXext, libX11, sourceByName}:
stdenv.mkDerivation rec {
name = "qgit-git";
meta =
{
license = "GPLv2";
homepage = "http://digilander.libero.it/mcostalba/";
description = "Graphical front-end to Git";
};
src = sourceByName "qgit";
buildInputs = [qt libXext libX11];
buildPhase = ''
qmake PREFIX=$out
make
'';
}
@@ -0,0 +1,25 @@
args:
args.stdenv.mkDerivation {
name = "stgit-0.14.3";
src = args.fetchurl {
url = http://homepage.ntlworld.com/cmarinas/stgit/stgit-0.14.3.tar.gz;
sha256 = "13gcvz6x91m2860n26xp12j0xsshzvwij03sfzm5g3ckm18ffkw7";
};
buildInputs =(with args; [python git]);
buildPhase = "true";
installPhase = ''
python ./setup.py install --prefix=$out
d="$out/etc/bash_completion.d"
ensureDir $d; ln -s "$out/share/stgit/contrib/stgit-completion.bash" "$d"
'';
meta = {
description = "quilt for git (stacking patches)";
homepage = http://procode.org/stgit/;
license = "GPL";
};
}