Merge branch 'jc/reset-remove' into next

* jc/reset-remove: (21 commits)
  git-reset <tree> -- <path> restores absense of <path> in <tree>
  diff-index --cached --raw: show tree entry on the LHS for unmerged entries.
  gitweb: Fix split patches output (e.g. file to symlink)
  Revert "gitweb: There can be empty patches (in git_patchset_body)"
  gitweb: Fix errors in git_patchset_body for empty patches
  gitweb: Fix error in "rename to"/"copy to" git diff header output
  gitweb: Fix error in git_patchest_body for file creation/deletion patch
  git-svn: fix show-ignore
  Documentation: tutorial editing
  Documentation/git-svn: clarify dcommit, rebase vs pull/merge
  git-svnimport: clean svn path when accessing SVN repo
  git-svnimport: support for incremental import
  git.el: Avoid setting font lock keywords before entering log-edit mode.
  instaweb: Nicer error message when the http daemon isn't found
  git.el: Don't use --info-only when resolving a file.
  git-clean: Fix the -q option.
  Print a more accurate error message when we fail to create a lock file.
  Describe git-clone's actual behavior in the summary
  Set default "tar" umask to 002 and owner.group to root.root
  Fix timestamp for test-tick
  ...
This commit is contained in:
Junio C Hamano
2007-01-06 22:57:56 -08:00
19 changed files with 127 additions and 70 deletions

View File

@@ -18,13 +18,13 @@ DESCRIPTION
Clones a repository into a newly created directory, creates
remote-tracking branches for each branch in the cloned repository
(visible using `git branch -r`), and creates and checks out a master
branch equal to the cloned repository's master branch.
(visible using `git branch -r`), and creates and checks out an initial
branch equal to the cloned repository's currently active branch.
After the clone, a plain `git fetch` without arguments will update
all the remote-tracking branches, and a `git pull` without
arguments will in addition merge the remote master branch into the
current branch.
current master branch, if any.
This default configuration is achieved by creating references to
the remote branch heads under `$GIT_DIR/refs/remotes/origin` and

View File

@@ -53,11 +53,13 @@ See '<<fetch-args,Additional Fetch Arguments>>' if you are interested in
manually joining branches on commit.
'dcommit'::
Commit all diffs from a specified head directly to the SVN
Commit each diff from a specified head directly to the SVN
repository, and then rebase or reset (depending on whether or
not there is a diff between SVN and head). It is recommended
that you run git-svn fetch and rebase (not pull) your commits
against the latest changes in the SVN repository.
not there is a diff between SVN and head). This will create
a revision in SVN for each commit in git.
It is recommended that you run git-svn fetch and rebase (not
pull or merge) your commits against the latest changes in the
SVN repository.
An optional command-line argument may be specified as an
alternative to HEAD.
This is advantageous over 'set-tree' (below) because it produces
@@ -408,19 +410,20 @@ See also:
git-svn multi-init
------------------------------------------------------------------------
REBASE VS. PULL
---------------
REBASE VS. PULL/MERGE
---------------------
Originally, git-svn recommended that the remotes/git-svn branch be
pulled from. This is because the author favored 'git-svn set-tree B'
to commit a single head rather than the 'git-svn set-tree A..B' notation
to commit multiple commits.
pulled or merged from. This is because the author favored
'git-svn set-tree B' to commit a single head rather than the
'git-svn set-tree A..B' notation to commit multiple commits.
If you use 'git-svn set-tree A..B' to commit several diffs and you do not
have the latest remotes/git-svn merged into my-branch, you should use
'git rebase' to update your work branch instead of 'git pull'. 'pull'
can cause non-linear history to be flattened when committing into SVN,
which can lead to merge commits reversing previous commits in SVN.
If you use 'git-svn set-tree A..B' to commit several diffs and you do
not have the latest remotes/git-svn merged into my-branch, you should
use 'git rebase' to update your work branch instead of 'git pull' or
'git merge'. 'pull/merge' can cause non-linear history to be flattened
when committing into SVN, which can lead to merge commits reversing
previous commits in SVN.
DESIGN PHILOSOPHY
-----------------

View File

