From: Junio C Hamano Date: Sun, 7 Jan 2007 07:49:16 +0000 (-0800) Subject: Merge branch 'jc/remote' X-Git-Tag: v1.5.0-rc1~66 X-Git-Url: https://www.git.lorimer.id.au/gitweb.git/diff_plain/8f905eb139aa2284ca9001de1265d25b661f907c?hp=e194cd1e0e08611462eb9c5a731a7a3d797f9252 Merge branch 'jc/remote' * jc/remote: git-remote --- diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt index e7085fdf5f..a78207461d 100644 --- a/Documentation/git-clone.txt +++ b/Documentation/git-clone.txt @@ -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 diff --git a/Documentation/git-svn.txt b/Documentation/git-svn.txt index f754d2f679..ce63defffd 100644 --- a/Documentation/git-svn.txt +++ b/Documentation/git-svn.txt @@ -53,11 +53,13 @@ See '<>' 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. - -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. +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' 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 ----------------- diff --git a/Documentation/git-svnimport.txt b/Documentation/git-svnimport.txt index 2c7c7dad54..b166cf3327 100644 --- a/Documentation/git-svnimport.txt +++ b/Documentation/git-svnimport.txt @@ -15,7 +15,7 @@ SYNOPSIS [ -b branch_subdir ] [ -T trunk_subdir ] [ -t tag_subdir ] [ -s start_chg ] [ -m ] [ -r ] [ -M regex ] [ -I ] [ -A ] - [ -P ] + [ -R ] [ -P ] [ ] @@ -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 :: + 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 :: Partial import of the SVN tree. + diff --git a/Documentation/tutorial.txt b/Documentation/tutorial.txt index 79884d9c74..01d4a47a97 100644 --- a/Documentation/tutorial.txt +++ b/Documentation/tutorial.txt @@ -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 diff --git a/archive-tar.c b/archive-tar.c index af47fdc955..7d52a061f4 100644 --- a/archive-tar.c +++ b/archive-tar.c @@ -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); diff --git a/builtin-prune.c b/builtin-prune.c index 00a53b3647..b469c43bc5 100644 --- a/builtin-prune.c +++ b/builtin-prune.c @@ -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. diff --git a/contrib/emacs/git.el b/contrib/emacs/git.el index 972c402ea0..ede3ab2bd8 100644 --- a/contrib/emacs/git.el +++ b/contrib/emacs/git.el @@ -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." diff --git a/diff-lib.c b/diff-lib.c index fc69fb92a5..2c9be60ed9 100644 --- a/diff-lib.c +++ b/diff-lib.c @@ -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: diff --git a/diff.c b/diff.c index f14288bb8a..2c2e9dcb8c 100644 --- a/diff.c +++ b/diff.c @@ -2875,10 +2875,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; } diff --git a/diff.h b/diff.h index eff445596d..7a347cf77d 100644 --- a/diff.h +++ b/diff.h @@ -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); diff --git a/diffcore.h b/diffcore.h index 2249bc2c05..1ea80671e3 100644 --- a/diffcore.h +++ b/diffcore.h @@ -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) diff --git a/git-clean.sh b/git-clean.sh index 3834323bcf..071b974f49 100755 --- a/git-clean.sh +++ b/git-clean.sh @@ -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 diff --git a/git-instaweb.sh b/git-instaweb.sh index 08362f43c0..80adc8307b 100755 --- a/git-instaweb.sh +++ b/git-instaweb.sh @@ -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." diff --git a/git-reset.sh b/git-reset.sh index a9693701a3..76c8a818d4 100755 --- a/git-reset.sh +++ b/git-reset.sh @@ -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 diff --git a/git-svn.perl b/git-svn.perl index 537776239c..1da31fdc7c 100755 --- a/git-svn.perl +++ b/git-svn.perl @@ -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 { diff --git a/git-svnimport.perl b/git-svnimport.perl index cbaa8ab37c..afbbe63c62 100755 --- a/git-svnimport.perl +++ b/git-svnimport.perl @@ -31,12 +31,13 @@ $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 <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 @@ ($$) 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 @@ sub commit_all { 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); diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 7906280f26..f46a42296d 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -2378,7 +2378,6 @@ sub git_patchset_body { my $patch_line; my $diffinfo; my (%from, %to); - my ($from_id, $to_id); print "
\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 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 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 "
$patch_line
\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'})); diff --git a/lockfile.c b/lockfile.c index 731bbf3c9c..4824f4dc02 100644 --- a/lockfile.c +++ b/lockfile.c @@ -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; } diff --git a/t/test-lib.sh b/t/test-lib.sh index bf108d4226..72ea2b2598 100755 --- a/t/test-lib.sh +++ b/t/test-lib.sh @@ -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 }