From 16157b8074926348a9ee191ce6b50c8e1656161c Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 5 Jan 2007 13:31:43 -0800 Subject: [PATCH 01/21] builtin-prune: memory diet. Somehow we forgot to turn save_commit_buffer off while walking the reachable objects. Releasing the memory for commit object data that we do not use matters for large projects (for example, about 90MB is saved while traversing linux-2.6 history). Signed-off-by: Junio C Hamano --- builtin-prune.c | 2 ++ 1 file changed, 2 insertions(+) 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. From 21afc41c363cdfbc33285291d92635741163e6a1 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sat, 6 Jan 2007 02:16:07 -0800 Subject: [PATCH 02/21] Fix timestamp for test-tick The earlier test timestamp was too old; I forgot that the bare unixtime integer had to be after Jan 1, 2000. This changes test_tick to use the git-epoch timestamp. Signed-off-by: Junio C Hamano --- t/test-lib.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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 } From f08b3b0e2e9ad87767d80ff03b013c686e08ba4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Scharfe?= Date: Fri, 5 Jan 2007 23:30:22 +0100 Subject: [PATCH 03/21] Set default "tar" umask to 002 and owner.group to root.root In order to make the generated tar files more friendly to users who extract them as root using GNU tar and its implied -p option, change the default umask to 002 and change the owner name and group name to root. This ensures that a) the extracted files and directories are not world-writable and b) that they belong to user and group root. Before they would have been assigned to a user and/or group named git if it existed. This also answers the question in the removed comment: uid=0, gid=0, uname=root, gname=root is exactly what we want. Normal users who let tar apply their umask while extracting are only affected if their umask allowed the world to change their files (e.g. a umask of zero). This case is so unlikely and strange that we don't need to support it. Signed-off-by: Rene Scharfe Signed-off-by: Junio C Hamano --- archive-tar.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) 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); From 1170e8026ae507c510619fceff969b1cf2900a28 Mon Sep 17 00:00:00 2001 From: Steven Grimm Date: Fri, 5 Jan 2007 17:52:20 -0800 Subject: [PATCH 04/21] Describe git-clone's actual behavior in the summary If a branch other than "master" is checked out in the origin repository, git-clone makes a local copy of that branch rather than the origin's "master" branch. This patch describes the actual behavior. Signed-off-by: Steven Grimm Signed-off-by: Junio C Hamano --- Documentation/git-clone.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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 From f9e8a43a007e81b564516576550a505967389942 Mon Sep 17 00:00:00 2001 From: Steven Grimm Date: Fri, 5 Jan 2007 19:14:04 -0800 Subject: [PATCH 05/21] Print a more accurate error message when we fail to create a lock file. Signed-off-by: Steven Grimm Signed-off-by: Junio C Hamano --- lockfile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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; } From e6d7b2f62e52c95c47b078f786705ef9ff8f43c2 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Sat, 6 Jan 2007 11:19:44 +0100 Subject: [PATCH 06/21] git-clean: Fix the -q option. The 'quiet' flag is set by -q, but it's not used anywhere. Remove it and set the 'echo1' variable instead. Signed-off-by: Alexandre Julliard Signed-off-by: Junio C Hamano --- git-clean.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) 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 From cdc0873a78771926b18d9331e04f466ded1b98f2 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Sat, 6 Jan 2007 11:20:57 +0100 Subject: [PATCH 07/21] git.el: Don't use --info-only when resolving a file. It doesn't make a difference for git.el, but it helps when interacting with git-rebase and friends. Signed-off-by: Alexandre Julliard Signed-off-by: Junio C Hamano --- contrib/emacs/git.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/emacs/git.el b/contrib/emacs/git.el index 972c402ea0..38915e59aa 100644 --- a/contrib/emacs/git.el +++ b/contrib/emacs/git.el @@ -777,7 +777,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)))) From f281e3a1c5948b7dbe2fb47731376506ba3c8c38 Mon Sep 17 00:00:00 2001 From: Fredrik Kuivinen Date: Sat, 6 Jan 2007 11:40:06 +0100 Subject: [PATCH 08/21] instaweb: Nicer error message when the http daemon isn't found Signed-off-by: Fredrik Kuivinen Signed-off-by: Junio C Hamano --- git-instaweb.sh | 3 +++ 1 file changed, 3 insertions(+) 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." From 9fa77a51a49b16fa8886643d7f6346eb0a0601c5 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Sat, 6 Jan 2007 14:46:47 +0100 Subject: [PATCH 09/21] git.el: Avoid setting font lock keywords before entering log-edit mode. Instead, reinitialize the keywords after the fact. This avoids conflicts with other users of log-edit mode, like pcl-cvs. Signed-off-by: Alexandre Julliard Signed-off-by: Junio C Hamano --- contrib/emacs/git.el | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/contrib/emacs/git.el b/contrib/emacs/git.el index 38915e59aa..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)) @@ -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." From 40006ea039b8d72cf6dce5816a50c8ba266833ee Mon Sep 17 00:00:00 2001 From: Sasha Khapyorsky Date: Sun, 7 Jan 2007 02:17:19 +0200 Subject: [PATCH 10/21] git-svnimport: support for incremental import This adds ability to do import "in chunks" (default 1000 revisions), after each chunk git repo will be repacked. The option -R is used to change default value of chunk size (or how often repository will repacked). Signed-off-by: Sasha Khapyorsky Signed-off-by: Junio C Hamano --- Documentation/git-svnimport.txt | 10 +++++++++- git-svnimport.perl | 32 +++++++++++++++++++++++++------- 2 files changed, 34 insertions(+), 8 deletions(-) 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/git-svnimport.perl b/git-svnimport.perl index cbaa8ab37c..f31fcf84ed 100755 --- a/git-svnimport.perl +++ b/git-svnimport.perl @@ -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 <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); From 09c3a408da1d02a3ea1119694b5deaeb14c20d65 Mon Sep 17 00:00:00 2001 From: Sasha Khapyorsky Date: Sun, 7 Jan 2007 02:22:10 +0200 Subject: [PATCH 11/21] git-svnimport: clean svn path when accessing SVN repo Clean svn path from leading '/' when accessing SVN repo. Signed-off-by: Sasha Khapyorsky Signed-off-by: Junio C Hamano --- git-svnimport.perl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/git-svnimport.perl b/git-svnimport.perl index f31fcf84ed..afbbe63c62 100755 --- a/git-svnimport.perl +++ b/git-svnimport.perl @@ -148,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; @@ -183,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'}) { @@ -199,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; @@ -356,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; From 2eff14259ea4035dc5f8a18f5998e88dd4da207e Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Sat, 6 Jan 2007 17:53:40 -0800 Subject: [PATCH 12/21] Documentation/git-svn: clarify dcommit, rebase vs pull/merge Clarify that dcommit creates a revision in SVN for every commit in git. Also, add 'merge' to the rebase vs pull section because git-merge is now a first-class UI. Signed-off-by: Eric Wong Signed-off-by: Junio C Hamano --- Documentation/git-svn.txt | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) 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. +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 ----------------- From 84dee6bbc9eb6dd8e613414ed0271d8290549e89 Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Sat, 6 Jan 2007 22:38:38 -0500 Subject: [PATCH 13/21] Documentation: tutorial editing Edit for conciseness. Add a "Making changes" section header. When possible, make sure that stuff in text boxes could be entered literally. (Don't use "..." unless we want a user to type that.) Move 'commit -a' example into a literal code section, clarify that it finds modified files automatically. Signed-off-by: "J. Bruce Fields" Signed-off-by: Junio C Hamano --- Documentation/tutorial.txt | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) 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 From fffe694d607ea683b5d08ee99a46d9b06cb74006 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Sat, 6 Jan 2007 22:25:55 -0800 Subject: [PATCH 14/21] git-svn: fix show-ignore Looks like I broke it in 747fa12cef73b6ca04fffaddaad7326cf546cdea but never noticed. Signed-off-by: Eric Wong Signed-off-by: Junio C Hamano --- git-svn.perl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 { From 62e4f26f3d55bd66989d9b953988de18ba393417 Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Sun, 7 Jan 2007 02:52:23 +0100 Subject: [PATCH 15/21] gitweb: Fix error in git_patchest_body for file creation/deletion patch $from_id, $to_id variables should be local per PATCH. Fix error in git_patchset_body for file creation (deletion) patches, where instead of /dev/null as from-file (to-file) diff header line, it had link to previous file with current file name. This error occured only if there was another patch before file creation (deletion) patch. Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- gitweb/gitweb.perl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 7906280f26..04c8015c1d 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; @@ -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 From 2e1951f6eddfa070916a0e678aa508f73d92aa50 Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Sun, 7 Jan 2007 02:52:24 +0100 Subject: [PATCH 16/21] gitweb: Fix error in "rename to"/"copy to" git diff header output Fix error in git_patchset_body subroutine, which caused "rename to"/"copy to" line in extended diff header to be displayed incorrectly. While at it, fix align. Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- gitweb/gitweb.perl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 04c8015c1d..1b4a4c07b8 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -2479,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})$/) { From 66399eff86555fce52dc7b54829f02e4bb2424b7 Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Sun, 7 Jan 2007 02:52:25 +0100 Subject: [PATCH 17/21] gitweb: Fix errors in git_patchset_body for empty patches We now do not skip over empty patches in git_patchset_body (where empty means that they consist only of git diff header, and of extended diff header, for example "pure rename" patch). This means that after extended diff header there can be next patch (i.e. /^diff /) or end of patchset, and not necessary patch body (i.e. /^--- /). Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- gitweb/gitweb.perl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 1b4a4c07b8..7ebdfbbbd5 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -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; @@ -2522,6 +2522,8 @@ 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'}) { $patch_line = '--- a/' . From ac8b0cd1cd61f74b76261df17a15ada87f437269 Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Sun, 7 Jan 2007 02:52:26 +0100 Subject: [PATCH 18/21] Revert "gitweb: There can be empty patches (in git_patchset_body)" This reverts commit 1ebb948f656c03a5bdaab4de1a113b9ffcb98bea, as that patch quieted warning but was not proper solution. The previous commit was. Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- gitweb/gitweb.perl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 7ebdfbbbd5..d60d7c665a 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -2533,7 +2533,7 @@ 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; From 13e86efbeae5994a85cc482b3964db7298c5c6ea Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Sun, 7 Jan 2007 02:52:27 +0100 Subject: [PATCH 19/21] gitweb: Fix split patches output (e.g. file to symlink) Do not replace /dev/null in two-line from-file/to-file diff header for split patches ("split" patch mean more than one patch per one diff-tree raw line) by a/file or b/file link. Split patches differ from pair of deletion/creation patch in git diff header: both a/file and b/file are hyperlinks, in all patches in a split. Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- gitweb/gitweb.perl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index d60d7c665a..f46a42296d 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -2525,7 +2525,7 @@ sub git_patchset_body { 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'})); @@ -2537,7 +2537,7 @@ sub git_patchset_body { 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'})); From e9c8409900fc84cd7721117c98dfe01acd535aa2 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 5 Jan 2007 01:25:18 -0800 Subject: [PATCH 20/21] diff-index --cached --raw: show tree entry on the LHS for unmerged entries. This updates the way diffcore represents an unmerged pair somewhat. It used to be that entries with mode=0 on both sides were used to represent an unmerged pair, but now it has an explicit flag. This is to allow diff-index --cached to report the entry from the tree when the path is unmerged in the index. This is used in updating "git reset -- " to restore absense of the path in the index from the tree. Signed-off-by: Junio C Hamano --- diff-lib.c | 9 ++++++--- diff.c | 6 ++++-- diff.h | 4 +++- diffcore.h | 4 ++-- 4 files changed, 15 insertions(+), 8 deletions(-) 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) From bc8c0294c6ab673e465a8b564e22b1b9c2a2ea50 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 5 Jan 2007 01:38:56 -0800 Subject: [PATCH 21/21] git-reset -- restores absense of in When exists in the index (either merged or unmerged), and does not have it, git-reset should be usable to restore the absense of it from the tree. This implements it. Signed-off-by: Junio C Hamano --- git-reset.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) 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