@@ -15,7 +15,7 @@ SYNOPSIS
[ -b branch_subdir ] [ -T trunk_subdir ] [ -t tag_subdir ]
[ -s start_chg ] [ -m ] [ -r ] [ -M regex ]
[ -I <ignorefile_name> ] [ -A <author_file> ]
[ -P <path_from_trunk> ]
[ -R <repack_each_revs>] [ -P <path_from_trunk> ]
<SVN_repository_URL> [ <path> ]
@@ -108,6 +108,14 @@ repository without -A.
Formerly, this option controlled how many revisions to pull,
due to SVN memory leaks. (These have been worked around.)
-R <repack_each_revs>::
Specify how often git repository should be repacked.
+
The default value is 1000. git-svnimport will do import in chunks of 1000
revisions, after each chunk git repository will be repacked. To disable
this behavior specify some big value here which is mote than number of
revisions to import.
-P <path_from_trunk>::
Partial import of the SVN tree.
+

View File

@@ -43,8 +43,7 @@ Initialized empty Git repository in .git/
You've now initialized the working directory--you may notice a new
directory created, named ".git". Tell git that you want it to track
every file under the current directory with (notice the dot '.'
that means the current directory):
every file under the current directory (note the '.') with:
------------------------------------------------
$ git add .
@@ -59,6 +58,9 @@ $ git commit
will prompt you for a commit message, then record the current state
of all the files to the repository.
Making changes
--------------
Try modifying some files, then run
------------------------------------------------
@@ -70,19 +72,21 @@ want the updated contents of these files in the commit and then
make a commit, like this:
------------------------------------------------
$ git add file1 file...
$ git add file1 file2 file3
$ git commit
------------------------------------------------
This will again prompt your for a message describing the change, and then
record the new versions of the files you listed. It is cumbersome
to list all files and you can say `git commit -a` (which stands for 'all')
instead of running `git add` beforehand.
record the new versions of the files you listed.
Alternatively, instead of running `git add` beforehand, you can use
------------------------------------------------
$ git commit -a
------------------------------------------------
which will automatically notice modified (but not new) files.
A note on commit messages: Though not required, it's a good idea to
begin the commit message with a single short (less than 50 character)
line summarizing the change, followed by a blank line and then a more

View File

@@ -15,7 +15,7 @@ static char block[BLOCKSIZE];
static unsigned long offset;
static time_t archive_time;
static int tar_umask;
static int tar_umask = 002;
static int verbose;
/* writes out the whole block, but only if it is full */
@@ -210,11 +210,10 @@ static void write_entry(const unsigned char *sha1, struct strbuf *path,
sprintf(header.size, "%011lo", S_ISREG(mode) ? size : 0);
sprintf(header.mtime, "%011lo", archive_time);
/* XXX: should we provide more meaningful info here? */
sprintf(header.uid, "%07o", 0);
sprintf(header.gid, "%07o", 0);
strlcpy(header.uname, "git", sizeof(header.uname));
strlcpy(header.gname, "git", sizeof(header.gname));
strlcpy(header.uname, "root", sizeof(header.uname));
strlcpy(header.gname, "root", sizeof(header.gname));
sprintf(header.devmajor, "%07o", 0);
sprintf(header.devminor, "%07o", 0);

View File

@@ -253,6 +253,8 @@ int cmd_prune(int argc, const char **argv, const char *prefix)
usage(prune_usage);
}
save_commit_buffer = 0;
/*
* Set up revision parsing, and mark us as being interested
* in all object types, not just commits.

View File

@@ -49,6 +49,7 @@
(eval-when-compile (require 'cl))
(require 'ewoc)
(require 'log-edit)
;;;; Customizations
@@ -147,6 +148,13 @@ if there is already one that displays the same directory."
(defconst git-log-msg-separator "--- log message follows this line ---")
(defvar git-log-edit-font-lock-keywords
`(("^\\(Author:\\|Date:\\|Parent:\\|Signed-off-by:\\)\\(.*\\)$"
(1 font-lock-keyword-face)
(2 font-lock-function-name-face))
(,(concat "^\\(" (regexp-quote git-log-msg-separator) "\\)$")
(1 font-lock-comment-face))))
(defun git-get-env-strings (env)
"Build a list of NAME=VALUE strings from a list of environment strings."
(mapcar (lambda (entry) (concat (car entry) "=" (cdr entry))) env))
@@ -777,7 +785,7 @@ and returns the process output as a string."
(interactive)
(let ((files (git-marked-files-state 'unmerged)))
(when files
(apply #'git-run-command nil nil "update-index" "--info-only" "--" (git-get-filenames files))
(apply #'git-run-command nil nil "update-index" "--" (git-get-filenames files))
(git-set-files-state files 'modified)
(git-refresh-files))))
@@ -894,14 +902,9 @@ and returns the process output as a string."
(sign-off
(insert (format "\n\nSigned-off-by: %s <%s>\n"
(git-get-committer-name) (git-get-committer-email)))))))
(let ((log-edit-font-lock-keywords
`(("^\\(Author:\\|Date:\\|Parent:\\|Signed-off-by:\\)\\(.*\\)"
(1 font-lock-keyword-face)
(2 font-lock-function-name-face))
(,(concat "^\\(" (regexp-quote git-log-msg-separator) "\\)$")
(1 font-lock-comment-face)))))
(log-edit #'git-do-commit nil #'git-log-edit-files buffer)
(re-search-forward (regexp-quote (concat git-log-msg-separator "\n")) nil t))))
(log-edit #'git-do-commit nil #'git-log-edit-files buffer)
(setq font-lock-keywords (font-lock-compile-keywords git-log-edit-font-lock-keywords))
(re-search-forward (regexp-quote (concat git-log-msg-separator "\n")) nil t)))
(defun git-find-file ()
"Visit the current file in its own buffer."

View File

@@ -97,7 +97,7 @@ int run_diff_files(struct rev_info *revs, int silent_on_removed)
* Show the diff for the 'ce' if we found the one
* from the desired stage.
*/
diff_unmerge(&revs->diffopt, ce->name);
diff_unmerge(&revs->diffopt, ce->name, 0, null_sha1);
if (ce_stage(ce) != diff_unmerged_stage)
continue;
}
@@ -297,9 +297,12 @@ static int diff_cache(struct rev_info *revs,
!show_modified(revs, ce, ac[1], 0,
cached, match_missing))
break;
/* fallthru */
diff_unmerge(&revs->diffopt, ce->name,
ntohl(ce->ce_mode), ce->sha1);
break;
case 3:
diff_unmerge(&revs->diffopt, ce->name);
diff_unmerge(&revs->diffopt, ce->name,
0, null_sha1);
break;
default:

