* [PATCH] Fix up remaining man pages that use asciidoc "callouts".
From: Sean Estabrooks @ 2006-04-28 13:15 UTC (permalink / raw)
To: git; +Cc: Sean Estabrooks
In-Reply-To: <11462301063885-git-send-email-seanlkml@sympatico.ca>
Unfortunately docbook does not allow a callout to be
referenced from inside a callout list description.
Rewrite one paragraph in git-reset man page to work
around this limitation.
Signed-off-by: Sean Estabrooks <seanlkml@sympatico.ca>
---
Documentation/everyday.txt | 45 +++++++++++------------
Documentation/git-checkout.txt | 18 +++++----
Documentation/git-diff.txt | 38 ++++++++++---------
Documentation/git-init-db.txt | 8 ++--
Documentation/git-reset.txt | 72 ++++++++++++++++++------------------
Documentation/git-update-index.txt | 31 ++++++++--------
6 files changed, 104 insertions(+), 108 deletions(-)
481f9838c408f36fe74a44197865b54842174546
diff --git a/Documentation/everyday.txt b/Documentation/everyday.txt
index 3ab9b91..4b56370 100644
--- a/Documentation/everyday.txt
+++ b/Documentation/everyday.txt
@@ -61,7 +61,8 @@ Check health and remove cruft.::
$ git count-objects <2>
$ git repack <3>
$ git prune <4>
-
+------------
++
<1> running without "--full" is usually cheap and assures the
repository health reasonably well.
<2> check how many loose objects there are and how much
@@ -69,17 +70,16 @@ diskspace is wasted by not repacking.
<3> without "-a" repacks incrementally. repacking every 4-5MB
of loose objects accumulation may be a good rule of thumb.
<4> after repack, prune removes the duplicate loose objects.
-------------
Repack a small project into single pack.::
+
------------
$ git repack -a -d <1>
$ git prune
-
+------------
++
<1> pack all the objects reachable from the refs into one pack
and remove unneeded other packs
-------------
Individual Developer (Standalone)[[Individual Developer (Standalone)]]
@@ -129,10 +129,10 @@ Extract a tarball and create a working t
$ git add . <1>
$ git commit -m 'import of frotz source tree.'
$ git tag v2.43 <2>
-
+------------
++
<1> add everything under the current directory.
<2> make a lightweight, unannotated tag.
-------------
Create a topic branch and develop.::
+
@@ -153,7 +153,8 @@ Create a topic branch and develop.::
$ git pull . alsa-audio <10>
$ git log --since='3 days ago' <11>
$ git log v2.43.. curses/ <12>
-
+------------
++
<1> create a new topic branch.
<2> revert your botched changes in "curses/ux_audio_oss.c".
<3> you need to tell git if you added a new file; removal and
@@ -170,7 +171,6 @@ you originally wrote.
combined and include --max-count=10 (show 10 commits), --until='2005-12-10'.
<12> view only the changes that touch what's in curses/
directory, since v2.43 tag.
-------------
Individual Developer (Participant)[[Individual Developer (Participant)]]
@@ -208,7 +208,8 @@ Clone the upstream and work on it. Feed
$ git reset --hard ORIG_HEAD <6>
$ git prune <7>
$ git fetch --tags <8>
-
+------------
++
<1> repeat as needed.
<2> extract patches from your branch for e-mail submission.
<3> "pull" fetches from "origin" by default and merges into the
@@ -221,7 +222,6 @@ area we are interested in.
<7> garbage collect leftover objects from reverted pull.
<8> from time to time, obtain official tags from the "origin"
and store them under .git/refs/tags/.
-------------
Push into another repository.::
@@ -239,7 +239,8 @@ satellite$ git push origin <4>
mothership$ cd frotz
mothership$ git checkout master
mothership$ git pull . satellite <5>
-
+------------
++
<1> mothership machine has a frotz repository under your home
directory; clone from it to start a repository on the satellite
machine.
@@ -252,7 +253,6 @@ to local "origin" branch.
mothership machine. You could use this as a back-up method.
<5> on mothership machine, merge the work done on the satellite
machine into the master branch.
-------------
Branch off of a specific tag.::
+
@@ -262,12 +262,12 @@ Branch off of a specific tag.::
$ git checkout master
$ git format-patch -k -m --stdout v2.6.14..private2.6.14 |
git am -3 -k <2>
-
+------------
++
<1> create a private branch based on a well known (but somewhat behind)
tag.
<2> forward port all changes in private2.6.14 branch to master branch
without a formal "merging".
-------------
Integrator[[Integrator]]
@@ -317,7 +317,8 @@ My typical GIT day.::
$ git fetch ko && git show-branch master maint 'tags/ko-*' <11>
$ git push ko <12>
$ git push ko v0.99.9x <13>
-
+------------
++
<1> see what I was in the middle of doing, if any.
<2> see what topic branches I have and think about how ready
they are.
@@ -346,7 +347,6 @@ In the output from "git show-branch", "m
everything "ko-master" has.
<12> push out the bleeding edge.
<13> push the tag out, too.
-------------
Repository Administration[[Repository Administration]]
@@ -367,7 +367,6 @@ example of managing a shared central rep
Examples
~~~~~~~~
-
Run git-daemon to serve /pub/scm from inetd.::
+
------------
@@ -388,13 +387,13 @@ cindy:x:1002:1002::/home/cindy:/usr/bin/
david:x:1003:1003::/home/david:/usr/bin/git-shell
$ grep git /etc/shells <2>
/usr/bin/git-shell
-
+------------
++
<1> log-in shell is set to /usr/bin/git-shell, which does not
allow anything but "git push" and "git pull". The users should
get an ssh access to the machine.
<2> in many distributions /etc/shells needs to list what is used
as the login shell.
-------------
CVS-style shared repository.::
+
@@ -419,7 +418,8 @@ git:x:9418:alice,bob,cindy,david
refs/heads/master alice\|cindy
refs/heads/doc-update bob
refs/tags/v[0-9]* david
-
+------------
++
<1> place the developers into the same git group.
<2> and make the shared repository writable by the group.
<3> use update-hook example by Carl from Documentation/howto/
@@ -427,7 +427,6 @@ for branch policy control.
<4> alice and cindy can push into master, only bob can push into doc-update.
david is the release manager and is the only person who can
create and push version tags.
-------------
HTTP server to support dumb protocol transfer.::
+
@@ -435,7 +434,7 @@ HTTP server to support dumb protocol tra
dev$ git update-server-info <1>
dev$ ftp user@isp.example.com <2>
ftp> cp -r .git /home/user/myproject.git
-
+------------
++
<1> make sure your info/refs and objects/info/packs are up-to-date
<2> upload to public HTTP server hosted by your ISP.
-------------
diff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt
index 985bb2f..78f2fe6 100644
--- a/Documentation/git-checkout.txt
+++ b/Documentation/git-checkout.txt
@@ -66,19 +66,19 @@ the `Makefile` to two revisions back, de
mistake, and gets it back from the index.
+
------------
-$ git checkout master <1>
-$ git checkout master~2 Makefile <2>
+$ git checkout master <1>
+$ git checkout master~2 Makefile <2>
$ rm -f hello.c
-$ git checkout hello.c <3>
-
+$ git checkout hello.c <3>
+------------
++
<1> switch branch
<2> take out a file out of other commit
-<3> or "git checkout -- hello.c", as in the next example.
-------------
+<3> restore hello.c from HEAD of current branch
+
-If you have an unfortunate branch that is named `hello.c`, the
-last step above would be confused as an instruction to switch to
-that branch. You should instead write:
+If you have an unfortunate branch that is named `hello.c`, this
+step would be confused as an instruction to switch to that branch.
+You should instead write:
+
------------
$ git checkout -- hello.c
diff --git a/Documentation/git-diff.txt b/Documentation/git-diff.txt
index 890931c..7267bcd 100644
--- a/Documentation/git-diff.txt
+++ b/Documentation/git-diff.txt
@@ -46,40 +46,41 @@ EXAMPLES
Various ways to check your working tree::
+
------------
-$ git diff <1>
-$ git diff --cached <2>
-$ git diff HEAD <3>
-
+$ git diff <1>
+$ git diff --cached <2>
+$ git diff HEAD <3>
+------------
++
<1> changes in the working tree since your last git-update-index.
<2> changes between the index and your last commit; what you
would be committing if you run "git commit" without "-a" option.
<3> changes in the working tree since your last commit; what you
would be committing if you run "git commit -a"
-------------
Comparing with arbitrary commits::
+
------------
-$ git diff test <1>
-$ git diff HEAD -- ./test <2>
-$ git diff HEAD^ HEAD <3>
-
+$ git diff test <1>
+$ git diff HEAD -- ./test <2>
+$ git diff HEAD^ HEAD <3>
+------------
++
<1> instead of using the tip of the current branch, compare with the
tip of "test" branch.
<2> instead of comparing with the tip of "test" branch, compare with
the tip of the current branch, but limit the comparison to the
file "test".
<3> compare the version before the last commit and the last commit.
-------------
Limiting the diff output::
+
------------
-$ git diff --diff-filter=MRC <1>
-$ git diff --name-status -r <2>
-$ git diff arch/i386 include/asm-i386 <3>
-
+$ git diff --diff-filter=MRC <1>
+$ git diff --name-status -r <2>
+$ git diff arch/i386 include/asm-i386 <3>
+------------
++
<1> show only modification, rename and copy, but not addition
nor deletion.
<2> show only names and the nature of change, but not actual
@@ -88,18 +89,17 @@ which in turn also disables recursive be
you would only see the directory name if there is a change in a
file in a subdirectory.
<3> limit diff output to named subtrees.
-------------
Munging the diff output::
+
------------
-$ git diff --find-copies-harder -B -C <1>
-$ git diff -R <2>
-
+$ git diff --find-copies-harder -B -C <1>
+$ git diff -R <2>
+------------
++
<1> spend extra cycles to find renames, copies and complete
rewrites (very expensive).
<2> output diff in reverse.
-------------
Author
diff --git a/Documentation/git-init-db.txt b/Documentation/git-init-db.txt
index aeb1115..8a150d8 100644
--- a/Documentation/git-init-db.txt
+++ b/Documentation/git-init-db.txt
@@ -60,12 +60,12 @@ Start a new git repository for an existi
+
----------------
$ cd /path/to/my/codebase
-$ git-init-db <1>
-$ git-add . <2>
-
+$ git-init-db <1>
+$ git-add . <2>
+----------------
++
<1> prepare /path/to/my/codebase/.git directory
<2> add all existing file to the index
-----------------
Author
diff --git a/Documentation/git-reset.txt b/Documentation/git-reset.txt
index b7b9798..b17cdba 100644
--- a/Documentation/git-reset.txt
+++ b/Documentation/git-reset.txt
@@ -49,10 +49,11 @@ Undo a commit and redo::
+
------------
$ git commit ...
-$ git reset --soft HEAD^ <1>
-$ edit <2>
-$ git commit -a -c ORIG_HEAD <3>
-
+$ git reset --soft HEAD^ <1>
+$ edit <2>
+$ git commit -a -c ORIG_HEAD <3>
+------------
++
<1> This is most often done when you remembered what you
just committed is incomplete, or you misspelled your commit
message, or both. Leaves working tree as it was before "reset".
@@ -60,43 +61,43 @@ message, or both. Leaves working tree a
<3> "reset" copies the old head to .git/ORIG_HEAD; redo the
commit by starting with its log message. If you do not need to
edit the message further, you can give -C option instead.
-------------
Undo commits permanently::
+
------------
$ git commit ...
-$ git reset --hard HEAD~3 <1>
-
+$ git reset --hard HEAD~3 <1>
+------------
++
<1> The last three commits (HEAD, HEAD^, and HEAD~2) were bad
and you do not want to ever see them again. Do *not* do this if
you have already given these commits to somebody else.
-------------
Undo a commit, making it a topic branch::
+
------------
-$ git branch topic/wip <1>
-$ git reset --hard HEAD~3 <2>
-$ git checkout topic/wip <3>
-
+$ git branch topic/wip <1>
+$ git reset --hard HEAD~3 <2>
+$ git checkout topic/wip <3>
+------------
++
<1> You have made some commits, but realize they were premature
to be in the "master" branch. You want to continue polishing
them in a topic branch, so create "topic/wip" branch off of the
current HEAD.
<2> Rewind the master branch to get rid of those three commits.
<3> Switch to "topic/wip" branch and keep working.
-------------
Undo update-index::
+
------------
-$ edit <1>
+$ edit <1>
$ git-update-index frotz.c filfre.c
-$ mailx <2>
-$ git reset <3>
-$ git pull git://info.example.com/ nitfol <4>
-
+$ mailx <2>
+$ git reset <3>
+$ git pull git://info.example.com/ nitfol <4>
+------------
++
<1> you are happily working on something, and find the changes
in these files are in good order. You do not want to see them
when you run "git diff", because you plan to work on other files
@@ -109,12 +110,11 @@ index changes for these two files. Your
remain there.
<4> then you can pull and merge, leaving frotz.c and filfre.c
changes still in the working tree.
-------------
Undo a merge or pull::
+
------------
-$ git pull <1>
+$ git pull <1>
Trying really trivial in-index merge...
fatal: Merge requires file-level merging
Nope.
@@ -122,20 +122,19 @@ Nope.
Auto-merging nitfol
CONFLICT (content): Merge conflict in nitfol
Automatic merge failed/prevented; fix up by hand
-$ git reset --hard <2>
-
+$ git reset --hard <2>
+$ git pull . topic/branch <3>
+Updating from 41223... to 13134...
+Fast forward
+$ git reset --hard ORIG_HEAD <4>
+------------
++
<1> try to update from the upstream resulted in a lot of
conflicts; you were not ready to spend a lot of time merging
right now, so you decide to do that later.
<2> "pull" has not made merge commit, so "git reset --hard"
which is a synonym for "git reset --hard HEAD" clears the mess
from the index file and the working tree.
-
-$ git pull . topic/branch <3>
-Updating from 41223... to 13134...
-Fast forward
-$ git reset --hard ORIG_HEAD <4>
-
<3> merge a topic branch into the current branch, which resulted
in a fast forward.
<4> but you decided that the topic branch is not ready for public
@@ -143,7 +142,6 @@ consumption yet. "pull" or "merge" alwa
tip of the current branch in ORIG_HEAD, so resetting hard to it
brings your index file and the working tree back to that state,
and resets the tip of the branch to that commit.
-------------
Interrupted workflow::
+
@@ -155,21 +153,21 @@ need to get to the other branch for a qu
------------
$ git checkout feature ;# you were working in "feature" branch and
$ work work work ;# got interrupted
-$ git commit -a -m 'snapshot WIP' <1>
+$ git commit -a -m 'snapshot WIP' <1>
$ git checkout master
$ fix fix fix
$ git commit ;# commit with real log
$ git checkout feature
-$ git reset --soft HEAD^ ;# go back to WIP state <2>
-$ git reset <3>
-
+$ git reset --soft HEAD^ ;# go back to WIP state <2>
+$ git reset <3>
+------------
++
<1> This commit will get blown away so a throw-away log message is OK.
<2> This removes the 'WIP' commit from the commit history, and sets
your working tree to the state just before you made that snapshot.
-<3> After <2>, the index file still has all the WIP changes you
- committed in <1>. This sets it to the last commit you were
- basing the WIP changes on.
-------------
+<3> At this point the index file still has all the WIP changes you
+ committed as 'snapshot WIP'. This updates the index to show your
+ WIP files as uncommitted.
Author
------
diff --git a/Documentation/git-update-index.txt b/Documentation/git-update-index.txt
index 0a1b0ad..d4137fc 100644
--- a/Documentation/git-update-index.txt
+++ b/Documentation/git-update-index.txt
@@ -247,34 +247,33 @@ To update and refresh only the files alr
$ git-checkout-index -n -f -a && git-update-index --ignore-missing --refresh
----------------
-On an inefficient filesystem with `core.ignorestat` set:
-
+On an inefficient filesystem with `core.ignorestat` set::
++
------------
-$ git update-index --really-refresh <1>
-$ git update-index --no-assume-unchanged foo.c <2>
-$ git diff --name-only <3>
+$ git update-index --really-refresh <1>
+$ git update-index --no-assume-unchanged foo.c <2>
+$ git diff --name-only <3>
$ edit foo.c
-$ git diff --name-only <4>
+$ git diff --name-only <4>
M foo.c
-$ git update-index foo.c <5>
-$ git diff --name-only <6>
+$ git update-index foo.c <5>
+$ git diff --name-only <6>
$ edit foo.c
-$ git diff --name-only <7>
-$ git update-index --no-assume-unchanged foo.c <8>
-$ git diff --name-only <9>
+$ git diff --name-only <7>
+$ git update-index --no-assume-unchanged foo.c <8>
+$ git diff --name-only <9>
M foo.c
-
-<1> forces lstat(2) to set "assume unchanged" bits for paths
- that match index.
+------------
++
+<1> forces lstat(2) to set "assume unchanged" bits for paths that match index.
<2> mark the path to be edited.
<3> this does lstat(2) and finds index matches the path.
-<4> this does lstat(2) and finds index does not match the path.
+<4> this does lstat(2) and finds index does *not* match the path.
<5> registering the new version to index sets "assume unchanged" bit.
<6> and it is assumed unchanged.
<7> even after you edit it.
<8> you can tell about the change after the fact.
<9> now it checks with lstat(2) and finds it has been changed.
-------------
Configuration
--
1.3.1.gc672
^ permalink raw reply related
* Re: Fix asciidoc callouts in git man pages
From: Jakub Narebski @ 2006-04-28 14:06 UTC (permalink / raw)
To: git
In-Reply-To: <BAYC1-PASMTP1046BB48C01D83AC57A694AEB20@CEZ.ICE>
<opublikowany i wysłany>
Sean Estabrooks wrote:
> Started out just wanting to update the git-branch man page
> to include the "-r" option but noticed that the asciidoc
> callouts weren't being rendered in its man page. Then
> noticed the same was true for all the man pages where
> they are used.
>
> It turns out we've not been following the guidelines
> properly on how to use them. The fact that they show up
> in a useful way in the html docs is really an accident.
> Even there they're not showing up as intended.
>
> Unfortunately, even after all the docs are fixed up to use
> the proper format, they still don't render properly in the
> man format. Seems this is a missing feature in the "xmlto"
> command.
>
> The final patch in this series adds an xsl fragment which
> is passed to xmlto so that the callouts appear properly in
> the man pages.
Have you sent bugreport/patch to the authors of asciidoc, by the way?
--
Jakub Narebski
Warsaw, Poland
^ permalink raw reply
* Re: Fix asciidoc callouts in git man pages
From: sean @ 2006-04-28 14:15 UTC (permalink / raw)
To: Jakub Narebski; +Cc: git
In-Reply-To: <e2t7f6$p1i$1@sea.gmane.org>
On Fri, 28 Apr 2006 16:06:06 +0200
Jakub Narebski <jnareb@gmail.com> wrote:
> Have you sent bugreport/patch to the authors of asciidoc, by the way?
Have now ;o) My xsl skills probably won't impress them any, but perhaps
they'll put some time into including the feature in a future release.
Cheers,
Sean
^ permalink raw reply
* [PATCH]: Allow misc https cert for git-svnimport
From: P. Christeas @ 2006-04-28 15:01 UTC (permalink / raw)
To: Eric Wong, git
[-- Attachment #1: Type: text/plain, Size: 111 bytes --]
Just had to access a server with a broken certificate (self signed), so I
added that patch to git-svnimport.
[-- Attachment #2: git-svnimport-ssl.patch --]
[-- Type: text/x-diff, Size: 2265 bytes --]
--- /usr/bin/git-svnimport 2006-04-13 09:39:39.000000000 +0300
+++ /home/panos/bin/git-svnimport 2006-04-28 17:55:45.000000000 +0300
@@ -96,9 +96,14 @@
sub conn {
my $self = shift;
my $repo = $self->{'fullrep'};
- my $auth = SVN::Core::auth_open ([SVN::Client::get_simple_provider,
+# my $auth = SVN::Core::auth_open ([SVN::Client::get_simple_provider,
+# SVN::Client::get_ssl_server_trust_file_provider,
+# SVN::Client::get_ssl_server_trust_prompt_provider(\&_trust_callback),
+# SVN::Client::get_username_provider]);
+ my $auth = [SVN::Client::get_simple_provider,
SVN::Client::get_ssl_server_trust_file_provider,
- SVN::Client::get_username_provider]);
+ SVN::Client::get_ssl_server_trust_prompt_provider(\&_trust_callback),
+ SVN::Client::get_username_provider];
my $s = SVN::Ra->new(url => $repo, auth => $auth);
die "SVN connection to $repo: $!\n" unless defined $s;
$self->{'svn'} = $s;
@@ -125,6 +130,45 @@
return $name;
}
+sub _trust_callback {
+ my ($cred,$realm,$ifailed,$server_cert_info,$may_save) = @_;
+ #$cred->accepted_failures($SVN::Auth::SSL::UNKNOWNCA);
+ print "SSL certificate is not trusted: $ifailed \n";
+ print "Fingerprint: " . $server_cert_info->fingerprint . "\n";
+ print "Hostname: ". $server_cert_info->hostname ;
+ print " (MISMATCH)" if ( $ifailed & $SVN::Auth::SSL::CNMISMATCH);
+ print "\n";
+
+ print "Valid from: ". $server_cert_info->valid_from;
+ print " (NOT YET)" if ( $ifailed & $SVN::Auth::SSL::NOTYETVALID);
+ print "\n";
+
+ print "Valid until: ". $server_cert_info->valid_until;
+ print " (EXPIRED)" if ( $ifailed & $SVN::Auth::SSL::EXPIRED);
+ print "\n";
+
+ print "Issuer: ". $server_cert_info->issuer_dname;
+ print " (UNKNOWN)" if ( $ifailed & $SVN::Auth::SSL::UNKNOWNCA);
+ print "\n\n";
+
+ print "Do you still want to accept that certificate? [y/N] ";
+ my $accept = <STDIN>;
+ chomp($accept);
+ print "\n";
+ if (($accept eq "y") or ($accept eq "Y" )) {
+ $cred->accepted_failures($ifailed);
+ # print "Save cert, so that it is accepted in future calls? [y/N] ";
+ # my $mmsave = <STDIN>;
+ # chomp($mmsave);
+ # if (($mmsave eq "y") or ($mmsave eq "Y" )) {
+ # $may_save = 1;
+ # }
+ print "\n";
+ }
+
+}
+
+
package main;
use URI;
^ permalink raw reply
* Re: Two gitweb feature requests
From: sean @ 2006-04-28 16:26 UTC (permalink / raw)
To: David Woodhouse; +Cc: kay.sievers, git
In-Reply-To: <1146144425.11909.450.camel@pmac.infradead.org>
On Thu, 27 Apr 2006 14:27:05 +0100
David Woodhouse <dwmw2@infradead.org> wrote:
> First... When publishing trees, I currently give both the git:// URL for
> people who want to pull the tree, and the http:// URL to gitweb for
> those who just want to browse.
>
> It would be useful if I could get away with giving just one URL --
> probably the http:// one to gitweb. If gitweb were to have a mode in
> which it gave a referral to the git:// URL, and if the git tools would
> use that, then that would work well.
This sounds like a good idea.
> Secondly, it would be useful if gitweb would list the branches in a
> repository and allow each of them to be viewed in the same way as it
> does the master branch.
At the bottom of the Summary page it already lists the branches,
underneath the tags.
Sean
^ permalink raw reply
* Re: Two gitweb feature requests
From: Jakub Narebski @ 2006-04-28 17:37 UTC (permalink / raw)
To: git
In-Reply-To: <1146144425.11909.450.camel@pmac.infradead.org>
I'd like to have 'parent directory' link for trees ('..' link) at the top of
it's contents. I know it is possible to use browser history for that, but
it would give greater similarity with 'directory listing' mode of WWW
servers.
--
Jakub Narebski
Warsaw, Poland
^ permalink raw reply
* Re: Two gitweb feature requests
From: Linus Torvalds @ 2006-04-28 18:23 UTC (permalink / raw)
To: Jakub Narebski; +Cc: git
In-Reply-To: <e2tjqm$83n$1@sea.gmane.org>
On Fri, 28 Apr 2006, Jakub Narebski wrote:
>
> I'd like to have 'parent directory' link for trees ('..' link) at the top of
> it's contents. I know it is possible to use browser history for that, but
> it would give greater similarity with 'directory listing' mode of WWW
> servers.
Well, a git "tree" doesn't actually _have_ a parent. It potentially has
multiple.
So to get to "a parent", you literally do need to keep track of how you
got to the tree. Which is certainly possible (maybe it even ends up being
in the URI that gitk generates, I didn't check), but basically, if it
isn't tracked explicitly, it basically is impossible to find.
Not having back-pointers is what allows git to do data sharing and a lot
of other things efficiently. A tree is a tree is a tree, and has zero data
about what points to it, so as long as the _contents_ of a tree are the
same, you have exactly the same object. That means that the same subtree
can - and will - be pointed to by multiple upper-level trees and commits.
So you do need that "browser history" one way or another. Either in the
browser (use the "back button") or by encoding the "how did we get here"
information in the URI and the dynamically generated page content.
The downside is that you'd have two different web-pages for the same tree
depending on which commit it came from. Which is not a downside from a
user perspective, but it's a downside from a caching/server perspective,
since it means less reuse of pages (maybe gitweb already does that,
though).
Linus
^ permalink raw reply
* Re: Two gitweb feature requests
From: Jakub Narebski @ 2006-04-28 19:11 UTC (permalink / raw)
To: git
In-Reply-To: <Pine.LNX.4.64.0604281116020.3701@g5.osdl.org>
Linus Torvalds wrote:
> On Fri, 28 Apr 2006, Jakub Narebski wrote:
>>
>> I'd like to have 'parent directory' link for trees ('..' link) at the top
>> of it's contents. I know it is possible to use browser history for that,
>> but it would give greater similarity with 'directory listing' mode of WWW
>> servers.
>
> Well, a git "tree" doesn't actually _have_ a parent. It potentially has
> multiple.
I have forgot about that. Sorry for the noise, then.
[...]
> So you do need that "browser history" one way or another. Either in the
> browser (use the "back button") or by encoding the "how did we get here"
> information in the URI and the dynamically generated page content.
Or use JavaScript via <a href="javascript:history.go(-1)">..</a>
But that wouldn't help me, because when I open the link in new window (new
tab), the new window (new tab) doesn't inherit history from parent... so
browser's "back" button doesn't work. Ah, well...
> The downside is that you'd have two different web-pages for the same tree
> depending on which commit it came from. Which is not a downside from a
> user perspective, but it's a downside from a caching/server perspective,
> since it means less reuse of pages (maybe gitweb already does that,
> though).
Perhaps if "how we get there" information was encoded via POST... but I
don't know if there would be the difference in caching c.f. GET (encoding
in URI).
--
Jakub Narebski
Warsaw, Poland
^ permalink raw reply
* Re: bug: git-repack -a -d produces broken pack on NFS
From: Alex Riesen @ 2006-04-28 22:27 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Junio C Hamano, Git Mailing List
In-Reply-To: <Pine.LNX.4.64.0604271500500.3701@g5.osdl.org>
Linus Torvalds, Fri, Apr 28, 2006 00:11:13 +0200:
> > NFS server: 2.6.15
> > Client: 2.6.17-rc2
> > mount options: tigra:/home /net/home nfs rw,nosuid,nodev,noatime,vers=3,rsize=8192,wsize=32768,hard,intr,proto=udp,timeo=7,retrans=3,addr=tigra 0 0
>
> It's repeatable? Can you check if it goes away if your remove "intr"?
It does not go away if I remove intr:
$ grep 'nfs\>' /proc/mounts
tigra:/home /net/home nfs rw,nosuid,nodev,noatime,vers=3,rsize=8192,wsize=32768,hard,proto=udp,timeo=7,retrans=3,addr=tigra 0 0
And this is really a broken packfile:
$ git fsck-objects --full
git-fsck-objects: error: Packfile .git/objects/pack/pack-9021635f04e29bb9f3313a54124f64589eca5764.pack SHA1 mismatch with itself
git-fsck-objects: fatal: failed to read delta-pack base object a23816d3e9a1684794c8e5a8f1cc0cce26fb61d8
And I actually was kind of sure about the hardware (like in: "it
worked flawlessly for in the past 2 years"). Until looked today in the
logs and saw this:
Apr 19 11:49:35 tigra kernel: eth1: tx underrun with maximum tx threshold, txcfg 0xd0f0102e.
Apr 19 11:49:35 tigra kernel: eth1: Link wake-up event 0xffffffff
Apr 19 11:49:35 tigra kernel: eth1: PCI error 0xf00000
Well, this is actually not _that_ day. And this:
Apr 28 23:42:19 tigra kernel: eth1: tx underrun with maximum tx threshold, txcfg 0xd0f0102e.
is not exactly the time of most recent test (the one without the "hard"
mount option). But this _is_ that very same interface, and "PCI error"
looks nasty. Ok, looking at the card... Seats kinda skewed in the
slot, pressing on it... Wow! (lights go out):
Apr 29 00:13:35 tigra kernel: eth1: Link wake-up event 0x00020b
Apr 29 00:13:35 tigra kernel: eth1: PCI error 0xf00000
Apr 29 00:13:39 tigra kernel: NETDEV WATCHDOG: eth1: transmit timed out
Apr 29 00:13:39 tigra kernel: eth1: Transmit timed out, status 0x000000, resetting...
Apr 29 00:13:39 tigra kernel: eth1: DSPCFG accepted after 0 usec.
Apr 29 00:13:39 tigra kernel: eth1: Setting full-duplex based on negotiated link capability.
Redoing test... (Two times only, it's late already):
$SRC/test2.git$ git repack -a -d
Generating pack...
Done counting 235775 objects.
Deltifying 235775 objects.
100% (235775/235775) done
Writing 235775 objects.
100% (235775/235775) done
Total 235775, written 235775 (delta 181885), reused 223766 (delta 171462)
Pack pack-9021635f04e29bb9f3313a54124f64589eca5764 created.
$SRC/test2.git$ git fsck-objects --full
dangling blob 419301f9bff67932cb9551f2d8436b277a3022b0
$SRC/test2.git$ git repack -a -d
Generating pack...
Done counting 235775 objects.
Deltifying 235775 objects.
100% (235775/235775) done
Writing 235775 objects.
100% (235775/235775) done
Total 235775, written 235775 (delta 181958), reused 235702 (delta 181885)
Pack pack-9021635f04e29bb9f3313a54124f64589eca5764 created.
$SRC/test2.git$ git fsck-objects --full
dangling blob 419301f9bff67932cb9551f2d8436b277a3022b0
Hmm... Ok, apologies everyone, I'm just lazy and stupid.
Still, would be nice not to loose a repository just because
user is an idiot.
^ permalink raw reply
* Re: bug: git-repack -a -d produces broken pack on NFS
From: Linus Torvalds @ 2006-04-28 23:18 UTC (permalink / raw)
To: Alex Riesen; +Cc: Junio C Hamano, Git Mailing List
In-Reply-To: <20060428222750.GA6462@steel.home>
On Sat, 29 Apr 2006, Alex Riesen wrote:
>
> mount option). But this _is_ that very same interface, and "PCI error"
> looks nasty. Ok, looking at the card... Seats kinda skewed in the
> slot, pressing on it... Wow! (lights go out):
>
> Apr 29 00:13:35 tigra kernel: eth1: Link wake-up event 0x00020b
> Apr 29 00:13:35 tigra kernel: eth1: PCI error 0xf00000
> Apr 29 00:13:39 tigra kernel: NETDEV WATCHDOG: eth1: transmit timed out
> Apr 29 00:13:39 tigra kernel: eth1: Transmit timed out, status 0x000000, resetting...
> Apr 29 00:13:39 tigra kernel: eth1: DSPCFG accepted after 0 usec.
> Apr 29 00:13:39 tigra kernel: eth1: Setting full-duplex based on negotiated link capability.
Ok, that "PCI error" meaning is not entirely clear, but it sounds like
noise on the line. The driver just has a comment saying
/* Hmmmmm, it's not clear how to recover from PCI faults. */
and it's actually pretty possible (and even likely) that whatever
corrupted the pack-file happened on the _send_ side, so by the time we get
a PCI error report, there's already a packet out the door that likely has
corrupted data.
Now, corrupted data would normally be caught by the UDP checksum, but:
- a lot of modern cards do the IP checksum on the card. Whether the
natsemi driver does or not, I have no clue. If it does, it would always
make the checksum match the (corrupted) data.
- the IP-level checksums are really quite weak. Realistically, you really
really _really_ want to have link-layer checksums working, but since
the link-level checksum is _always_ computed by the card (and since a
PCI error would have corrupted the packet data that the card saw),
link-level checksums will always have the same error that the data got,
and pass.
So even if we did the UDP checksum in software, it has a reasonable
chance of not triggering. It's just 16 bits, and not a _good_ 16 bits
at that.
Anyway, definitely looks hw-induced.
> Hmm... Ok, apologies everyone, I'm just lazy and stupid.
Having flaky hw is just unhappy. I'm glad git caught it quickly.
> Still, would be nice not to loose a repository just because
> user is an idiot.
Well, there's two sides to this:
- packs are very much designed to be very very dense. That means that
even the _slightest_ corruption will likely totally destroy them. Even
a single-bit flip likely causes massive damage to an archive.
This is a direct and unavoidable consequence of compression and
density. A less dense format automatically has a lot more redundant
data, and the less dense it is, the more likely you can recover from
single-bit errors (or even worse ones).
So this is the downside to compression and packing. All forms of
compression (and we do both traditional stream-compression with zlib
and aggressive delta compression between objects) inevitably make the
effects of corruption much worse, and much harder to recover from.
That's the bad part.
- The good part is that replication is obviously trivial, and git is
inherently very good at making incremental backups.
Now, we could try to have something that tries to recover as much of a
corrupted pack-file as possible. Right now, git-unpack-objects just dies
(as early as possible) if the pack is corrupt. Having some mode where it
tries to recover from errors and continue would probably be a good
debugging and recovery tool.
Linus
^ permalink raw reply
* Do not use zlib 1.1.3 with git packs!
From: Johannes Schindelin @ 2006-04-29 0:52 UTC (permalink / raw)
To: git
Hi,
I had a strange effect when trying to repack a git repository on my iBook:
first, "git-repack -a -d" would quit without an error message when about
57% of the objects were written (*not* when deltifying them!).
It became even stranger when I tracked it to a segmentation fault in
adler32(), where the debugger insisted that a buffer was NULL, but the
calling code insisted it was not.
Upgrading to zlib 1.2.3 helped. That is, after I had a complete systen
fsck-up, since virtually every binary, including su, login and getty, are
linked to zlib on Mac OS X. (Yeah, yeah, no Linux, I know.)
Ciao,
Dscho
P.S.: This _might_ be related to the git-repack issue that came up a few
days ago.
^ permalink raw reply
* Re: Do not use zlib 1.1.3 with git packs!
From: Johannes Schindelin @ 2006-04-29 1:47 UTC (permalink / raw)
To: git
In-Reply-To: <Pine.LNX.4.63.0604290245510.30565@wbgn013.biozentrum.uni-wuerzburg.de>
Hi,
On Sat, 29 Apr 2006, Johannes Schindelin wrote:
> Upgrading to zlib 1.2.3 helped.
Apparently I was too enthusiastic to have a working system again.
The problem showed again, but with a different repository.
This time, though, I have an idea what could be the culprit.
In create_delta(), there might be illegal accesses. The function adler32()
is called for BLK_SIZE bytes (which is 16 bytes at the moment), starting
from data, which is initially trg_buf, and is incremented until it is
(trg_buf + trg_size).
I gather that close to the end, adler32() tries to read 15 bytes after the
end of the allocated target buffer.
Am I wrong?
Ciao,
Dscho
^ permalink raw reply
* Re: Do not use zlib 1.1.3 with git packs!
From: Nicolas Pitre @ 2006-04-29 3:20 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: git
In-Reply-To: <Pine.LNX.4.63.0604290341380.22696@wbgn013.biozentrum.uni-wuerzburg.de>
On Sat, 29 Apr 2006, Johannes Schindelin wrote:
> Hi,
>
> On Sat, 29 Apr 2006, Johannes Schindelin wrote:
>
> > Upgrading to zlib 1.2.3 helped.
>
> Apparently I was too enthusiastic to have a working system again.
>
> The problem showed again, but with a different repository.
>
> This time, though, I have an idea what could be the culprit.
>
> In create_delta(), there might be illegal accesses. The function adler32()
> is called for BLK_SIZE bytes (which is 16 bytes at the moment), starting
> from data, which is initially trg_buf, and is incremented until it is
> (trg_buf + trg_size).
>
> I gather that close to the end, adler32() tries to read 15 bytes after the
> end of the allocated target buffer.
>
> Am I wrong?
You're not. My bad.
(I'm testing a version where adler32 has been replaced with rabin
polynomial so that issue will be gone at the same time.
A patch should be coming in less than an hour.)
Nicolas
^ permalink raw reply
* [PATCH] replace adler32 with Rabin's polynomial in diff-delta
From: Nicolas Pitre @ 2006-04-29 4:58 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Johannes Schindelin, git
This brings another small repacking speedup for sensibly the same pack
size. On the Linux kernel repo, git-repack -a -f is 3.7% faster for a
0.4% larger pack.
Credits to Geert Bosch who brought the Rabin's polynomial idea to my
attention.
This also eliminate the issue of adler32() reading past the data buffer,
as noticed by Johannes Schindelin.
Signed-off-by: Nicolas Pitre <nico@cam.org>
---
diff --git a/Makefile b/Makefile
index 8ce27a6..c13208f 100644
--- a/Makefile
+++ b/Makefile
@@ -609,7 +609,7 @@ test-date$X: test-date.c date.o ctype.o
$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) test-date.c date.o ctype.o
test-delta$X: test-delta.c diff-delta.o patch-delta.o
- $(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $^ -lz
+ $(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $^
check:
for i in *.c; do sparse $(ALL_CFLAGS) $(SPARSE_FLAGS) $$i || exit; done
diff --git a/diff-delta.c b/diff-delta.c
index fdedf94..a40a89c 100644
--- a/diff-delta.c
+++ b/diff-delta.c
@@ -20,18 +20,106 @@
#include <stdlib.h>
#include <string.h>
-#include <zlib.h>
#include "delta.h"
-/* block size: min = 16, max = 64k, power of 2 */
-#define BLK_SIZE 16
-
/* maximum hash entry list for the same hash bucket */
#define HASH_LIMIT 64
-#define GR_PRIME 0x9e370001
-#define HASH(v, shift) (((unsigned int)(v) * GR_PRIME) >> (shift))
+#define RABIN_SHIFT 23
+#define RABIN_WINDOW 16
+
+static const unsigned int T[256] = {
+ 0x00000000, 0xab59b4d1, 0x56b369a2, 0xfdeadd73, 0x063f6795, 0xad66d344,
+ 0x508c0e37, 0xfbd5bae6, 0x0c7ecf2a, 0xa7277bfb, 0x5acda688, 0xf1941259,
+ 0x0a41a8bf, 0xa1181c6e, 0x5cf2c11d, 0xf7ab75cc, 0x18fd9e54, 0xb3a42a85,
+ 0x4e4ef7f6, 0xe5174327, 0x1ec2f9c1, 0xb59b4d10, 0x48719063, 0xe32824b2,
+ 0x1483517e, 0xbfdae5af, 0x423038dc, 0xe9698c0d, 0x12bc36eb, 0xb9e5823a,
+ 0x440f5f49, 0xef56eb98, 0x31fb3ca8, 0x9aa28879, 0x6748550a, 0xcc11e1db,
+ 0x37c45b3d, 0x9c9defec, 0x6177329f, 0xca2e864e, 0x3d85f382, 0x96dc4753,
+ 0x6b369a20, 0xc06f2ef1, 0x3bba9417, 0x90e320c6, 0x6d09fdb5, 0xc6504964,
+ 0x2906a2fc, 0x825f162d, 0x7fb5cb5e, 0xd4ec7f8f, 0x2f39c569, 0x846071b8,
+ 0x798aaccb, 0xd2d3181a, 0x25786dd6, 0x8e21d907, 0x73cb0474, 0xd892b0a5,
+ 0x23470a43, 0x881ebe92, 0x75f463e1, 0xdeadd730, 0x63f67950, 0xc8afcd81,
+ 0x354510f2, 0x9e1ca423, 0x65c91ec5, 0xce90aa14, 0x337a7767, 0x9823c3b6,
+ 0x6f88b67a, 0xc4d102ab, 0x393bdfd8, 0x92626b09, 0x69b7d1ef, 0xc2ee653e,
+ 0x3f04b84d, 0x945d0c9c, 0x7b0be704, 0xd05253d5, 0x2db88ea6, 0x86e13a77,
+ 0x7d348091, 0xd66d3440, 0x2b87e933, 0x80de5de2, 0x7775282e, 0xdc2c9cff,
+ 0x21c6418c, 0x8a9ff55d, 0x714a4fbb, 0xda13fb6a, 0x27f92619, 0x8ca092c8,
+ 0x520d45f8, 0xf954f129, 0x04be2c5a, 0xafe7988b, 0x5432226d, 0xff6b96bc,
+ 0x02814bcf, 0xa9d8ff1e, 0x5e738ad2, 0xf52a3e03, 0x08c0e370, 0xa39957a1,
+ 0x584ced47, 0xf3155996, 0x0eff84e5, 0xa5a63034, 0x4af0dbac, 0xe1a96f7d,
+ 0x1c43b20e, 0xb71a06df, 0x4ccfbc39, 0xe79608e8, 0x1a7cd59b, 0xb125614a,
+ 0x468e1486, 0xedd7a057, 0x103d7d24, 0xbb64c9f5, 0x40b17313, 0xebe8c7c2,
+ 0x16021ab1, 0xbd5bae60, 0x6cb54671, 0xc7ecf2a0, 0x3a062fd3, 0x915f9b02,
+ 0x6a8a21e4, 0xc1d39535, 0x3c394846, 0x9760fc97, 0x60cb895b, 0xcb923d8a,
+ 0x3678e0f9, 0x9d215428, 0x66f4eece, 0xcdad5a1f, 0x3047876c, 0x9b1e33bd,
+ 0x7448d825, 0xdf116cf4, 0x22fbb187, 0x89a20556, 0x7277bfb0, 0xd92e0b61,
+ 0x24c4d612, 0x8f9d62c3, 0x7836170f, 0xd36fa3de, 0x2e857ead, 0x85dcca7c,
+ 0x7e09709a, 0xd550c44b, 0x28ba1938, 0x83e3ade9, 0x5d4e7ad9, 0xf617ce08,
+ 0x0bfd137b, 0xa0a4a7aa, 0x5b711d4c, 0xf028a99d, 0x0dc274ee, 0xa69bc03f,
+ 0x5130b5f3, 0xfa690122, 0x0783dc51, 0xacda6880, 0x570fd266, 0xfc5666b7,
+ 0x01bcbbc4, 0xaae50f15, 0x45b3e48d, 0xeeea505c, 0x13008d2f, 0xb85939fe,
+ 0x438c8318, 0xe8d537c9, 0x153feaba, 0xbe665e6b, 0x49cd2ba7, 0xe2949f76,
+ 0x1f7e4205, 0xb427f6d4, 0x4ff24c32, 0xe4abf8e3, 0x19412590, 0xb2189141,
+ 0x0f433f21, 0xa41a8bf0, 0x59f05683, 0xf2a9e252, 0x097c58b4, 0xa225ec65,
+ 0x5fcf3116, 0xf49685c7, 0x033df00b, 0xa86444da, 0x558e99a9, 0xfed72d78,
+ 0x0502979e, 0xae5b234f, 0x53b1fe3c, 0xf8e84aed, 0x17bea175, 0xbce715a4,
+ 0x410dc8d7, 0xea547c06, 0x1181c6e0, 0xbad87231, 0x4732af42, 0xec6b1b93,
+ 0x1bc06e5f, 0xb099da8e, 0x4d7307fd, 0xe62ab32c, 0x1dff09ca, 0xb6a6bd1b,
+ 0x4b4c6068, 0xe015d4b9, 0x3eb80389, 0x95e1b758, 0x680b6a2b, 0xc352defa,
+ 0x3887641c, 0x93ded0cd, 0x6e340dbe, 0xc56db96f, 0x32c6cca3, 0x999f7872,
+ 0x6475a501, 0xcf2c11d0, 0x34f9ab36, 0x9fa01fe7, 0x624ac294, 0xc9137645,
+ 0x26459ddd, 0x8d1c290c, 0x70f6f47f, 0xdbaf40ae, 0x207afa48, 0x8b234e99,
+ 0x76c993ea, 0xdd90273b, 0x2a3b52f7, 0x8162e626, 0x7c883b55, 0xd7d18f84,
+ 0x2c043562, 0x875d81b3, 0x7ab75cc0, 0xd1eee811
+};
+
+static const unsigned int U[256] = {
+ 0x00000000, 0x7eb5200d, 0x5633f4cb, 0x2886d4c6, 0x073e5d47, 0x798b7d4a,
+ 0x510da98c, 0x2fb88981, 0x0e7cba8e, 0x70c99a83, 0x584f4e45, 0x26fa6e48,
+ 0x0942e7c9, 0x77f7c7c4, 0x5f711302, 0x21c4330f, 0x1cf9751c, 0x624c5511,
+ 0x4aca81d7, 0x347fa1da, 0x1bc7285b, 0x65720856, 0x4df4dc90, 0x3341fc9d,
+ 0x1285cf92, 0x6c30ef9f, 0x44b63b59, 0x3a031b54, 0x15bb92d5, 0x6b0eb2d8,
+ 0x4388661e, 0x3d3d4613, 0x39f2ea38, 0x4747ca35, 0x6fc11ef3, 0x11743efe,
+ 0x3eccb77f, 0x40799772, 0x68ff43b4, 0x164a63b9, 0x378e50b6, 0x493b70bb,
+ 0x61bda47d, 0x1f088470, 0x30b00df1, 0x4e052dfc, 0x6683f93a, 0x1836d937,
+ 0x250b9f24, 0x5bbebf29, 0x73386bef, 0x0d8d4be2, 0x2235c263, 0x5c80e26e,
+ 0x740636a8, 0x0ab316a5, 0x2b7725aa, 0x55c205a7, 0x7d44d161, 0x03f1f16c,
+ 0x2c4978ed, 0x52fc58e0, 0x7a7a8c26, 0x04cfac2b, 0x73e5d470, 0x0d50f47d,
+ 0x25d620bb, 0x5b6300b6, 0x74db8937, 0x0a6ea93a, 0x22e87dfc, 0x5c5d5df1,
+ 0x7d996efe, 0x032c4ef3, 0x2baa9a35, 0x551fba38, 0x7aa733b9, 0x041213b4,
+ 0x2c94c772, 0x5221e77f, 0x6f1ca16c, 0x11a98161, 0x392f55a7, 0x479a75aa,
+ 0x6822fc2b, 0x1697dc26, 0x3e1108e0, 0x40a428ed, 0x61601be2, 0x1fd53bef,
+ 0x3753ef29, 0x49e6cf24, 0x665e46a5, 0x18eb66a8, 0x306db26e, 0x4ed89263,
+ 0x4a173e48, 0x34a21e45, 0x1c24ca83, 0x6291ea8e, 0x4d29630f, 0x339c4302,
+ 0x1b1a97c4, 0x65afb7c9, 0x446b84c6, 0x3adea4cb, 0x1258700d, 0x6ced5000,
+ 0x4355d981, 0x3de0f98c, 0x15662d4a, 0x6bd30d47, 0x56ee4b54, 0x285b6b59,
+ 0x00ddbf9f, 0x7e689f92, 0x51d01613, 0x2f65361e, 0x07e3e2d8, 0x7956c2d5,
+ 0x5892f1da, 0x2627d1d7, 0x0ea10511, 0x7014251c, 0x5facac9d, 0x21198c90,
+ 0x099f5856, 0x772a785b, 0x4c921c31, 0x32273c3c, 0x1aa1e8fa, 0x6414c8f7,
+ 0x4bac4176, 0x3519617b, 0x1d9fb5bd, 0x632a95b0, 0x42eea6bf, 0x3c5b86b2,
+ 0x14dd5274, 0x6a687279, 0x45d0fbf8, 0x3b65dbf5, 0x13e30f33, 0x6d562f3e,
+ 0x506b692d, 0x2ede4920, 0x06589de6, 0x78edbdeb, 0x5755346a, 0x29e01467,
+ 0x0166c0a1, 0x7fd3e0ac, 0x5e17d3a3, 0x20a2f3ae, 0x08242768, 0x76910765,
+ 0x59298ee4, 0x279caee9, 0x0f1a7a2f, 0x71af5a22, 0x7560f609, 0x0bd5d604,
+ 0x235302c2, 0x5de622cf, 0x725eab4e, 0x0ceb8b43, 0x246d5f85, 0x5ad87f88,
+ 0x7b1c4c87, 0x05a96c8a, 0x2d2fb84c, 0x539a9841, 0x7c2211c0, 0x029731cd,
+ 0x2a11e50b, 0x54a4c506, 0x69998315, 0x172ca318, 0x3faa77de, 0x411f57d3,
+ 0x6ea7de52, 0x1012fe5f, 0x38942a99, 0x46210a94, 0x67e5399b, 0x19501996,
+ 0x31d6cd50, 0x4f63ed5d, 0x60db64dc, 0x1e6e44d1, 0x36e89017, 0x485db01a,
+ 0x3f77c841, 0x41c2e84c, 0x69443c8a, 0x17f11c87, 0x38499506, 0x46fcb50b,
+ 0x6e7a61cd, 0x10cf41c0, 0x310b72cf, 0x4fbe52c2, 0x67388604, 0x198da609,
+ 0x36352f88, 0x48800f85, 0x6006db43, 0x1eb3fb4e, 0x238ebd5d, 0x5d3b9d50,
+ 0x75bd4996, 0x0b08699b, 0x24b0e01a, 0x5a05c017, 0x728314d1, 0x0c3634dc,
+ 0x2df207d3, 0x534727de, 0x7bc1f318, 0x0574d315, 0x2acc5a94, 0x54797a99,
+ 0x7cffae5f, 0x024a8e52, 0x06852279, 0x78300274, 0x50b6d6b2, 0x2e03f6bf,
+ 0x01bb7f3e, 0x7f0e5f33, 0x57888bf5, 0x293dabf8, 0x08f998f7, 0x764cb8fa,
+ 0x5eca6c3c, 0x207f4c31, 0x0fc7c5b0, 0x7172e5bd, 0x59f4317b, 0x27411176,
+ 0x1a7c5765, 0x64c97768, 0x4c4fa3ae, 0x32fa83a3, 0x1d420a22, 0x63f72a2f,
+ 0x4b71fee9, 0x35c4dee4, 0x1400edeb, 0x6ab5cde6, 0x42331920, 0x3c86392d,
+ 0x133eb0ac, 0x6d8b90a1, 0x450d4467, 0x3bb8646a
+};
struct index_entry {
const unsigned char *ptr;
@@ -42,13 +130,13 @@ struct index_entry {
struct delta_index {
const void *src_buf;
unsigned long src_size;
- unsigned int hash_shift;
+ unsigned int hash_mask;
struct index_entry *hash[0];
};
struct delta_index * create_delta_index(const void *buf, unsigned long bufsize)
{
- unsigned int i, hsize, hshift, entries, *hash_count;
+ unsigned int i, hsize, hmask, entries, *hash_count;
const unsigned char *data, *buffer = buf;
struct delta_index *index;
struct index_entry *entry, **hash;
@@ -57,12 +145,14 @@ struct delta_index * create_delta_index(
if (!buf || !bufsize)
return NULL;
- /* determine index hash size */
- entries = bufsize / BLK_SIZE;
+ /* Determine index hash size. Note that indexing skips the
+ first byte to allow for optimizing the rabin polynomial
+ initialization in create_delta(). */
+ entries = (bufsize - 1) / RABIN_WINDOW;
hsize = entries / 4;
for (i = 4; (1 << i) < hsize && i < 31; i++);
hsize = 1 << i;
- hshift = 32 - i;
+ hmask = hsize - 1;
/* allocate lookup index */
mem = malloc(sizeof(*index) +
@@ -78,7 +168,7 @@ struct delta_index * create_delta_index(
index->src_buf = buf;
index->src_size = bufsize;
- index->hash_shift = hshift;
+ index->hash_mask = hmask;
memset(hash, 0, hsize * sizeof(*hash));
/* allocate an array to count hash entries */
@@ -89,17 +179,19 @@ struct delta_index * create_delta_index(
}
/* then populate the index */
- data = buffer + entries * BLK_SIZE - BLK_SIZE;
+ data = buffer + entries * RABIN_WINDOW - RABIN_WINDOW;
while (data >= buffer) {
- unsigned int val = adler32(0, data, BLK_SIZE);
- i = HASH(val, hshift);
- entry->ptr = data;
+ unsigned int val = 0;
+ for (i = 1; i <= RABIN_WINDOW; i++)
+ val = ((val << 8) | data[i]) ^ T[val >> RABIN_SHIFT];
+ i = val & hmask;
+ entry->ptr = data + RABIN_WINDOW;
entry->val = val;
entry->next = hash[i];
hash[i] = entry++;
hash_count[i]++;
- data -= BLK_SIZE;
- }
+ data -= RABIN_WINDOW;
+ }
/*
* Determine a limit on the number of entries in the same hash
@@ -136,20 +228,18 @@ void free_delta_index(struct delta_index
free(index);
}
-/* provide the size of the copy opcode given the block offset and size */
-#define COPYOP_SIZE(o, s) \
- (!!(o & 0xff) + !!(o & 0xff00) + !!(o & 0xff0000) + !!(o & 0xff000000) + \
- !!(s & 0xff) + !!(s & 0xff00) + 1)
-
-/* the maximum size for any opcode */
-#define MAX_OP_SIZE COPYOP_SIZE(0xffffffff, 0xffffffff)
+/*
+ * The maximum size for any opcode sequence, including the initial header
+ * plus rabin window plus biggest copy.
+ */
+#define MAX_OP_SIZE (5 + 5 + 1 + RABIN_WINDOW + 7)
void *
create_delta(const struct delta_index *index,
const void *trg_buf, unsigned long trg_size,
unsigned long *delta_size, unsigned long max_size)
{
- unsigned int i, outpos, outsize, hash_shift;
+ unsigned int i, outpos, outsize, hash_mask, val;
int inscnt;
const unsigned char *ref_data, *ref_top, *data, *top;
unsigned char *out;
@@ -185,14 +275,22 @@ create_delta(const struct delta_index *i
ref_top = ref_data + index->src_size;
data = trg_buf;
top = trg_buf + trg_size;
- hash_shift = index->hash_shift;
- inscnt = 0;
+ hash_mask = index->hash_mask;
+
+ outpos++;
+ val = 0;
+ for (i = 0; i < RABIN_WINDOW && data < top; i++, data++) {
+ out[outpos++] = *data;
+ val = ((val << 8) | *data) ^ T[val >> RABIN_SHIFT];
+ }
+ inscnt = i;
while (data < top) {
unsigned int moff = 0, msize = 0;
struct index_entry *entry;
- unsigned int val = adler32(0, data, BLK_SIZE);
- i = HASH(val, hash_shift);
+ val ^= U[data[-RABIN_WINDOW]];
+ val = ((val << 8) | *data) ^ T[val >> RABIN_SHIFT];
+ i = val & hash_mask;
for (entry = index->hash[i]; entry; entry = entry->next) {
const unsigned char *ref = entry->ptr;
const unsigned char *src = data;
@@ -214,7 +312,7 @@ create_delta(const struct delta_index *i
}
}
- if (!msize || msize < COPYOP_SIZE(moff, msize)) {
+ if (msize < 4) {
if (!inscnt)
outpos++;
out[outpos++] = *data++;
@@ -226,6 +324,20 @@ create_delta(const struct delta_index *i
} else {
unsigned char *op;
+ if (msize >= RABIN_WINDOW) {
+ const unsigned char *sk;
+ sk = data + msize - RABIN_WINDOW;
+ val = 0;
+ for (i = 0; i < RABIN_WINDOW; i++)
+ val = ((val << 8) | *sk++) ^ T[val >> RABIN_SHIFT];
+ } else {
+ const unsigned char *sk = data + 1;
+ for (i = 1; i < msize; i++) {
+ val ^= U[sk[-RABIN_WINDOW]];
+ val = ((val << 8) | *sk++) ^ T[val >> RABIN_SHIFT];
+ }
+ }
+
if (inscnt) {
while (moff && ref_data[moff-1] == data[-1]) {
if (msize == 0x10000)
@@ -270,9 +382,8 @@ create_delta(const struct delta_index *i
if (max_size && outsize >= max_size)
outsize = max_size + MAX_OP_SIZE + 1;
if (max_size && outpos > max_size)
- out = NULL;
- else
- out = realloc(out, outsize);
+ break;
+ out = realloc(out, outsize);
if (!out) {
free(tmp);
return NULL;
@@ -283,6 +394,11 @@ create_delta(const struct delta_index *i
if (inscnt)
out[outpos - inscnt - 1] = inscnt;
+ if (max_size && outpos > max_size) {
+ free(out);
+ return NULL;
+ }
+
*delta_size = outpos;
return out;
}
^ permalink raw reply related
* Re: Two gitweb feature requests
From: Jeff King @ 2006-04-29 5:02 UTC (permalink / raw)
To: git
In-Reply-To: <Pine.LNX.4.64.0604281116020.3701@g5.osdl.org>
On Fri, Apr 28, 2006 at 11:23:11AM -0700, Linus Torvalds wrote:
> The downside is that you'd have two different web-pages for the same tree
> depending on which commit it came from. Which is not a downside from a
> user perspective, but it's a downside from a caching/server perspective,
> since it means less reuse of pages (maybe gitweb already does that,
> though).
The gitweb request for a tree already contains not only the tree hash,
but also the commit hash and the filename path. It's possible (but more
expensive than typical tree requests) to find '..' by munging the path
and traversing the tree from the root.
-Peff
^ permalink raw reply
* Re: Do not use zlib 1.1.3 with git packs!
From: Junio C Hamano @ 2006-04-29 6:36 UTC (permalink / raw)
To: Nicolas Pitre; +Cc: git, Johannes Schindelin
In-Reply-To: <Pine.LNX.4.64.0604282316520.18816@localhost.localdomain>
Nicolas Pitre <nico@cam.org> writes:
> On Sat, 29 Apr 2006, Johannes Schindelin wrote:
>
>> I gather that close to the end, adler32() tries to read 15 bytes after the
>> end of the allocated target buffer.
>>
>> Am I wrong?
>
> You're not. My bad.
Thanks both, for catching this while still in "next".
^ permalink raw reply
* [PATCH] built-in diff.
From: Junio C Hamano @ 2006-04-29 7:19 UTC (permalink / raw)
To: git
This starts to replace the shell script version of "git diff".
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
* Should apply on top of "next" with trivial conflict fixups
(hint: "git am -3").
It is not fully compatible with the shell script version yet,
so it is called "git diffn" for now. It does not do the
fancy option defaulting, other than "git diffn --cached" to
mean "git diffn --cached HEAD", and I do not think I got the
defaulting to --cc right either. Also it does not default to
do -M either. If somebody cares deeply, patches are welcome.
When its option defaulting gets compatible with the shell
script version, or when its new default options becomes
accepted, we will rename it to "git diff" and merge it in.
To ask for the diff-raw output, you can give --raw option.
Makefile | 2
builtin-diff.c | 332 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
builtin.h | 1
git.c | 1
4 files changed, 335 insertions(+), 1 deletions(-)
diff --git a/Makefile b/Makefile
index 8ce27a6..277c1ac 100644
--- a/Makefile
+++ b/Makefile
@@ -214,7 +214,7 @@ LIB_OBJS = \
$(DIFF_OBJS)
BUILTIN_OBJS = \
- builtin-log.o builtin-help.o
+ builtin-log.o builtin-help.o builtin-diff.o
GITLIBS = $(LIB_FILE) $(XDIFF_LIB)
LIBS = $(GITLIBS) -lz
diff --git a/builtin-diff.c b/builtin-diff.c
new file mode 100644
index 0000000..1968212
--- /dev/null
+++ b/builtin-diff.c
@@ -0,0 +1,332 @@
+/*
+ * Builtin "git diff"
+ *
+ * Copyright (c) 2006 Junio C Hamano
+ */
+#include "cache.h"
+#include "commit.h"
+#include "blob.h"
+#include "tag.h"
+#include "diff.h"
+#include "diffcore.h"
+#include "revision.h"
+#include "log-tree.h"
+#include "builtin.h"
+
+/* NEEDSWORK: struct object has place for name but we _do_
+ * know mode when we extracted the blob out of a tree, which
+ * we currently lose.
+ */
+struct blobinfo {
+ unsigned char sha1[20];
+ const char *name;
+};
+
+static const char builtin_diff_usage[] =
+"diff <options> <rev>{0,2} -- <path>*";
+
+static int builtin_diff_files(struct rev_info *revs,
+ int argc, const char **argv)
+{
+ int silent = 0;
+ while (1 < argc) {
+ const char *arg = argv[1];
+ if (!strcmp(arg, "--base"))
+ revs->max_count = 1;
+ else if (!strcmp(arg, "--ours"))
+ revs->max_count = 2;
+ else if (!strcmp(arg, "--theirs"))
+ revs->max_count = 3;
+ else if (!strcmp(arg, "-q"))
+ silent = 1;
+ else if (!strcmp(arg, "--raw"))
+ revs->diffopt.output_format = DIFF_FORMAT_RAW;
+ else
+ usage(builtin_diff_usage);
+ argv++; argc--;
+ }
+ /*
+ * Make sure there are NO revision (i.e. pending object) parameter,
+ * rev.max_count is reasonable (0 <= n <= 3),
+ * there is no other revision filtering parameters.
+ */
+ if (revs->pending_objects ||
+ revs->min_age != -1 ||
+ revs->max_age != -1)
+ usage(builtin_diff_usage);
+ /*
+ * Backward compatibility wart - "diff-files -s" used to
+ * defeat the common diff option "-s" which asked for
+ * DIFF_FORMAT_NO_OUTPUT.
+ */
+ if (revs->diffopt.output_format == DIFF_FORMAT_NO_OUTPUT)
+ revs->diffopt.output_format = DIFF_FORMAT_RAW;
+ return run_diff_files(revs, silent);
+}
+
+static void stuff_change(struct diff_options *opt,
+ unsigned old_mode, unsigned new_mode,
+ const unsigned char *old_sha1,
+ const unsigned char *new_sha1,
+ const char *old_name,
+ const char *new_name)
+{
+ struct diff_filespec *one, *two;
+
+ if (memcmp(null_sha1, old_sha1, 20) &&
+ memcmp(null_sha1, new_sha1, 20) &&
+ !memcmp(old_sha1, new_sha1, 20))
+ return;
+
+ if (opt->reverse_diff) {
+ unsigned tmp;
+ const
+ const unsigned char *tmp_u;
+ const char *tmp_c;
+ tmp = old_mode; old_mode = new_mode; new_mode = tmp;
+ tmp_u = old_sha1; old_sha1 = new_sha1; new_sha1 = tmp_u;
+ tmp_c = old_name; old_name = new_name; new_name = tmp_c;
+ }
+ one = alloc_filespec(old_name);
+ two = alloc_filespec(new_name);
+ fill_filespec(one, old_sha1, old_mode);
+ fill_filespec(two, new_sha1, new_mode);
+
+ /* NEEDSWORK: shouldn't this part of diffopt??? */
+ diff_queue(&diff_queued_diff, one, two);
+}
+
+static int builtin_diff_b_f(struct rev_info *revs,
+ int argc, const char **argv,
+ struct blobinfo *blob,
+ const char *path)
+{
+ /* Blob vs file in the working tree*/
+ struct stat st;
+
+ while (1 < argc) {
+ const char *arg = argv[1];
+ if (!strcmp(arg, "--raw"))
+ revs->diffopt.output_format = DIFF_FORMAT_RAW;
+ else
+ usage(builtin_diff_usage);
+ argv++; argc--;
+ }
+ if (lstat(path, &st))
+ die("'%s': %s", path, strerror(errno));
+ if (!(S_ISREG(st.st_mode) || S_ISLNK(st.st_mode)))
+ die("'%s': not a regular file or symlink", path);
+ stuff_change(&revs->diffopt,
+ canon_mode(st.st_mode), canon_mode(st.st_mode),
+ blob[0].sha1, null_sha1,
+ blob[0].name, path);
+ diffcore_std(&revs->diffopt);
+ diff_flush(&revs->diffopt);
+ return 0;
+}
+
+static int builtin_diff_blobs(struct rev_info *revs,
+ int argc, const char **argv,
+ struct blobinfo *blob)
+{
+ /* Blobs */
+ unsigned mode = canon_mode(S_IFREG | 0644);
+
+ while (1 < argc) {
+ const char *arg = argv[1];
+ if (!strcmp(arg, "--raw"))
+ revs->diffopt.output_format = DIFF_FORMAT_RAW;
+ else
+ usage(builtin_diff_usage);
+ argv++; argc--;
+ }
+ stuff_change(&revs->diffopt,
+ mode, mode,
+ blob[0].sha1, blob[1].sha1,
+ blob[1].name, blob[1].name);
+ diffcore_std(&revs->diffopt);
+ diff_flush(&revs->diffopt);
+ return 0;
+}
+
+static int builtin_diff_index(struct rev_info *revs,
+ int argc, const char **argv)
+{
+ int cached = 0;
+ while (1 < argc) {
+ const char *arg = argv[1];
+ if (!strcmp(arg, "--cached"))
+ cached = 1;
+ else if (!strcmp(arg, "--raw"))
+ revs->diffopt.output_format = DIFF_FORMAT_RAW;
+ else
+ usage(builtin_diff_usage);
+ argv++; argc--;
+ }
+ /*
+ * Make sure there is one revision (i.e. pending object),
+ * and there is no revision filtering parameters.
+ */
+ if (!revs->pending_objects || revs->pending_objects->next ||
+ revs->max_count != -1 || revs->min_age != -1 ||
+ revs->max_age != -1)
+ usage(builtin_diff_usage);
+ return run_diff_index(revs, cached);
+}
+
+static int builtin_diff_tree(struct rev_info *revs,
+ int argc, const char **argv,
+ struct object_list *ent)
+{
+ /* We saw two trees, ent[0] and ent[1].
+ * unless ent[0] is unintesting, they are swapped
+ */
+ const unsigned char *(sha1[2]);
+ int swap = 1;
+ while (1 < argc) {
+ const char *arg = argv[1];
+ if (!strcmp(arg, "--raw"))
+ revs->diffopt.output_format = DIFF_FORMAT_RAW;
+ else
+ usage(builtin_diff_usage);
+ argv++; argc--;
+ }
+ if (ent[0].item->flags & UNINTERESTING)
+ swap = 0;
+ sha1[swap] = ent[0].item->sha1;
+ sha1[1-swap] = ent[1].item->sha1;
+ diff_tree_sha1(sha1[0], sha1[1], "", &revs->diffopt);
+ log_tree_diff_flush(revs);
+ return 0;
+}
+
+static void add_head(struct rev_info *revs)
+{
+ unsigned char sha1[20];
+ struct object *obj;
+ if (get_sha1("HEAD", sha1))
+ return;
+ obj = parse_object(sha1);
+ if (!obj)
+ return;
+ add_object(obj, &revs->pending_objects, NULL, "HEAD");
+}
+
+int cmd_diff(int argc, const char **argv, char **envp)
+{
+ struct rev_info rev;
+ struct object_list *list, ent[2];
+ int ents = 0, blobs = 0, paths = 0;
+ const char *path = NULL;
+ struct blobinfo blob[2];
+
+ /*
+ * We could get N tree-ish in the rev.pending_objects list.
+ * Also there could be M blobs there, and P pathspecs.
+ *
+ * N=0, M=0:
+ * cache vs files (diff-files)
+ * N=0, M=2:
+ * compare two random blobs. P must be zero.
+ * N=0, M=1, P=1:
+ * compare a blob with a working tree file.
+ *
+ * N=1, M=0:
+ * tree vs cache (diff-index --cached)
+ *
+ * N=2, M=0:
+ * tree vs tree (diff-tree)
+ *
+ * Other cases are errors.
+ */
+
+ git_config(git_diff_config);
+ init_revisions(&rev);
+ rev.diffopt.output_format = DIFF_FORMAT_PATCH;
+
+ argc = setup_revisions(argc, argv, &rev, NULL);
+ /* Do we have --cached and not have a pending object, then
+ * default to HEAD by hand. Eek.
+ */
+ if (!rev.pending_objects) {
+ int i;
+ for (i = 1; i < argc; i++) {
+ const char *arg = argv[i];
+ if (!strcmp(arg, "--"))
+ break;
+ else if (!strcmp(arg, "--cached")) {
+ add_head(&rev);
+ break;
+ }
+ }
+ }
+
+ for (list = rev.pending_objects; list; list = list->next) {
+ struct object *obj = list->item;
+ const char *name = list->name;
+ int flags = (obj->flags & UNINTERESTING);
+ if (!obj->parsed)
+ obj = parse_object(obj->sha1);
+ obj = deref_tag(obj, NULL, 0);
+ if (!obj)
+ die("invalid object '%s' given.", name);
+ if (!strcmp(obj->type, commit_type))
+ obj = &((struct commit *)obj)->tree->object;
+ if (!strcmp(obj->type, tree_type)) {
+ if (2 <= ents)
+ die("more than two trees given: '%s'", name);
+ obj->flags |= flags;
+ ent[ents].item = obj;
+ ent[ents].name = name;
+ ents++;
+ continue;
+ }
+ if (!strcmp(obj->type, blob_type)) {
+ if (2 <= blobs)
+ die("more than two blobs given: '%s'", name);
+ memcpy(blob[blobs].sha1, obj->sha1, 20);
+ blob[blobs].name = name;
+ blobs++;
+ continue;
+
+ }
+ die("unhandled object '%s' given.", name);
+ }
+ if (rev.prune_data) {
+ const char **pathspec = rev.prune_data;
+ while (*pathspec) {
+ if (!path)
+ path = *pathspec;
+ paths++;
+ pathspec++;
+ }
+ }
+
+ /*
+ * Now, do the arguments look reasonable?
+ */
+ if (!ents) {
+ switch (blobs) {
+ case 0:
+ return builtin_diff_files(&rev, argc, argv);
+ break;
+ case 1:
+ if (paths != 1)
+ usage(builtin_diff_usage);
+ return builtin_diff_b_f(&rev, argc, argv, blob, path);
+ break;
+ case 2:
+ return builtin_diff_blobs(&rev, argc, argv, blob);
+ break;
+ default:
+ usage(builtin_diff_usage);
+ }
+ }
+ else if (blobs)
+ usage(builtin_diff_usage);
+ else if (ents == 1)
+ return builtin_diff_index(&rev, argc, argv);
+ else if (ents == 2)
+ return builtin_diff_tree(&rev, argc, argv, ent);
+ usage(builtin_diff_usage);
+}
diff --git a/builtin.h b/builtin.h
index 47408a0..52ffa52 100644
--- a/builtin.h
+++ b/builtin.h
@@ -19,5 +19,6 @@ extern int cmd_version(int argc, const c
extern int cmd_whatchanged(int argc, const char **argv, char **envp);
extern int cmd_show(int argc, const char **argv, char **envp);
extern int cmd_log(int argc, const char **argv, char **envp);
+extern int cmd_diff(int argc, const char **argv, char **envp);
#endif
diff --git a/git.c b/git.c
index 01b7e28..ff9b87a 100644
--- a/git.c
+++ b/git.c
@@ -46,6 +46,7 @@ static void handle_internal_command(int
{ "log", cmd_log },
{ "whatchanged", cmd_whatchanged },
{ "show", cmd_show },
+ { "diffn", cmd_diff },
};
int i;
--
1.3.1.g1d19
^ permalink raw reply related
* Re: Two gitweb feature requests
From: Jakub Narebski @ 2006-04-29 7:27 UTC (permalink / raw)
To: git
It would be nice if gitweb provided for the GIT repository description
which doesn't fit the "Description" column and is shortened, and any
other text which doesn't fit it's own column, full text of said field
as the "title" attribute for the cell 'td' element, or encompasing
'span' element. It would result in having full, not shortened text of
said field (e.g. repository description) in the pop-up on mouse hover
over said field. To simplify things it could be provided
unconditionally, regardless whether the field needs shortening or not.
By the way, would it be possible for the repository without provided
description to stand out more, perhaps by changing formatting of
default description:
"Unnamed repository; edit this file to name it for gitweb."
to use ALL CAPS for attention, like that:
"UNNAMED REPOSITORY; edit this file to name it for gitweb."
or perhaps if possible use HTML formatting [additionally] for that.
--
Jakub Narebski
Poland
^ permalink raw reply
* [ANNOUNCE] qgit-1.2
From: Marco Costalba @ 2006-04-29 7:54 UTC (permalink / raw)
To: git, linux-kernel
This is qgit-1.2
With qgit you will be able to browse revisions history, view patch content
and changed files, graphically following different development branches.
FEATURES
- View revisions, diffs, files history, files annotation, archive tree.
- Commit changes visually cherry picking modified files.
- Apply or format patch series from selected commits, drag and
drop commits between two instances of qgit.
- qgit implements a GUI for the most common StGIT commands like push/pop
and apply/format patches. You can also create new patches or refresh
current top one using the same semantics of git commit, i.e. cherry
picking single modified files.
NEW IN THIS RELEASE
A lot of work has been done from 1.1
Main new features:
*Add support for code range filtering*
To filter a mouse selected code text across all revisions file history,
this is very useful to quick search for revisions that modified a given
chunk of code.
*Much improved graph for partial repos views*
Thanks to new --boundary git-rev-list option graphs for partial repo
views are now much more clear and easy to follow.
*Support for launching an external diff viewer*
Useful, as example, to view the diffs in a 'tiled pane' mode. Default
is kompare, but it is easily user settable.
*Show stat info in patch viewer*
Use new --patch-with-stat git-diff-tree option to prepend stat info in
patch viewer.
*Adjustable font size in revision list view*
To squeeze revision graph without compromise patch and file content views.
*Key bindings for scrolling patch and revision logs*
Same keyboard navigation map of gitk. See help (F1) for details.
*Support for 'working dir' pseudo-tree in tree view*
To browse working dir changes and files in a tree like view. This is useful
for people coming from others SCM systems.
*Loading speed improvements*
Heavy optimization work to speed-up start up times, about 20%-30% from
qgit 1.1.1
NOTE: interface change.
Browsing file history revisions in annotate window does not update main view
anymore. Double click is now required to update main view. This makes qgit
less 'jumpy' and let browse file history without loosing main view selection.
Please note that you will need git 1.3.0 or newer.
DOWNLOAD
Tarball is at
http://prdownloads.sourceforge.net/qgit/qgit-1.2.tar.bz2?download
Git archive is at
http://digilander.libero.it/mcostalba/scm/qgit.git
See http://digilander.libero.it/mcostalba/ for detailed download information.
INSTALLATION
git 1.3.0 is required.
To install from tarball:
./configure
make
make install-strip
To install from git archive:
autoreconf -i
./configure
make
make install-strip
Or check the shipped README for detailed information.
CHANGELOG from 1.2rc2
- do not update main view when browsing file history: double click is
now required
- show "working dir" pseudo rev also when there is no change
- add support for 'working dir' pseudo-tree in tree view
- add key bindings for scrolling patch and revision logs views
- add support for adjustable font size in revision list view
- add "revision diff" entry in context menu
- support lane mouse selection also for not free lanes
- help view should not be a top level window
- restore selection when removing code filtering
- fix a bad crash in diff viewer window
- fix a inconsistency in spinbox in annotation view
- fix an off by one bug that creates invalid pixmaps
- fix highlighting of selected revision if a reference name is used
- small GUI tweaks
For a complete changelog see shipped ChangeLog file or git repository
revision's history
Marco
^ permalink raw reply
* [PATCH] built-in diff: assorted updates.
From: Junio C Hamano @ 2006-04-29 9:29 UTC (permalink / raw)
To: git
In-Reply-To: <7virosalxb.fsf@assigned-by-dhcp.cox.net>
"git diff(n)" without --base, --ours, etc. defaults to --cc,
which usually is the same as -p unless you are in the middle of
a conflicted merge, just like the shell script version.
"git diff(n) blobA blobB path" complains and dies.
"git diff(n) tree0 tree1 tree2...treeN" does combined diff that
shows a merge of tree1..treeN to result in tree0.
Giving "-c" option to any command that defaults to "--cc" turns
off dense-combined flag.
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
* Comes on top of the previous "built-in diff" patch.
Now I think this is more or less what Linus envisioned when
he started converting the rev related option parsing to use
setup_revisions(), including the exotic combinations the
shell script "git diff" does not support:
git diff(n) HEAD~10:Makefile Makefile ; blob vs any file
git diff(n) HEAD~10:Makefile HEAD~20:Makefile ; two blobs
git diff(n) v1.0.0 v1.0.0^1 v1.0.0^2 ; combine 'em
The normal ones are also supported:
git diff(n) -- Documentation ; index vs working
git diff(n) --cached ; tree vs index
git diff(n) HEAD ; tree vs working
git diff(n) HEAD~10 HEAD~8 ; two trees
git diff(n) HEAD:arch/i386 HEAD:arch/x86_64 ; two trees
builtin-diff.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++---------
combine-diff.c | 47 ++++++++++++++++++++++++++++++-----------------
diff.h | 2 ++
revision.c | 1 +
4 files changed, 79 insertions(+), 26 deletions(-)
diff --git a/builtin-diff.c b/builtin-diff.c
index 1968212..c543105 100644
--- a/builtin-diff.c
+++ b/builtin-diff.c
@@ -47,13 +47,17 @@ static int builtin_diff_files(struct rev
}
/*
* Make sure there are NO revision (i.e. pending object) parameter,
- * rev.max_count is reasonable (0 <= n <= 3),
- * there is no other revision filtering parameters.
+ * specified rev.max_count is reasonable (0 <= n <= 3), and
+ * there is no other revision filtering parameter.
*/
if (revs->pending_objects ||
revs->min_age != -1 ||
- revs->max_age != -1)
+ revs->max_age != -1 ||
+ 3 < revs->max_count)
usage(builtin_diff_usage);
+ if (revs->max_count < 0 &&
+ (revs->diffopt.output_format == DIFF_FORMAT_PATCH))
+ revs->combine_merges = revs->dense_combined_merges = 1;
/*
* Backward compatibility wart - "diff-files -s" used to
* defeat the common diff option "-s" which asked for
@@ -178,9 +182,6 @@ static int builtin_diff_tree(struct rev_
int argc, const char **argv,
struct object_list *ent)
{
- /* We saw two trees, ent[0] and ent[1].
- * unless ent[0] is unintesting, they are swapped
- */
const unsigned char *(sha1[2]);
int swap = 1;
while (1 < argc) {
@@ -191,6 +192,10 @@ static int builtin_diff_tree(struct rev_
usage(builtin_diff_usage);
argv++; argc--;
}
+
+ /* We saw two trees, ent[0] and ent[1].
+ * unless ent[0] is unintesting, they are swapped
+ */
if (ent[0].item->flags & UNINTERESTING)
swap = 0;
sha1[swap] = ent[0].item->sha1;
@@ -200,6 +205,33 @@ static int builtin_diff_tree(struct rev_
return 0;
}
+static int builtin_diff_combined(struct rev_info *revs,
+ int argc, const char **argv,
+ struct object_list *ent,
+ int ents)
+{
+ const unsigned char (*parent)[20];
+ int i;
+
+ while (1 < argc) {
+ const char *arg = argv[1];
+ if (!strcmp(arg, "--raw"))
+ revs->diffopt.output_format = DIFF_FORMAT_RAW;
+ else
+ usage(builtin_diff_usage);
+ argv++; argc--;
+ }
+ if (!revs->dense_combined_merges && !revs->combine_merges)
+ revs->dense_combined_merges = revs->combine_merges = 1;
+ parent = xmalloc(ents * sizeof(*parent));
+ /* Again, the revs are all reverse */
+ for (i = 0; i < ents; i++)
+ memcpy(parent + i, ent[ents - 1 - i].item->sha1, 20);
+ diff_tree_combined(parent[0], parent + 1, ents - 1,
+ revs->dense_combined_merges, revs);
+ return 0;
+}
+
static void add_head(struct rev_info *revs)
{
unsigned char sha1[20];
@@ -215,7 +247,7 @@ static void add_head(struct rev_info *re
int cmd_diff(int argc, const char **argv, char **envp)
{
struct rev_info rev;
- struct object_list *list, ent[2];
+ struct object_list *list, ent[100];
int ents = 0, blobs = 0, paths = 0;
const char *path = NULL;
struct blobinfo blob[2];
@@ -273,8 +305,9 @@ int cmd_diff(int argc, const char **argv
if (!strcmp(obj->type, commit_type))
obj = &((struct commit *)obj)->tree->object;
if (!strcmp(obj->type, tree_type)) {
- if (2 <= ents)
- die("more than two trees given: '%s'", name);
+ if (ARRAY_SIZE(ent) <= ents)
+ die("more than %d trees given: '%s'",
+ ARRAY_SIZE(ent), name);
obj->flags |= flags;
ent[ents].item = obj;
ent[ents].name = name;
@@ -316,6 +349,8 @@ int cmd_diff(int argc, const char **argv
return builtin_diff_b_f(&rev, argc, argv, blob, path);
break;
case 2:
+ if (paths)
+ usage(builtin_diff_usage);
return builtin_diff_blobs(&rev, argc, argv, blob);
break;
default:
@@ -328,5 +363,7 @@ int cmd_diff(int argc, const char **argv
return builtin_diff_index(&rev, argc, argv);
else if (ents == 2)
return builtin_diff_tree(&rev, argc, argv, ent);
+ else
+ return builtin_diff_combined(&rev, argc, argv, ent, ents);
usage(builtin_diff_usage);
}
diff --git a/combine-diff.c b/combine-diff.c
index ca36f5d..8a8fe38 100644
--- a/combine-diff.c
+++ b/combine-diff.c
@@ -831,15 +831,16 @@ void show_combined_diff(struct combine_d
}
}
-void diff_tree_combined_merge(const unsigned char *sha1,
- int dense, struct rev_info *rev)
+void diff_tree_combined(const unsigned char *sha1,
+ const unsigned char parent[][20],
+ int num_parent,
+ int dense,
+ struct rev_info *rev)
{
struct diff_options *opt = &rev->diffopt;
- struct commit *commit = lookup_commit(sha1);
struct diff_options diffopts;
- struct commit_list *parents;
struct combine_diff_path *p, *paths = NULL;
- int num_parent, i, num_paths;
+ int i, num_paths;
int do_diffstat;
do_diffstat = (opt->output_format == DIFF_FORMAT_DIFFSTAT ||
@@ -849,17 +850,8 @@ void diff_tree_combined_merge(const unsi
diffopts.with_stat = 0;
diffopts.recursive = 1;
- /* count parents */
- for (parents = commit->parents, num_parent = 0;
- parents;
- parents = parents->next, num_parent++)
- ; /* nothing */
-
/* find set of paths that everybody touches */
- for (parents = commit->parents, i = 0;
- parents;
- parents = parents->next, i++) {
- struct commit *parent = parents->item;
+ for (i = 0; i < num_parent; i++) {
/* show stat against the first parent even
* when doing combined diff.
*/
@@ -867,8 +859,7 @@ void diff_tree_combined_merge(const unsi
diffopts.output_format = DIFF_FORMAT_DIFFSTAT;
else
diffopts.output_format = DIFF_FORMAT_NO_OUTPUT;
- diff_tree_sha1(parent->object.sha1, commit->object.sha1, "",
- &diffopts);
+ diff_tree_sha1(parent[i], sha1, "", &diffopts);
diffcore_std(&diffopts);
paths = intersect_paths(paths, i, num_parent);
@@ -907,3 +898,25 @@ void diff_tree_combined_merge(const unsi
free(tmp);
}
}
+
+void diff_tree_combined_merge(const unsigned char *sha1,
+ int dense, struct rev_info *rev)
+{
+ int num_parent;
+ const unsigned char (*parent)[20];
+ struct commit *commit = lookup_commit(sha1);
+ struct commit_list *parents;
+
+ /* count parents */
+ for (parents = commit->parents, num_parent = 0;
+ parents;
+ parents = parents->next, num_parent++)
+ ; /* nothing */
+
+ parent = xmalloc(num_parent * sizeof(*parent));
+ for (parents = commit->parents, num_parent = 0;
+ parents;
+ parents = parents->next, num_parent++)
+ memcpy(parent + num_parent, parents->item->object.sha1, 20);
+ diff_tree_combined(sha1, parent, num_parent, dense, rev);
+}
diff --git a/diff.h b/diff.h
index 7150b90..b3b2c4d 100644
--- a/diff.h
+++ b/diff.h
@@ -75,6 +75,8 @@ #define combine_diff_path_size(n, l) \
extern void show_combined_diff(struct combine_diff_path *elem, int num_parent,
int dense, struct rev_info *);
+extern void diff_tree_combined(const unsigned char *sha1, const unsigned char parent[][20], int num_parent, int dense, struct rev_info *rev);
+
extern void diff_tree_combined_merge(const unsigned char *sha1, int, struct rev_info *);
extern void diff_addremove(struct diff_options *,
diff --git a/revision.c b/revision.c
index f2a9f25..4381d45 100644
--- a/revision.c
+++ b/revision.c
@@ -664,6 +664,7 @@ int setup_revisions(int argc, const char
}
if (!strcmp(arg, "-c")) {
revs->diff = 1;
+ revs->dense_combined_merges = 0;
revs->combine_merges = 1;
continue;
}
--
1.3.1.ga0c5
^ permalink raw reply related
* [PATCH/RFC] Extended SHA1 -- "rev^#" syntax to mean "all parents"
From: Junio C Hamano @ 2006-04-29 9:45 UTC (permalink / raw)
To: git
In-Reply-To: <7virosalxb.fsf@assigned-by-dhcp.cox.net>
A short-hand "rev^#" is understood to be "all parents of the
named commit" with this patch. So you can do
git show v1.0.0^#
to view the parents of a merge commit,
gitk ^v1.0.0^# v1.0.4
to view the log between two revs (including the bottom one), and
git diff --cc v1.1.0 v1.0.0^#
to inspect what got changed from the merge parents of v1.0.0 to v1.1.0.
This might be just my shiny new toy that is not very useful in
practice. I needed it to do the multi-tree diff on Len's
infamous 12-way Octopus; typing "diff --cc funmerge funmerge^1
funmerge^2 funmerge^3 ..." was too painful.
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
revision.c | 37 +++++++++++++++++++++++++++++++++++++
1 files changed, 37 insertions(+), 0 deletions(-)
diff --git a/revision.c b/revision.c
index f2a9f25..194f35b 100644
--- a/revision.c
+++ b/revision.c
@@ -477,6 +477,36 @@ static void handle_all(struct rev_info *
for_each_ref(handle_one_ref);
}
+static int add_parents_only(struct rev_info *revs, const char *arg, int flags)
+{
+ unsigned char sha1[20];
+ struct object *it;
+ struct commit *commit;
+ struct commit_list *parents;
+
+ if (*arg == '^') {
+ flags ^= UNINTERESTING;
+ arg++;
+ }
+ if (get_sha1(arg, sha1))
+ return 0;
+ while (1) {
+ it = get_reference(revs, arg, sha1, 0);
+ if (strcmp(it->type, tag_type))
+ break;
+ memcpy(sha1, ((struct tag*)it)->tagged->sha1, 20);
+ }
+ if (strcmp(it->type, commit_type))
+ return 0;
+ commit = (struct commit *)it;
+ for (parents = commit->parents; parents; parents = parents->next) {
+ it = &parents->item->object;
+ it->flags |= flags;
+ add_pending_object(revs, it, arg);
+ }
+ return 1;
+}
+
void init_revisions(struct rev_info *revs)
{
memset(revs, 0, sizeof(*revs));
@@ -746,6 +776,13 @@ int setup_revisions(int argc, const char
}
*dotdot = '.';
}
+ dotdot = strstr(arg, "^#");
+ if (dotdot && !dotdot[2]) {
+ *dotdot = 0;
+ if (add_parents_only(revs, arg, flags))
+ continue;
+ *dotdot = '^';
+ }
local_flags = 0;
if (*arg == '^') {
local_flags = UNINTERESTING;
--
1.3.1.ga0c5
^ permalink raw reply related
* Re: Two gitweb feature requests
From: Jakub Narebski @ 2006-04-29 11:16 UTC (permalink / raw)
To: git
In-Reply-To: <1146144425.11909.450.camel@pmac.infradead.org>
It would be nice if gitweb provided for the GIT repository description which
doesn't fit the "Description" column and is shortened, and any other text
which doesn't fit it's own column, full text of said field as the "title"
attribute for the cell 'td' element, or encompasing 'span' element. It
would result in having full, not shortened text of said field (e.g.
repository description) in the pop-up on mouse hover over said field. To
simplify things it could be provided unconditionally, regardless whether
the field needs shortening or not.
By the way, would it be possible for the repository without provided
description to stand out more, perhaps by changing formatting of default
description:
"Unnamed repository; edit this file to name it for gitweb."
to use ALL CAPS for attention, like that:
"UNNAMED REPOSITORY; edit this file to name it for gitweb."
or perhaps if possible use HTML formatting [additionally] for that.
--
Jakub Narebski
Warsaw, Poland
^ permalink raw reply
* Re: fatal: git-write-tree: not able to write tree
From: colin @ 2006-04-29 13:23 UTC (permalink / raw)
To: junkio; +Cc: git
diff --git a/git-am.sh b/git-am.sh
index eab4aa8..872145b 100755
--- a/git-am.sh
+++ b/git-am.sh
@@ -376,6 +376,13 @@ do
echo "No changes - did you forget update-index?"
stop_here $this
fi
+ unmerged=$(git-ls-files -u)
+ if test -n "$unmerged"
+ then
+ echo "You still have unmerged paths in your index"
+ echo "did you forget update-index?"
+ stop_here $this
+ fi
apply_status=0
;;
esac
Er... it's very non-obvious to me why you'd want to stick a workaround
here when you could instead fix git-write-tree to do it. That seems
like The Right Thing.
(It would also be helpful to mention at least one unmerged file by name.)
^ permalink raw reply related
* Features ask for git-send-email
From: Bertrand Jacquin @ 2006-04-29 13:30 UTC (permalink / raw)
To: Git Mailing List
Hi,
Could it be possible to add a features in git-send-email.perl to
accept a differrent charset as iso-8859-1 ? I would like to send
fr_FR.utf8 mail as I use git to manager a latex files tree which are
written in utf8.
Any objection ?
--
Beber
#e.fr@freenode
^ permalink raw reply
* Re: cg-clone not fetching all tags?
From: Wolfgang Denk @ 2006-04-29 14:00 UTC (permalink / raw)
To: Git Mailing List
In-Reply-To: <20060427105251.AA4B2353DAC@atlas.denx.de>
[Repost because there was zero response, not even somebody telling me
to RTFM or so.]
Hi,
it seems that "cg-clone" does not fetch all tags any more - only the
most recent ones (modiufied in the last N days?) seem to be fetched?
[Eventually the "N days" might correspond to "changing tools to
version X", but I have no way to find out.]
This happens only when using HTTP; using ssh or rsync works fine.
Also, if we follow the "cg-clone" by a "git-fetch -t" command, this
will load the missing tags.
Is this intentional, or am I doing anything wrong?
[For testing, try "cg-clone http://www.denx.de/git/u-boot.git"]
Best regards,
Wolfgang Denk
--
Software Engineering: Embedded and Realtime Systems, Embedded Linux
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd@denx.de
In theory, there is no difference between theory and practice. In
practice, however, there is.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox