summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/RelNotes-1.5.3.txt16
-rw-r--r--Documentation/asciidoc.conf6
-rw-r--r--Documentation/git-branch.txt4
-rw-r--r--Documentation/git-stash.txt11
-rw-r--r--INSTALL7
-rw-r--r--Makefile26
-rw-r--r--builtin-mailinfo.c33
-rw-r--r--contrib/emacs/Makefile2
-rw-r--r--contrib/p4import/README1
-rw-r--r--contrib/p4import/git-p4import.py (renamed from git-p4import.py)0
-rw-r--r--contrib/p4import/git-p4import.txt (renamed from Documentation/git-p4import.txt)0
-rw-r--r--entry.c37
-rwxr-xr-xgit-filter-branch.sh31
-rwxr-xr-xgit-svn.perl5
-rw-r--r--git.spec.in29
-rw-r--r--t/lib-git-svn.sh34
-rwxr-xr-xt/t7400-submodule-basic.sh9
-rwxr-xr-xt/t9115-git-svn-dcommit-funky-renames.sh54
-rw-r--r--t/t9115/funky-names.dump103
-rw-r--r--unpack-trees.c75
20 files changed, 374 insertions, 109 deletions
diff --git a/Documentation/RelNotes-1.5.3.txt b/Documentation/RelNotes-1.5.3.txt
index 63e33b9..896ff1d 100644
--- a/Documentation/RelNotes-1.5.3.txt
+++ b/Documentation/RelNotes-1.5.3.txt
@@ -21,6 +21,8 @@ Updates since v1.5.2
* New commands and options.
+ - "git log --date=<format>" can use more formats: iso8601, rfc2822.
+
- The hunk header output from "git diff" family can be customized
with the attributes mechanism. See gitattributes(5) for details.
@@ -68,6 +70,10 @@ Updates since v1.5.2
- "git gc --aggressive" tells the command to spend more cycles
to optimize the repository harder.
+ - "git repack" learned a "window-memory" limit which
+ dynamically reduces the window size to stay within the
+ specified memory usage.
+
- "git repack" can be told to split resulting packs to avoid
exceeding limit specified with "--max-pack-size".
@@ -99,6 +105,9 @@ Updates since v1.5.2
* Updated behavior of existing commands.
+ - "git rm --cached" does not complain when removing a newly
+ added file from the index anymore.
+
- "git svn dcommit" retains local merge information.
- "git config" to set values also honors type flags like --bool
@@ -175,6 +184,11 @@ Updates since v1.5.2
concatenate them into a single line and treat the result as
"oneline".
+ - "git p4import" has been demoted to contrib status. For
+ a superior option, checkout the git-p4 front end to
+ git-fast-import (also in contrib). The man page and p4
+ rpm have been removed as well.
+
* Builds
- old-style function definitions (most notably, a function
@@ -218,6 +232,6 @@ this release, unless otherwise noted.
--
exec >/var/tmp/1
-O=v1.5.3-rc1
+O=v1.5.3-rc2
echo O=`git describe refs/heads/master`
git shortlog --no-merges $O..refs/heads/master ^refs/heads/maint
diff --git a/Documentation/asciidoc.conf b/Documentation/asciidoc.conf
index 6b6220d..af5b155 100644
--- a/Documentation/asciidoc.conf
+++ b/Documentation/asciidoc.conf
@@ -27,7 +27,13 @@ ifdef::backend-docbook[]
[listingblock]
<example><title>{title}</title>
<literallayout>
+ifdef::doctype-manpage[]
+&#10;.ft C&#10;
+endif::doctype-manpage[]
|
+ifdef::doctype-manpage[]
+&#10;.ft&#10;
+endif::doctype-manpage[]
</literallayout>
{title#}</example>
endif::backend-docbook[]
diff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt
index bb6b57d..bc6aa88 100644
--- a/Documentation/git-branch.txt
+++ b/Documentation/git-branch.txt
@@ -130,8 +130,8 @@ Delete unneeded branch::
------------
$ git clone git://git.kernel.org/.../git.git my.git
$ cd my.git
-$ git branch -d -r todo html man <1>
-$ git branch -D test <2>
+$ git branch -d -r origin/todo origin/html origin/man <1>
+$ git branch -D test <2>
------------
+
<1> delete remote-tracking branches "todo", "html", "man"
diff --git a/Documentation/git-stash.txt b/Documentation/git-stash.txt
index ad95ed9..17121ad 100644
--- a/Documentation/git-stash.txt
+++ b/Documentation/git-stash.txt
@@ -8,7 +8,8 @@ git-stash - Stash the changes in a dirty working directory away
SYNOPSIS
--------
[verse]
-'git-stash' (save | list | show [<stash>] | apply [<stash>] | clear)
+'git-stash' (list | show [<stash>] | apply [<stash>] | clear)
+'git-stash' [save] [message...]
DESCRIPTION
-----------
@@ -22,7 +23,9 @@ The modifications stashed away by this command can be listed with
`git-stash list`, inspected with `git-stash show`, and restored
(potentially on top of a different commit) with `git-stash apply`.
Calling git-stash without any arguments is equivalent to `git-stash
-save`.
+save`. A stash is by default listed as "WIP on 'branchname' ...", but
+you can give a more descriptive message on the command line when
+you create one.
The latest stash you created is stored in `$GIT_DIR/refs/stash`; older
stashes are found in the reflog of this reference and can be named using
@@ -48,8 +51,8 @@ list::
based on.
+
----------------------------------------------------------------
-stash@{0}: submit: 6ebd0e2... Add git-stash
-stash@{1}: master: 9cc0589... Merge branch 'master' of gfi
+stash@{0}: WIP on submit: 6ebd0e2... Update git-stash documentation
+stash@{1}: On master: 9cc0589... Add git-stash
----------------------------------------------------------------
show [<stash>]::
diff --git a/INSTALL b/INSTALL
index 63ba148..79e71b6 100644
--- a/INSTALL
+++ b/INSTALL
@@ -56,9 +56,8 @@ Issues of note:
- "zlib", the compression library. Git won't build without it.
- - "openssl". The git-rev-list program uses bignum support from
- openssl, and unless you specify otherwise, you'll also get the
- SHA1 library from here.
+ - "openssl". Unless you specify otherwise, you'll get the SHA1
+ library from here.
If you don't have openssl, you can use one of the SHA1 libraries
that come with git (git includes the one from Mozilla, and has
@@ -73,7 +72,7 @@ Issues of note:
management over DAV. Similar to "curl" above, this is optional.
- "wish", the Tcl/Tk windowing shell is used in gitk to show the
- history graphically
+ history graphically, and in git-gui.
- "ssh" is used to push and pull over the net
diff --git a/Makefile b/Makefile
index 5db3fb4..73b487f 100644
--- a/Makefile
+++ b/Makefile
@@ -112,8 +112,6 @@ all::
# Define NO_PERL_MAKEMAKER if you cannot use Makefiles generated by perl's
# MakeMaker (e.g. using ActiveState under Cygwin).
#
-# Define WITH_P4IMPORT to build and install Python git-p4import script.
-#
# Define NO_TCLTK if you do not want Tcl/Tk GUI.
#
# The TCL_PATH variable governs the location of the Tcl interpreter
@@ -223,20 +221,9 @@ SCRIPT_PERL = \
git-svnimport.perl git-cvsexportcommit.perl \
git-send-email.perl git-svn.perl
-SCRIPT_PYTHON = \
- git-p4import.py
-
-ifdef WITH_P4IMPORT
SCRIPTS = $(patsubst %.sh,%,$(SCRIPT_SH)) \
$(patsubst %.perl,%,$(SCRIPT_PERL)) \
- $(patsubst %.py,%,$(SCRIPT_PYTHON)) \
git-status git-instaweb
-else
-SCRIPTS = $(patsubst %.sh,%,$(SCRIPT_SH)) \
- $(patsubst %.perl,%,$(SCRIPT_PERL)) \
- git-status git-instaweb
-endif
-
# ... and all the rest that could be moved out of bindir to gitexecdir
PROGRAMS = \
@@ -286,9 +273,6 @@ endif
ifndef PERL_PATH
PERL_PATH = /usr/bin/perl
endif
-ifndef PYTHON_PATH
- PYTHON_PATH = /usr/local/bin/python
-endif
export PERL_PATH
@@ -711,7 +695,6 @@ prefix_SQ = $(subst ','\'',$(prefix))
SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH))
PERL_PATH_SQ = $(subst ','\'',$(PERL_PATH))
-PYTHON_PATH_SQ = $(subst ','\'',$(PYTHON_PATH))
TCLTK_PATH_SQ = $(subst ','\'',$(TCLTK_PATH))
LIBS = $(GITLIBS) $(EXTLIBS)
@@ -782,15 +765,6 @@ $(patsubst %.sh,%,$(SCRIPT_SH)) : % : %.sh
$(patsubst %.perl,%,$(SCRIPT_PERL)): perl/perl.mak
-$(patsubst %.py,%,$(SCRIPT_PYTHON)) : % : %.py
- $(RM) $@ $@+
- sed -e '1s|#!.*/python|#!$(PYTHON_PATH_SQ)|' \
- -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \
- -e 's/@@NO_CURL@@/$(NO_CURL)/g' \
- $@.py >$@+
- chmod +x $@+
- mv $@+ $@
-
perl/perl.mak: GIT-CFLAGS
$(QUIET_SUBDIR0)perl $(QUIET_SUBDIR1) PERL_PATH='$(PERL_PATH_SQ)' prefix='$(prefix_SQ)' $(@F)
diff --git a/builtin-mailinfo.c b/builtin-mailinfo.c
index 489c2c5..a37a4ff 100644
--- a/builtin-mailinfo.c
+++ b/builtin-mailinfo.c
@@ -499,15 +499,40 @@ static int decode_b_segment(char *in, char *ot, char *ep)
return 0;
}
+/*
+ * When there is no known charset, guess.
+ *
+ * Right now we assume that if the target is UTF-8 (the default),
+ * and it already looks like UTF-8 (which includes US-ASCII as its
+ * subset, of course) then that is what it is and there is nothing
+ * to do.
+ *
+ * Otherwise, we default to assuming it is Latin1 for historical
+ * reasons.
+ */
+static const char *guess_charset(const char *line, const char *target_charset)
+{
+ if (is_encoding_utf8(target_charset)) {
+ if (is_utf8(line))
+ return NULL;
+ }
+ return "latin1";
+}
+
static void convert_to_utf8(char *line, const char *charset)
{
- static const char latin_one[] = "latin1";
- const char *input_charset = *charset ? charset : latin_one;
- char *out = reencode_string(line, metainfo_charset, input_charset);
+ char *out;
+
+ if (!charset || !*charset) {
+ charset = guess_charset(line, metainfo_charset);
+ if (!charset)
+ return;
+ }
+ out = reencode_string(line, metainfo_charset, charset);
if (!out)
die("cannot convert from %s to %s\n",
- input_charset, metainfo_charset);
+ charset, metainfo_charset);
strcpy(line, out);
free(out);
}
diff --git a/contrib/emacs/Makefile b/contrib/emacs/Makefile
index 5e94d6f..a48540a 100644
--- a/contrib/emacs/Makefile
+++ b/contrib/emacs/Makefile
@@ -13,7 +13,7 @@ all: $(ELC)
install: all
$(INSTALL) -d $(DESTDIR)$(emacsdir)
- $(INSTALL_ELC) $(ELC) $(DESTDIR)$(emacsdir)
+ $(INSTALL_ELC) $(ELC:.elc=.el) $(ELC) $(DESTDIR)$(emacsdir)
%.elc: %.el
$(EMACS) -batch -f batch-byte-compile $<
diff --git a/contrib/p4import/README b/contrib/p4import/README
new file mode 100644
index 0000000..b9892b6
--- /dev/null
+++ b/contrib/p4import/README
@@ -0,0 +1 @@
+Please see contrib/fast-import/git-p4 for a better Perforce importer.
diff --git a/git-p4import.py b/contrib/p4import/git-p4import.py
index 0f3d97b..0f3d97b 100644
--- a/git-p4import.py
+++ b/contrib/p4import/git-p4import.py
diff --git a/Documentation/git-p4import.txt b/contrib/p4import/git-p4import.txt
index 9967587..9967587 100644
--- a/Documentation/git-p4import.txt
+++ b/contrib/p4import/git-p4import.txt
diff --git a/entry.c b/entry.c
index c540ae1..0625112 100644
--- a/entry.c
+++ b/entry.c
@@ -8,17 +8,40 @@ static void create_directories(const char *path, const struct checkout *state)
const char *slash = path;
while ((slash = strchr(slash+1, '/')) != NULL) {
+ struct stat st;
+ int stat_status;
+
len = slash - path;
memcpy(buf, path, len);
buf[len] = 0;
+
+ if (len <= state->base_dir_len)
+ /*
+ * checkout-index --prefix=<dir>; <dir> is
+ * allowed to be a symlink to an existing
+ * directory.
+ */
+ stat_status = stat(buf, &st);
+ else
+ /*
+ * if there currently is a symlink, we would
+ * want to replace it with a real directory.
+ */
+ stat_status = lstat(buf, &st);
+
+ if (!stat_status && S_ISDIR(st.st_mode))
+ continue; /* ok, it is already a directory. */
+
+ /*
+ * We know stat_status == 0 means something exists
+ * there and this mkdir would fail, but that is an
+ * error codepath; we do not care, as we unlink and
+ * mkdir again in such a case.
+ */
if (mkdir(buf, 0777)) {
- if (errno == EEXIST) {
- struct stat st;
- if (len > state->base_dir_len && state->force && !unlink(buf) && !mkdir(buf, 0777))
- continue;
- if (!stat(buf, &st) && S_ISDIR(st.st_mode))
- continue; /* ok */
- }
+ if (errno == EEXIST && state->force &&
+ !unlink(buf) && !mkdir(buf, 0777))
+ continue;
die("cannot create directory at %s", buf);
}
}
diff --git a/git-filter-branch.sh b/git-filter-branch.sh
index 5401970..0d000ed 100755
--- a/git-filter-branch.sh
+++ b/git-filter-branch.sh
@@ -8,8 +8,6 @@
# a new branch. You can specify a number of filters to modify the commits,
# files and trees.
-set -e
-
USAGE="git-filter-branch [-d TEMPDIR] [FILTERS] DESTBRANCH [REV-RANGE]"
. git-sh-setup
@@ -141,9 +139,10 @@ git show-ref "refs/heads/$dstbranch" 2> /dev/null &&
die "branch $dstbranch already exists"
test ! -e "$tempdir" || die "$tempdir already exists, please remove it"
-mkdir -p "$tempdir/t"
-cd "$tempdir/t"
-workdir="$(pwd)"
+mkdir -p "$tempdir/t" &&
+cd "$tempdir/t" &&
+workdir="$(pwd)" ||
+die ""
case "$GIT_DIR" in
/*)
@@ -155,12 +154,12 @@ esac
export GIT_DIR GIT_WORK_TREE=.
export GIT_INDEX_FILE="$(pwd)/../index"
-git read-tree # seed the index file
+git read-tree || die "Could not seed the index"
ret=0
-
-mkdir ../map # map old->new commit ids for rewriting parents
+# map old->new commit ids for rewriting parents
+mkdir ../map || die "Could not create map/ directory"
case "$filter_subdir" in
"")
@@ -170,7 +169,7 @@ case "$filter_subdir" in
*)
git rev-list --reverse --topo-order --default HEAD \
--parents --full-history "$@" -- "$filter_subdir"
-esac > ../revs
+esac > ../revs || die "Could not get the commits"
commits=$(wc -l <../revs | tr -d " ")
test $commits -eq 0 && die "Found nothing to rewrite"
@@ -186,10 +185,11 @@ while read commit parents; do
;;
*)
git read-tree -i -m $commit:"$filter_subdir"
- esac
+ esac || die "Could not initialize the index"
export GIT_COMMIT=$commit
- git cat-file commit "$commit" >../commit
+ git cat-file commit "$commit" >../commit ||
+ die "Cannot read commit $commit"
eval "$(set_ident AUTHOR <../commit)" ||
die "setting author failed for commit $commit"
@@ -199,7 +199,8 @@ while read commit parents; do
die "env filter failed: $filter_env"
if [ "$filter_tree" ]; then
- git checkout-index -f -u -a
+ git checkout-index -f -u -a ||
+ die "Could not checkout the index"
# files that $commit removed are now still in the working tree;
# remove them, else they would be added again
git ls-files -z --others | xargs -0 rm -f
@@ -240,7 +241,8 @@ case "$target_head" in
echo Nothing rewritten
;;
*)
- git update-ref refs/heads/"$dstbranch" $target_head
+ git update-ref refs/heads/"$dstbranch" $target_head ||
+ die "Could not update $dstbranch with $target_head"
if [ $(wc -l <../map/$src_head) -gt 1 ]; then
echo "WARNING: Your commit filter caused the head commit to expand to several rewritten commits. Only the first such commit was recorded as the current $dstbranch head but you will need to resolve the situation now (probably by manually merging the other commits). These are all the commits:" >&2
sed 's/^/ /' ../map/$src_head >&2
@@ -277,7 +279,8 @@ if [ "$filter_tag_name" ]; then
warn "unreferencing tag object $sha1t"
fi
- git update-ref "refs/tags/$new_ref" "$new_sha1"
+ git update-ref "refs/tags/$new_ref" "$new_sha1" ||
+ die "Could not write tag $new_ref"
done
fi
diff --git a/git-svn.perl b/git-svn.perl
index 299b40f..6c692a7 100755
--- a/git-svn.perl
+++ b/git-svn.perl
@@ -740,7 +740,7 @@ sub load_authors {
my $log = $cmd eq 'log';
while (<$authors>) {
chomp;
- next unless /^(\S+?|\(no author\))\s*=\s*(.+?)\s*<(.+)>\s*$/;
+ next unless /^(.+?|\(no author\))\s*=\s*(.+?)\s*<(.+)>\s*$/;
my ($user, $name, $email) = ($1, $2, $3);
if ($log) {
$Git::SVN::Log::rusers{"$name <$email>"} = $user;
@@ -2724,6 +2724,9 @@ sub repo_path {
sub url_path {
my ($self, $path) = @_;
+ if ($self->{url} =~ m#^https?://#) {
+ $path =~ s/([^a-zA-Z0-9_.-])/uc sprintf("%%%02x",ord($1))/eg;
+ }
$self->{url} . '/' . $self->repo_path($path);
}
diff --git a/git.spec.in b/git.spec.in
index 27182ba..fe7b3d8 100644
--- a/git.spec.in
+++ b/git.spec.in
@@ -12,7 +12,7 @@ URL: http://kernel.org/pub/software/scm/git/
Source: http://kernel.org/pub/software/scm/git/%{name}-%{version}.tar.gz
BuildRequires: zlib-devel >= 1.2, openssl-devel, curl-devel, expat-devel %{!?_without_docs:, xmlto, asciidoc > 6.0.3}
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
-Requires: git-core, git-svn, git-cvs, git-arch, git-email, gitk, git-gui, git-p4, perl-Git
+Requires: git-core, git-svn, git-cvs, git-arch, git-email, gitk, git-gui, perl-Git
%description
Git is a fast, scalable, distributed revision control system with an
@@ -53,13 +53,6 @@ Requires: git-core = %{version}-%{release}, tla
%description arch
Git tools for importing Arch repositories.
-%package p4
-Summary: Git tools for importing Perforce repositories
-Group: Development/Tools
-Requires: git-core = %{version}-%{release}, python
-%description p4
-Git tools for importing Perforce repositories.
-
%package email
Summary: Git tools for sending email
Group: Development/Tools
@@ -95,14 +88,14 @@ Perl interface to Git
%setup -q
%build
-make %{_smp_mflags} CFLAGS="$RPM_OPT_FLAGS" WITH_P4IMPORT=YesPlease \
+make %{_smp_mflags} CFLAGS="$RPM_OPT_FLAGS" \
ETC_GITCONFIG=/etc/gitconfig \
- prefix=%{_prefix} PYTHON_PATH=%{python_path} all %{!?_without_docs: doc}
+ prefix=%{_prefix} all %{!?_without_docs: doc}
%install
rm -rf $RPM_BUILD_ROOT
make %{_smp_mflags} CFLAGS="$RPM_OPT_FLAGS" DESTDIR=$RPM_BUILD_ROOT \
- WITH_P4IMPORT=YesPlease prefix=%{_prefix} mandir=%{_mandir} \
+ prefix=%{_prefix} mandir=%{_mandir} \
ETC_GITCONFIG=/etc/gitconfig \
PYTHON_PATH=%{python_path} \
INSTALLDIRS=vendor install %{!?_without_docs: install-doc}
@@ -110,10 +103,10 @@ find $RPM_BUILD_ROOT -type f -name .packlist -exec rm -f {} ';'
find $RPM_BUILD_ROOT -type f -name '*.bs' -empty -exec rm -f {} ';'
find $RPM_BUILD_ROOT -type f -name perllocal.pod -exec rm -f {} ';'
-(find $RPM_BUILD_ROOT%{_bindir} -type f | grep -vE "p4import|archimport|svn|cvs|email|gitk|git-gui|git-citool" | sed -e s@^$RPM_BUILD_ROOT@@) > bin-man-doc-files
+(find $RPM_BUILD_ROOT%{_bindir} -type f | grep -vE "archimport|svn|cvs|email|gitk|git-gui|git-citool" | sed -e s@^$RPM_BUILD_ROOT@@) > bin-man-doc-files
(find $RPM_BUILD_ROOT%{perl_vendorlib} -type f | sed -e s@^$RPM_BUILD_ROOT@@) >> perl-files
%if %{!?_without_docs:1}0
-(find $RPM_BUILD_ROOT%{_mandir} $RPM_BUILD_ROOT/Documentation -type f | grep -vE "p4import|archimport|svn|git-cvs|email|gitk|git-gui|git-citool" | sed -e s@^$RPM_BUILD_ROOT@@ -e 's/$/*/' ) >> bin-man-doc-files
+(find $RPM_BUILD_ROOT%{_mandir} $RPM_BUILD_ROOT/Documentation -type f | grep -vE "archimport|svn|git-cvs|email|gitk|git-gui|git-citool" | sed -e s@^$RPM_BUILD_ROOT@@ -e 's/$/*/' ) >> bin-man-doc-files
%else
rm -rf $RPM_BUILD_ROOT%{_mandir}
%endif
@@ -145,13 +138,6 @@ rm -rf $RPM_BUILD_ROOT
%{!?_without_docs: %{_mandir}/man1/git-archimport.1*}
%{!?_without_docs: %doc Documentation/git-archimport.html }
-%files p4
-%defattr(-,root,root)
-%doc Documentation/git-p4import.txt
-%{_bindir}/git-p4import
-%{!?_without_docs: %{_mandir}/man1/git-p4import.1*}
-%{!?_without_docs: %doc Documentation/git-p4import.html }
-
%files email
%defattr(-,root,root)
%doc Documentation/*email*.txt
@@ -187,6 +173,9 @@ rm -rf $RPM_BUILD_ROOT
%{!?_without_docs: %doc Documentation/technical}
%changelog
+* Sun Jul 15 2007 Sean Estabrooks <seanlkml@sympatico.ca>
+- Removed p4import.
+
* Tue Jun 26 2007 Quy Tonthat <qtonthat@gmail.com>
- Fixed problems looking for wrong manpages.
diff --git a/t/lib-git-svn.sh b/t/lib-git-svn.sh
index f6fe78c..8d4a447 100644
--- a/t/lib-git-svn.sh
+++ b/t/lib-git-svn.sh
@@ -48,3 +48,37 @@ svnrepo="file://$svnrepo"
poke() {
test-chmtime +1 "$1"
}
+
+SVN_HTTPD_MODULE_PATH=${SVN_HTTPD_MODULE_PATH-'/usr/lib/apache2/modules'}
+SVN_HTTPD_PATH=${SVN_HTTPD_PATH-'/usr/sbin/apache2'}
+
+start_httpd () {
+ if test -z "$SVN_HTTPD_PORT"
+ then
+ echo >&2 'SVN_HTTPD_PORT is not defined!'
+ return
+ fi
+
+ mkdir "$GIT_DIR"/logs
+
+ cat > "$GIT_DIR/httpd.conf" <<EOF
+ServerName "git-svn test"
+ServerRoot "$GIT_DIR"
+DocumentRoot "$GIT_DIR"
+PidFile "$GIT_DIR/httpd.pid"
+Listen 127.0.0.1:$SVN_HTTPD_PORT
+LoadModule dav_module $SVN_HTTPD_MODULE_PATH/mod_dav.so
+LoadModule dav_svn_module $SVN_HTTPD_MODULE_PATH/mod_dav_svn.so
+<Location /svn>
+ DAV svn
+ SVNPath $rawsvnrepo
+</Location>
+EOF
+ "$SVN_HTTPD_PATH" -f "$GIT_DIR"/httpd.conf -k start
+ svnrepo=http://127.0.0.1:$SVN_HTTPD_PORT/svn
+}
+
+stop_httpd () {
+ test -z "$SVN_HTTPD_PORT" && return
+ "$SVN_HTTPD_PATH" -f "$GIT_DIR"/httpd.conf -k stop
+}
diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh
index 5e91db6..e8ce7cd 100755
--- a/t/t7400-submodule-basic.sh
+++ b/t/t7400-submodule-basic.sh
@@ -21,6 +21,10 @@ subcommands of git-submodule.
# -add an entry to .gitmodules for submodule 'example'
#
test_expect_success 'Prepare submodule testing' '
+ : > t &&
+ git-add t &&
+ git-commit -m "initial commit" &&
+ git branch initial HEAD &&
mkdir lib &&
cd lib &&
git init &&
@@ -166,4 +170,9 @@ test_expect_success 'status should be "up-to-date" after update' '
git-submodule status | grep "^ $rev1"
'
+test_expect_success 'checkout superproject with subproject already present' '
+ git-checkout initial &&
+ git-checkout master
+'
+
test_done
diff --git a/t/t9115-git-svn-dcommit-funky-renames.sh b/t/t9115-git-svn-dcommit-funky-renames.sh
new file mode 100755
index 0000000..182299c
--- /dev/null
+++ b/t/t9115-git-svn-dcommit-funky-renames.sh
@@ -0,0 +1,54 @@
+#!/bin/sh
+#
+# Copyright (c) 2007 Eric Wong
+
+
+test_description='git-svn dcommit can commit renames of files with ugly names'
+
+. ./lib-git-svn.sh
+
+test_expect_success 'load repository with strange names' "
+ svnadmin load -q $rawsvnrepo < ../t9115/funky-names.dump &&
+ start_httpd
+ "
+
+test_expect_success 'init and fetch repository' "
+ git svn init $svnrepo &&
+ git svn fetch &&
+ git reset --hard git-svn
+ "
+
+test_expect_success 'create file in existing ugly and empty dir' '
+ mkdir "#{bad_directory_name}" &&
+ echo hi > "#{bad_directory_name}/ foo" &&
+ git update-index --add "#{bad_directory_name}/ foo" &&
+ git commit -m "new file in ugly parent" &&
+ git svn dcommit
+ '
+
+test_expect_success 'rename ugly file' '
+ git mv "#{bad_directory_name}/ foo" "file name with feces" &&
+ git commit -m "rename ugly file" &&
+ git svn dcommit
+ '
+
+test_expect_success 'rename pretty file' '
+ echo :x > pretty &&
+ git update-index --add pretty &&
+ git commit -m "pretty :x" &&
+ git svn dcommit &&
+ mkdir regular_dir_name &&
+ git mv pretty regular_dir_name/pretty &&
+ git commit -m "moved pretty file" &&
+ git svn dcommit
+ '
+
+test_expect_success 'rename pretty file into ugly one' '
+ git mv regular_dir_name/pretty "#{bad_directory_name}/ booboo" &&
+ git commit -m booboo &&
+ git svn dcommit
+ '
+
+stop_httpd
+
+test_done
diff --git a/t/t9115/funky-names.dump b/t/t9115/funky-names.dump
new file mode 100644
index 0000000..42422f7
--- /dev/null
+++ b/t/t9115/funky-names.dump
@@ -0,0 +1,103 @@
+SVN-fs-dump-format-version: 2
+
+UUID: 819c44fe-2bcc-4066-88e4-985e2bc0b418
+
+Revision-number: 0
+Prop-content-length: 56
+Content-length: 56
+
+K 8
+svn:date
+V 27
+2007-07-12T07:54:26.062914Z
+PROPS-END
+
+Revision-number: 1
+Prop-content-length: 152
+Content-length: 152
+
+K 7
+svn:log
+V 44
+what will those wacky people think of next?
+
+K 10
+svn:author
+V 12
+normalperson
+K 8
+svn:date
+V 27
+2007-07-12T08:00:05.011573Z
+PROPS-END
+
+Node-path: leading space
+Node-kind: dir
+Node-action: add
+Prop-content-length: 10
+Content-length: 10
+
+PROPS-END
+
+
+Node-path: leading space file
+Node-kind: file
+Node-action: add
+Prop-content-length: 10
+Text-content-length: 5
+Text-content-md5: e4fa20c67542cdc21271e08d329397ab
+Content-length: 15
+
+PROPS-END
+ugly
+
+
+Node-path: #{bad_directory_name}
+Node-kind: dir
+Node-action: add
+Prop-content-length: 10
+Content-length: 10
+
+PROPS-END
+
+
+Node-path: #{cool_name}
+Node-kind: file
+Node-action: add
+Prop-content-length: 10
+Text-content-length: 18
+Text-content-md5: 87dac40ca337dfa3dcc8911388c3ddda
+Content-length: 28
+
+PROPS-END
+strange name here
+
+
+Node-path: dir name with spaces
+Node-kind: dir
+Node-action: add
+Prop-content-length: 10
+Content-length: 10
+
+PROPS-END
+
+
+Node-path: file name with spaces
+Node-kind: file
+Node-action: add
+Prop-content-length: 10
+Text-content-length: 7
+Text-content-md5: c1f10cfd640618484a2a475c11410fd3
+Content-length: 17
+
+PROPS-END
+spaces
+
+
+Node-path: regular_dir_name
+Node-kind: dir
+Node-action: add
+Prop-content-length: 10
+Content-length: 10
+
+PROPS-END
diff --git a/unpack-trees.c b/unpack-trees.c
index 89dd279..7cc029e 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
@@ -425,11 +426,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.
+ *
+ * Currently, git does not checkout subprojects during a superproject
+ * checkout, so it is not going to overwrite anything.
+ */
+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;
@@ -437,13 +451,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_ISGITLINK(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 (!hashcmp(sha1, ce->sha1))
+ return 0;
+ return 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;
@@ -451,7 +476,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;
/*
@@ -469,16 +494,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;
}
@@ -487,7 +512,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,15 +520,15 @@ static void verify_absent(const char *path, const char *action,
if (o->index_only || o->reset || !o->update)
return;
- if (has_symlink_leading_path(path, NULL))
+ if (has_symlink_leading_path(ce->name, NULL))
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;
@@ -515,7 +540,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, action, o);
/*
* If this removed entries from the index,
@@ -543,7 +568,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)
@@ -551,7 +576,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);
}
}
@@ -575,7 +600,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);
}
@@ -590,7 +615,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);
@@ -707,18 +732,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;
}
}
@@ -733,8 +758,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;
}
/*