6
diff.c
View File

@@ -2887,10 +2887,12 @@ void diff_change(struct diff_options *options,
}
void diff_unmerge(struct diff_options *options,
const char *path)
const char *path,
unsigned mode, const unsigned char *sha1)
{
struct diff_filespec *one, *two;
one = alloc_filespec(path);
two = alloc_filespec(path);
diff_queue(&diff_queued_diff, one, two);
fill_filespec(one, sha1, mode);
diff_queue(&diff_queued_diff, one, two)->is_unmerged = 1;
}

4
diff.h
View File

@@ -144,7 +144,9 @@ extern void diff_change(struct diff_options *,
const char *base, const char *path);
extern void diff_unmerge(struct diff_options *,
const char *path);
const char *path,
unsigned mode,
const unsigned char *sha1);
extern int diff_scoreopt_parse(const char *opt);

View File

@@ -54,9 +54,9 @@ struct diff_filepair {
unsigned source_stays : 1; /* all of R/C are copies */
unsigned broken_pair : 1;
unsigned renamed_pair : 1;
unsigned is_unmerged : 1;
};
#define DIFF_PAIR_UNMERGED(p) \
(!DIFF_FILE_VALID((p)->one) && !DIFF_FILE_VALID((p)->two))
#define DIFF_PAIR_UNMERGED(p) ((p)->is_unmerged)
#define DIFF_PAIR_RENAME(p) ((p)->renamed_pair)

View File

@@ -18,7 +18,6 @@ SUBDIRECTORY_OK=Yes
ignored=
ignoredonly=
cleandir=
quiet=
rmf="rm -f --"
rmrf="rm -rf --"
rm_refuse="echo Not removing"
@@ -31,14 +30,13 @@ do
cleandir=1
;;
-n)
quiet=1
rmf="echo Would remove"
rmrf="echo Would remove"
rm_refuse="echo Would not remove"
echo1=":"
;;
-q)
quiet=1
echo1=":"
;;
-x)
ignored=1

View File

@@ -53,6 +53,9 @@ start_httpd () {
return
fi
done
echo "$httpd_only not found. Install $httpd_only or use" \
"--httpd to specify another http daemon."
exit 1
fi
if test $? != 0; then
echo "Could not execute http daemon $httpd."

View File

@@ -44,8 +44,10 @@ if test $# != 0
then
test "$reset_type" == "--mixed" ||
die "Cannot do partial $reset_type reset."
git ls-tree -r --full-name $rev -- "$@" |
git update-index --add --index-info || exit
git-diff-index --cached $rev -- "$@" |
sed -e 's/^:\([0-7][0-7]*\) [0-7][0-7]* \([0-9a-f][0-9a-f]*\) [0-9a-f][0-9a-f]* [A-Z] \(.*\)$/\1 \2 \3/' |
git update-index --add --remove --index-info || exit
git update-index --refresh
exit
fi

View File

@@ -536,7 +536,7 @@ sub show_ignore {
my $repo;
$SVN ||= libsvn_connect($SVN_URL);
my $r = defined $_revision ? $_revision : $SVN->get_latest_revnum;
libsvn_traverse_ignore(\*STDOUT, $SVN->{svn_path}, $r);
libsvn_traverse_ignore(\*STDOUT, '', $r);
}
sub graft_branches {

View File

@@ -31,12 +31,13 @@ $SIG{'PIPE'}="IGNORE";
$ENV{'TZ'}="UTC";
our($opt_h,$opt_o,$opt_v,$opt_u,$opt_C,$opt_i,$opt_m,$opt_M,$opt_t,$opt_T,
$opt_b,$opt_r,$opt_I,$opt_A,$opt_s,$opt_l,$opt_d,$opt_D,$opt_S,$opt_F,$opt_P);
$opt_b,$opt_r,$opt_I,$opt_A,$opt_s,$opt_l,$opt_d,$opt_D,$opt_S,$opt_F,
$opt_P,$opt_R);
sub usage() {
print STDERR <<END;
Usage: ${\basename $0} # fetch/update GIT from SVN
[-o branch-for-HEAD] [-h] [-v] [-l max_rev]
[-o branch-for-HEAD] [-h] [-v] [-l max_rev] [-R repack_each_revs]
[-C GIT_repository] [-t tagname] [-T trunkname] [-b branchname]
[-d|-D] [-i] [-u] [-r] [-I ignorefilename] [-s start_chg]
[-m] [-M regex] [-A author_file] [-S] [-F] [-P project_name] [SVN_URL]
@@ -44,7 +45,7 @@ END
exit(1);
}
getopts("A:b:C:dDFhiI:l:mM:o:rs:t:T:SP:uv") or usage();
getopts("A:b:C:dDFhiI:l:mM:o:rs:t:T:SP:R:uv") or usage();
usage if $opt_h;
my $tag_name = $opt_t || "tags";
@@ -52,6 +53,7 @@ my $trunk_name = $opt_T || "trunk";
my $branch_name = $opt_b || "branches";
my $project_name = $opt_P || "";
$project_name = "/" . $project_name if ($project_name);
my $repack_after = $opt_R || 1000;
@ARGV == 1 or @ARGV == 2 or usage();
@@ -146,6 +148,7 @@ sub file {
print "... $rev $path ...\n" if $opt_v;
my (undef, $properties);
my $pool = SVN::Pool->new();
$path =~ s#^/*##;
eval { (undef, $properties)
= $self->{'svn'}->get_file($path,$rev,$fh,$pool); };
$pool->clear;
@@ -181,6 +184,7 @@ sub ignore {
my($self,$path,$rev) = @_;
print "... $rev $path ...\n" if $opt_v;
$path =~ s#^/*##;
my (undef,undef,$properties)
= $self->{'svn'}->get_dir($path,$rev,undef);
if (exists $properties->{'svn:ignore'}) {
@@ -197,6 +201,7 @@ sub ignore {
sub dir_list {
my($self,$path,$rev) = @_;
$path =~ s#^/*##;
my ($dirents,undef,$properties)
= $self->{'svn'}->get_dir($path,$rev,undef);
return $dirents;
@@ -354,6 +359,7 @@ open BRANCHES,">>", "$git_dir/svn2git";
sub node_kind($$) {
my ($svnpath, $revision) = @_;
my $pool=SVN::Pool->new;
$svnpath =~ s#^/*##;
my $kind = $svn->{'svn'}->check_path($svnpath,$revision,$pool);
$pool->clear;
return $kind;
@@ -934,11 +940,27 @@ if ($opt_l < $current_rev) {
exit;
}
print "Fetching from $current_rev to $opt_l ...\n" if $opt_v;
print "Processing from $current_rev to $opt_l ...\n" if $opt_v;
my $pool=SVN::Pool->new;
$svn->{'svn'}->get_log("/",$current_rev,$opt_l,0,1,1,\&commit_all,$pool);
$pool->clear;
my $from_rev;
my $to_rev = $current_rev;
while ($to_rev < $opt_l) {
$from_rev = $to_rev;
$to_rev = $from_rev + $repack_after;
$to_rev = $opt_l if $opt_l < $to_rev;
print "Fetching from $from_rev to $to_rev ...\n" if $opt_v;
my $pool=SVN::Pool->new;
$svn->{'svn'}->get_log("/",$from_rev,$to_rev,0,1,1,\&commit_all,$pool);
$pool->clear;
my $pid = fork();
die "Fork: $!\n" unless defined $pid;
unless($pid) {
exec("git-repack", "-d")
or die "Cannot repack: $!\n";
}
waitpid($pid, 0);
}
unlink($git_index);

View File

@@ -2378,7 +2378,6 @@ sub git_patchset_body {
my $patch_line;
my $diffinfo;
my (%from, %to);
my ($from_id, $to_id);
print "<div class=\"patchset\">\n";
@@ -2392,6 +2391,7 @@ sub git_patchset_body {
PATCH:
while ($patch_line) {
my @diff_header;
my ($from_id, $to_id);
# git diff header
#assert($patch_line =~ m/^diff /) if DEBUG;
@@ -2403,7 +2403,7 @@ sub git_patchset_body {
while ($patch_line = <$fd>) {
chomp $patch_line;
last EXTENDED_HEADER if ($patch_line =~ m/^--- /);
last EXTENDED_HEADER if ($patch_line =~ m/^--- |^diff /);
if ($patch_line =~ m/^index ([0-9a-fA-F]{40})..([0-9a-fA-F]{40})/) {
$from_id = $1;
@@ -2439,11 +2439,15 @@ sub git_patchset_body {
$from{'href'} = href(action=>"blob", hash_base=>$hash_parent,
hash=>$diffinfo->{'from_id'},
file_name=>$from{'file'});
} else {
delete $from{'href'};
}
if ($diffinfo->{'status'} ne "D") { # not deleted file
$to{'href'} = href(action=>"blob", hash_base=>$hash,
hash=>$diffinfo->{'to_id'},
file_name=>$to{'file'});
} else {
delete $to{'href'};
}
# this is first patch for raw difftree line with $patch_idx index
# we index @$difftree array from 0, but number patches from 1
@@ -2475,11 +2479,11 @@ sub git_patchset_body {
# match <path>
if ($patch_line =~ s!^((copy|rename) from ).*$!$1! && $from{'href'}) {
$patch_line .= $cgi->a({-href=>$from{'href'}, -class=>"path"},
esc_path($from{'file'}));
esc_path($from{'file'}));
}
if ($patch_line =~ s!^((copy|rename) to ).*$!$1! && $to{'href'}) {
$patch_line = $cgi->a({-href=>$to{'href'}, -class=>"path"},
esc_path($to{'file'}));
$patch_line .= $cgi->a({-href=>$to{'href'}, -class=>"path"},
esc_path($to{'file'}));
}
# match <mode>
if ($patch_line =~ m/\s(\d{6})$/) {
@@ -2518,8 +2522,10 @@ sub git_patchset_body {
# from-file/to-file diff header
$patch_line = $last_patch_line;
last PATCH unless $patch_line;
next PATCH if ($patch_line =~ m/^diff /);
#assert($patch_line =~ m/^---/) if DEBUG;
if ($from{'href'}) {
if ($from{'href'} && $patch_line =~ m!^--- "?a/!) {
$patch_line = '--- a/' .
$cgi->a({-href=>$from{'href'}, -class=>"path"},
esc_path($from{'file'}));
@@ -2527,11 +2533,11 @@ sub git_patchset_body {
print "<div class=\"diff from_file\">$patch_line</div>\n";
$patch_line = <$fd>;
last PATCH unless $patch_line;
#last PATCH unless $patch_line;
chomp $patch_line;
#assert($patch_line =~ m/^+++/) if DEBUG;
if ($to{'href'}) {
if ($to{'href'} && $patch_line =~ m!^\+\+\+ "?b/!) {
$patch_line = '+++ b/' .
$cgi->a({-href=>$to{'href'}, -class=>"path"},
esc_path($to{'file'}));

View File

@@ -49,7 +49,7 @@ int hold_lock_file_for_update(struct lock_file *lk, const char *path, int die_on
{
int fd = lock_file(lk, path);
if (fd < 0 && die_on_error)
die("unable to create '%s': %s", path, strerror(errno));
die("unable to create '%s.lock': %s", path, strerror(errno));
return fd;
}

View File

@@ -99,12 +99,12 @@ trap 'echo >&5 "FATAL: Unexpected exit with code $?"; exit 1' exit
test_tick () {
if test -z "${test_tick+set}"
then
test_tick=432630000
test_tick=1112911993
else
test_tick=$(($test_tick + 60))
fi
GIT_COMMITTER_DATE=$test_tick
GIT_AUTHOR_DATE=$test_tick
GIT_COMMITTER_DATE="$test_tick -0700"
GIT_AUTHOR_DATE="$test_tick -0700"
export GIT_COMMITTER_DATE GIT_AUTHOR_DATE
}