* Re: [PATCH v2] parse-opt: migrate builtin-ls-files.
From: Pierre Habouzit @ 2009-01-07 14:46 UTC (permalink / raw)
To: Miklos Vajna; +Cc: Junio C Hamano, git
In-Reply-To: <1231297894-31809-1-git-send-email-vmiklos@frugalware.org>
[-- Attachment #1: Type: text/plain, Size: 746 bytes --]
On Wed, Jan 07, 2009 at 03:11:34AM +0000, Miklos Vajna wrote:
> +static int option_parse_ignored(const struct option *opt,
> + const char *arg, int unset)
> +{
> + struct dir_struct *dir = opt->value;
> +
> + if (unset)
> + dir->show_ignored = 0;
> + else
> + dir->show_ignored = 1;
dir->show_ignored = !unset ?
> +static int option_parse_directory(const struct option *opt,
> + const char *arg, int unset)
> +{
ditto
> +static int option_parse_empty(const struct option *opt,
> + const char *arg, int unset)
> +{
ditto
--
·O· Pierre Habouzit
··O madcoder@debian.org
OOO http://www.madism.org
[-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --]
^ permalink raw reply
* git rebase orthodontics
From: jidanni @ 2009-01-07 14:47 UTC (permalink / raw)
To: git
In today's adventure we follow junior user me as he sets off in his
first bumper car ride on the wrong side of git-rebase, wherein he
discovers there are no guard rails. git version 1.6.0.6.
$ git branch
* jidanni
master
$ git commit -m bla --allow-empty
$ git rebase --interactive master
(In the editor I change the single pick offered into a squash)
grep: ....git/rebase-merge/done: No such file or directory
Cannot 'squash' without a previous commit
(OK, but the grep error being shown to the user is a bug.)
$ git show --abbrev-commit --pretty=raw jidanni master
commit 07aef4a...
tree 28f9caca33a8294d36b3d42f21ff472c6126da16
parent 3ad166e006afc3ce57a35b6ac650569e557b024a...
commit 3ad166e...
tree 28f9caca33a8294d36b3d42f21ff472c6126da16
parent 726f8d08e2f7642d56a568eb82a685de0da0baf7
$ EDITOR=cat git rebase --interactive master
pick 07aef4a This is a commit with No files, wow. bla.
# Rebase 3ad166e..07aef4a onto 3ad166e ...
Successfully rebased and updated refs/heads/jidanni.
(But it didn't. git show shows no change. ls -l shows
refs/heads/jidanni was not touched.
OK, it seems like all I am doing is changing
A jidanni
/
D---E---F---G master
into the same thing, a noop. But shouldn't it warn and quit, instead
of rewarding me with the success message? Let's try it the other way
around:
$ git checkout master
$ git rebase --interactive jidanni #Wherein one sees:
noop
# Rebase 07aef4a..3ad166e onto 07aef4a
Successfully rebased and updated refs/heads/master.
OK, now I have achieved
D---E---F---G---A master, jidanni
Observations:
When I tried a noop, it didn't say noop in the editor.
When I tried a yesop, it did say noop in the editor.
In both cases it gave the same success message.
^ permalink raw reply
* Re: Problems getting rid of large files using git-filter-branch
From: Nicolas Pitre @ 2009-01-07 15:02 UTC (permalink / raw)
To: Øyvind Harboe; +Cc: git
In-Reply-To: <c09652430901070026m6ca0ec98ndc7483aac8dfde89@mail.gmail.com>
[-- Attachment #1: Type: TEXT/PLAIN, Size: 2045 bytes --]
On Wed, 7 Jan 2009, Øyvind Harboe wrote:
> Here is a summary of the solution I used. I'm a beginner in git
> and just summarizing what others told me and what I did. Use at
> your own risk!
>
> 1. Remove anything you know should be removed, e.g.:
>
> git filter-branch --tree-filter 'find . -regex ".*toolchain\..*" -exec
> rm -f {} \;' HEAD
>
> 2. Expire the log:
>
> git reflog expire --all
>
> 3. Delete stuff from .git that should be manually "verified" to be
> correct. I don't actually
> know how to "verify" that at this point... Use backups Luke!
>
> rm -rf .git/refs/original
> # delete lines w/"refs/original" from .git/packed-refs
> vi .git/packed-refs
> # for good measure...
> git reflog expire --all
> git gc
>
> 4. Your repository is still huge. By creating a new repository and pulling from
> this one, the garbage will stay in the old one...
>
> mkdir newrep
> cd newrep
> git init
> git pull file:///oldrep
I'd suggest you skip 2 and 3, and do 4 only. Using 4 makes 2
unnecessary, and is far safer than 3. Manually deleting stuff in .git
is fine only if you really know what you're doing and have some
acquaintance with the git internals.
> 5. Check size of .git. If it is still too big, try figuring out which
> files that are big by looking at the packs(.git/objects/pack/xxx):
>
> $ git verify-pack -v $PACK | grep -v "^chain " | sort -n -k 4
>
> and then for the last few lines do a
>
> $ git rev-list --all --objects | grep $SHA1
>
> 6. Go back to #1 until done.
>
> Your repository should now be of reasonable size...
>
> I've found some great scripts for converting from svn/cvs, but really
> the above procedure
> is necessary to run when converting nasty old repositories...
>
> --
> Øyvind Harboe
> http://www.zylin.com/zy1000.html
> ARM7 ARM9 XScale Cortex
> JTAG debugger and flash programmer
> --
> To unsubscribe from this list: send the line "unsubscribe git" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply
* Re: [PATCH (topgit) 1/2] Implement setup_pager just like in git
From: Petr Baudis @ 2009-01-07 15:10 UTC (permalink / raw)
To: Kirill Smelkov, Pierre Habouzit; +Cc: martin f krafft, git
In-Reply-To: <20090107112754.GA15158@roro3>
On Wed, Jan 07, 2009 at 02:27:54PM +0300, Kirill Smelkov wrote:
> >From 2193b7c703c2d31c8739eec617b8c0e8c1d09b79 Mon Sep 17 00:00:00 2001
> From: Kirill Smelkov <kirr@landau.phys.spbu.ru>
> Date: Tue, 6 Jan 2009 17:56:37 +0300
> Subject: [PATCH (topgit) v2] Implement setup_pager just like in git
>
> setup_pager() spawns a pager process and redirect the rest of our output
> to it.
>
> This will be needed to fix `tg patch` output in the next commit.
>
> Signed-off-by: Kirill Smelkov <kirr@landau.phys.spbu.ru>
But you never use it...?
> ---
> tg.sh | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
> 1 files changed, 54 insertions(+), 0 deletions(-)
>
> diff --git a/tg.sh b/tg.sh
> index 8c23d26..bf9cf5c 100644
> --- a/tg.sh
> +++ b/tg.sh
> @@ -243,6 +243,60 @@ do_help()
> fi
> }
>
> +## Pager stuff
> +
> +# isatty FD
> +isatty()
> +{
> + tty -s 0<&$1
> +}
> +
> +# setup_pager
> +# Spawn pager process and redirect the rest of our output to it
> +setup_pager()
> +{
> + isatty 1 || return 0
> +
> + # TG_PAGER = GIT_PAGER | PAGER
> + # (but differentiate between GIT_PAGER='' and unset variables)
> + # http://unix.derkeiler.com/Newsgroups/comp.unix.shell/2004-03/0792.html
> + case ${GIT_PAGER+XXX} in
> + '')
> + case ${PAGER+XXX} in
> + '')
I'm pretty sure there's been a nice trick for this, but I can't remember
it at all now.
> + # both GIT_PAGER & PAGER unset
> + TG_PAGER=''
> + ;;
> + *)
> + TG_PAGER="$PAGER"
> + ;;
> + esac
> + ;;
> + *)
> + TG_PAGER="$GIT_PAGER"
> + ;;
> + esac
> +
> + [ -z "$TG_PAGER" -o "$TG_PAGER" = "cat" ] && return 0
> +
> +
> + # now spawn pager
> + export LESS=${LESS:-FRSX} # as in pager.c:pager_preexec()
> +
> + _pager_fifo_dir="$(mktemp -t -d tg-pager-fifo.XXXXXX)"
> + _pager_fifo="$_pager_fifo_dir/0"
> + mkfifo -m 600 "$_pager_fifo"
> +
> + "$TG_PAGER" < "$_pager_fifo" &
> + exec > "$_pager_fifo" # dup2(pager_fifo.in, 1)
> +
> + # this is needed so e.g. `git diff` will still colorize it's output if
> + # requested in ~/.gitconfig with color.diff=auto
> + export GIT_PAGER_IN_USE=1
> +
> + # atexit(close(1); wait pager)
> + trap "exec >&-; rm "$_pager_fifo"; rmdir "$_pager_fifo_dir"; wait" EXIT
> +}
Frankly, I would have been just much happier if something like git
pager--helper would be provided for external tools to use. Seeing how it
gets reimplemented like this just pains me greatly.
On Wed, Jan 07, 2009 at 03:44:32PM +0100, Pierre Habouzit wrote:
> On Wed, Jan 07, 2009 at 11:27:54AM +0000, Kirill Smelkov wrote:
> > isatty()
> > {
> > tty -s 0<&$1
> > }
>
> why not test -t 0 ? I'm not sure it's POSIX though.
It's SUS for many issues already it seems.
--
Petr "Pasky" Baudis
The average, healthy, well-adjusted adult gets up at seven-thirty
in the morning feeling just terrible. -- Jean Kerr
^ permalink raw reply
* Re: [PATCH/RFC] Allow writing loose objects that are corrupted in a pack file
From: Nicolas Pitre @ 2009-01-07 15:31 UTC (permalink / raw)
To: R. Tyler Ballance; +Cc: Linus Torvalds, Jan Krüger, Git ML
In-Reply-To: <1231314099.8870.415.camel@starfruit>
On Tue, 6 Jan 2009, R. Tyler Ballance wrote:
> On Tue, 2009-01-06 at 20:54 -0800, Linus Torvalds wrote:
> >
> > On Tue, 6 Jan 2009, R. Tyler Ballance wrote:
> > >
> > > I'll back the patch out and redeploy, it's worth mentioning that a
> > > coworker of mine just got the issue as well (on 1.6.1). He was able to
> > > `git pull` and the error went away, but I doubt that it "magically fixed
> > > itself"
> >
> > Quite frankly, that behaviour sounds like a disk _cache_ corruption issue.
> > The fact that some corruption "comes and goes" and sometimes magically
> > heals itself sounds very much like some disk cache problem, and then that
> > particular part of the cache gets replaced and then when re-populated it
> > is magically correct.
> >
> > We had that in one case with a Linux NFS client, where a rename across
> > directories caused problems.
> >
> > This was a networked filesystem on OS X, right? File caching is much more
> > "interesting" in networked filesystems than it is in normal private
> > on-disk ones.
>
> Not quite, what I meant was that some users (not all) who've experienced
> this issue are using Samba to copy files over directly into the Git
> repository. I was mentioning this in case somewhere between Finder,
> Samba, ext3 and Git, some file system change events were pissing Git off
> and causing it.
As long as those files are not within the .git directory that should be
fine.
> I don't think this is the case as the coworker that I
> mentioned earlier doesn't use Samba and neither do I (we both experience
> the issue today, mine disappeared by upgrading to 1.6.1, his by `git
> pull`).
Problem is that none of that "makes sense". If a real git corruption
was there, it wouldn't disappear without explicit action from your part.
What git v1.6.1 is able to do over earlier versions is to still function
properly if some corrupted objects have a redundant copy in the same
repository, but it wouldn't stop complaining about the existence of
corrupted data. Doing a 'git gc' or 'git repack -a' might get rid of
the corruption. And a 'git pull' might hide it if the received pack
during the pull operation happens to contain another copy of the object
that was corrupted before, but it wouldn't prevent 'git fsck --full'
from seeing it.
The fact that you cannot reproduce the corruption issues after
unarchiving a repository that was known to have problems right before it
was archived is really really strange. That does not rule out git bugs
of course, but at least this shows that no actual corruption on disk was
initially involved.
Again, I'd suggest you perform your git usage within a script session so
to capture the exact operation performed and error messages produced
when/if similar problems do occur again. Otherwise we're only running
after our tail.
Nicolas
^ permalink raw reply
* Re: Error: unable to unlink ... when using "git gc"
From: Boyd Stephen Smith Jr. @ 2009-01-07 15:48 UTC (permalink / raw)
To: git; +Cc: Sitaram Chamarty
In-Reply-To: <slrngm92hr.72d.sitaramc@sitaramc.homelinux.net>
[-- Attachment #1: Type: text/plain, Size: 1589 bytes --]
On Wednesday 2009 January 07 04:55:56 you wrote:
> On 2009-01-07, Boyd Stephen Smith Jr. <bss@iguanasuicide.net> wrote:
> > On Tuesday 06 January 2009, Sitaram Chamarty <sitaramc@gmail.com>
> > wrote=20
> >
> >> chmod g+ws .git
> >>
> >>Now set the group to something (I use "gitpushers" ;-)
> >>
> >> chgrp -R gitpushers .git
> >
> > ISTR this breaking here when someone on the team had a umask like 077
> > and=20 was using file:// or ssh:// to push. I tended up "fixing" things
> > with a=20 cronjob, (which is a bit of a hack) IIRC.
>
> That doesn't sound right. "git help init" says:
> - 0xxx: 0xxx is an octal number and each file will have mode 0xxx
> - 0xxx will override users umask(2) value, and thus, users
> with a safe umask (0077) can use this option
> - 0660 is equivalent to group.
>
> So when you say "group", you're saying "0660", and when you
> say "0660", you're overriding users umask value.
Very good then. It is from when I was significantly less experienced in using
git and managing repos, so I may have forgotten to use the correct options OR
it could just have been the version of git I was using (1.4.4.4, IIRC) --
still using that in at least one place, as it is the current version in
Debian Etch.
It's good to know it works properly now, if all the right switches are set.
--
Boyd Stephen Smith Jr. ,= ,-_-. =.
bss@iguanasuicide.net ((_/)o o(\_))
ICQ: 514984 YM/AIM: DaTwinkDaddy `-'(. .)`-'
http://iguanasuicide.net/ \_/
[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 197 bytes --]
^ permalink raw reply
* Re: [PATCH] gitweb: support the rel=vcs microformat
From: Joey Hess @ 2009-01-07 15:50 UTC (permalink / raw)
To: Giuseppe Bilotta; +Cc: git
In-Reply-To: <gk2794$djn$1@ger.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 1005 bytes --]
Giuseppe Bilotta wrote:
> In this patch you do NOT add titles to the rel=vcs links, which means that
> everything works fine only if there is a single URL for each project. If a
> project has different URLs, it's going to appear multiple times as _different_
> projects to a spec-compliant reader.
>
> A possible solution would be to make @git_url_list into a map keyed by the
> project name and having the description and repo URL(s) as values.
Yes. I considered doing that, but didn't immediatly see a way to get the
project description w/o additional overhead (of looking it up a second
time).
> > This changes git_get_project_description() to not check wantarray, and only
> > return in list context -- the only way it is used AFAICS.
>
> I assume you mean git_get_project_url_list()?
In fact yes.
Thanks for the feedback. There are some changes happening to the
microformat that should make gitweb's job slightly easier, I'll respin
the patch soon.
--
see shy jo
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* Re: git rebase orthodontics
From: Boyd Stephen Smith Jr. @ 2009-01-07 16:10 UTC (permalink / raw)
To: jidanni; +Cc: git
In-Reply-To: <87sknvxje8.fsf@jidanni.org>
[-- Attachment #1: Type: text/plain, Size: 559 bytes --]
If you want to go from:
> A jidanni
> /
> D---E---F---G master
To:
> D---E---F---G---A master, jidanni
You don't want rebase. You want 'git checkout master && git merge jidanni'.
I think you can throw --no-commit on the merge is you want to avoid a non-ff
update to the master ref.
--
Boyd Stephen Smith Jr. ,= ,-_-. =.
bss@iguanasuicide.net ((_/)o o(\_))
ICQ: 514984 YM/AIM: DaTwinkDaddy `-'(. .)`-'
http://iguanasuicide.net/ \_/
[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 197 bytes --]
^ permalink raw reply
* Re: Comments on Presentation Notes Request.
From: Tim Visher @ 2009-01-07 16:11 UTC (permalink / raw)
To: david; +Cc: git
In-Reply-To: <alpine.DEB.1.10.0901070030320.31038@asgard.lang.hm>
[-- Attachment #1: Type: text/plain, Size: 8698 bytes --]
Thanks for the suggestions so far. I've updated the notes.
@Peff: Thanks especially for pointing me towards Junio's
presentatation. That's an excellent source.
Here's the patch for your suggestions:
diff --git a/scmOutline.txt b/scmOutline.txt
index 1791fa0..d25198c 100644
--- a/scmOutline.txt
+++ b/scmOutline.txt
@@ -1,4 +1,4 @@
-SCM: Distributed, Centralized, and Everything in Between.
+SCM: Centralized, Distributed, and Everything in Between.
* What is SCM and Why is it Useful?
@@ -20,7 +20,11 @@ Not only is it unlimited, but it's random access.
If you changed a function a w
Many people can edit the same code base at the same time and know,
without a doubt, that when they pull all those changes together, the
system will merge the content intelligently or inform you of the
conflict and let you merge it. You don't need to lock files.
Obviously, if there is bad coordination then the possibilities of
conflicts rise, but this should not happen regularly.
-*** Diff Debugging
+*** Software Archeology
+
+With a proper SCMS, it becomes a somewhat trivial operation to
discover the author and reasons for a given change. This is because
of the rich metadata associated with commits (author, date, complete
change set, diffs, and commentary). So rather than wandering asking
if anyone remembers doing something and why, you simply commit that
information into the system and then refer to it when you need to.
+
+**** Diff Debugging
You can find where a bug was introduced by learning how to reproduce
the bug and then doing a binary chop search back through the History
to come to the exact commit that introduced the bug.
@@ -30,11 +34,11 @@ You can find where a bug was introduced by
learning how to reproduce the bug and
The more you commit, the more fine grained control you have over the
undo feature of SCM. Most documents that I have read suggested a TDD
approach wherein you commit whenever you have written just enough code
for your test to pass. But...
-** Don't Commit Broken Code (To the Public Tree)
+** Don't _Publish_ Broken Code
Of primary concern is the fact that your central HEAD should _always_
build. This is why practices like Continuous Integration and TDD are
so important. TDD gives you the freedom to be sure that a change you
made hasn't broken anything you weren't expecting it to break.
Continuous Integration allows you to be sure that your whole system
will build every time. Thus, you should _never_ commit broken code to
the (public) tree.
-Of course, in a centralized system, committing is intrinsically
public. Even on branches, every time you commit any sort of change,
everyone is able to see it and so you could be breaking the build for
someone (even if it's just yourself and the build system). One of the
nice features of a distributed system is that your public/private
ontology is much richer and thus allows you to have broken code in
your SCMS.
+Of course, in a centralized system, committing is intrinsically
public. Even on branches, every time you commit any sort of change,
everyone is able to see it and so you could be breaking the build for
someone (even if it's just yourself and the build system). One of the
nice features of a distributed system is that your public/private
ontology is much richer and thus allows you to have broken code in
your SCMS, so long as you haven't published it, at no penalty to
anyone but yourself.
** Whole Hog
@@ -130,7 +134,9 @@ Once you've published, however, not much changes.
Almost everything except upda
*** Natural Backup
-Because every developer has a copy of the repository, every developer
you add adds an extra failure point. The more developers you have,
the more backups you have of the repository.
+Because every developer has a copy of the repository, every developer
you add adds an extra layer of redundancy. The more developers you
have, the more backups you have of the repository.
+
+An important point to make clear here is that you only are backing up
what everyone is duplicating. If you have 10 unpublished branches
that no one else has cloned, then those are obviously not backed up.
However, the idea here would be that anything that is being developed
actively by multiple people is backed up by as many developers. Other
than that, your private data must be backed up by you (which is what
you do anyway, right? ;).
*** Must Learn New Work Flows.
@@ -148,6 +154,8 @@ This bears some explanation. Within a distributed
system, you can have a single
Git's implementation just happens to be wickedly fast. It's faster
than mercurial, it's faster than bazaar, etc. Everything, committing,
merging, viewing history, branching, and even updating and and pushing
are all faster.
+This is much more important than just shaving a few seconds off the
operations. Because Git is so much faster, you begin to do things
differently because of how fast it is. Git's blazing fast branching
and merging wouldn't matter at all if you never branched and merged
(which is possible), but because their blazing fast you _should_ begin
to branch and merge much more often, which __does__ fundamentally
change the way you develop your code (hopefully for the better).
+
** Tracks Content, not Files
Git tracks content, not files, and it's the only SCMS at the moment
that does this. This has many effects internally, but the most
apparent effect I know of is that for the first time Git can easily
tell you the history of even a function in a file because Git can tell
you which files that function existed (or does exist) in over the
course of development.
@@ -171,9 +179,9 @@ This is very powerful yet somewhat awkward to
grasp. Basically, the upshot of t
I've found this to be particularly useful when working with an
existing code base that was not properly formatted. Often, I'll come
to a file that has a bunch of wonky white space choices and improperly
indented logical constructs and I'll just quickly run through it
correcting that stuff before continuing with the feature I was working
on. Afterwords, I'll stage the formatting and commit it, and then
stage the feature I was working on and commit that. You may not want
that kind of control (and if you don't, you don't need to use it), but
I like it.
-** Excellent Merge algorithms
+** Stupid but _Fast_ Merge Algorithms
-Git has excellent merge algorithms. This is widely attributed and
doesn't require much explanation. It was one of Git's original design
goals, and it has been proven by Git's implementation. Merging in Git
is _much_ less painful than in other systems.
+Merging in Git is _much_ less painful than in other systems. This is
mainly because of how fast it is and how much data it remembers when
it does a merge. As opposed to CVS which can't merge a branch twice
because it doesn't remember where the last merge happened, Git keeps
track of that information so you can merge between branches as much as
you want. Git's philosophy is to make merging as fast and painless as
possible so that you merge early and often enough to not develop
really bad conflicts that are nearly impossible to resolve.
** Has powerful 'maintainer tools'
@@ -196,3 +204,4 @@ Git guarantees absolutely that if corruption
happens, you will know about it. I
- <http://svnbook.red-bean.com/> - Rolling publish book on
Subversion. Chapter 1 is a good introduction to general centralized
SCM concepts and principles.
- <http://www.perforce.com/perforce/bestpractices.html> - An
excellent set of best practices from the Perforce team. Some of it
(especially the branches) has a distinct centralized lean, but most of
it is quite good.
- <http://www.bobev.com/PresentationsAndPapers/Common%20SCM%20Patterns.pdf>
- Interesting presentation by Pretzel Logic from 2001 attempting to
outline some common SCM best practices as Patterns.
+- <http://members.cox.net/junkio/200607-ols.pdf> - A presentation by
Junio Hamano (the Git maintainer) at a Linux symposium on what Git is
with some tutorials.
I've also attached it as a file. It was generated by `git diff -p`.
I'm also looking for anyplace where I'm technically inaccurate.
Unfortunately, I've written a lot of this from things that I've either
read or heard. I'm mainly experienced with VSS and Subversion (and
both of those to a very small degree), and making a lot of progress
with Git. I've kind of been swept away by all the energy surrounding
git right now, though, so I'm sure my judgement is somewhat clouded.
Thanks again for your help!
--
In Christ,
Timmy V.
http://burningones.com/
http://five.sentenc.es/ - Spend less time on e-mail
[-- Attachment #2: suggestionsPatch01 --]
[-- Type: application/octet-stream, Size: 7915 bytes --]
diff --git a/scmOutline.txt b/scmOutline.txt
index 1791fa0..d25198c 100644
--- a/scmOutline.txt
+++ b/scmOutline.txt
@@ -1,4 +1,4 @@
-SCM: Distributed, Centralized, and Everything in Between.
+SCM: Centralized, Distributed, and Everything in Between.
* What is SCM and Why is it Useful?
@@ -20,7 +20,11 @@ Not only is it unlimited, but it's random access. If you changed a function a w
Many people can edit the same code base at the same time and know, without a doubt, that when they pull all those changes together, the system will merge the content intelligently or inform you of the conflict and let you merge it. You don't need to lock files. Obviously, if there is bad coordination then the possibilities of conflicts rise, but this should not happen regularly.
-*** Diff Debugging
+*** Software Archeology
+
+With a proper SCMS, it becomes a somewhat trivial operation to discover the author and reasons for a given change. This is because of the rich metadata associated with commits (author, date, complete change set, diffs, and commentary). So rather than wandering asking if anyone remembers doing something and why, you simply commit that information into the system and then refer to it when you need to.
+
+**** Diff Debugging
You can find where a bug was introduced by learning how to reproduce the bug and then doing a binary chop search back through the History to come to the exact commit that introduced the bug.
@@ -30,11 +34,11 @@ You can find where a bug was introduced by learning how to reproduce the bug and
The more you commit, the more fine grained control you have over the undo feature of SCM. Most documents that I have read suggested a TDD approach wherein you commit whenever you have written just enough code for your test to pass. But...
-** Don't Commit Broken Code (To the Public Tree)
+** Don't _Publish_ Broken Code
Of primary concern is the fact that your central HEAD should _always_ build. This is why practices like Continuous Integration and TDD are so important. TDD gives you the freedom to be sure that a change you made hasn't broken anything you weren't expecting it to break. Continuous Integration allows you to be sure that your whole system will build every time. Thus, you should _never_ commit broken code to the (public) tree.
-Of course, in a centralized system, committing is intrinsically public. Even on branches, every time you commit any sort of change, everyone is able to see it and so you could be breaking the build for someone (even if it's just yourself and the build system). One of the nice features of a distributed system is that your public/private ontology is much richer and thus allows you to have broken code in your SCMS.
+Of course, in a centralized system, committing is intrinsically public. Even on branches, every time you commit any sort of change, everyone is able to see it and so you could be breaking the build for someone (even if it's just yourself and the build system). One of the nice features of a distributed system is that your public/private ontology is much richer and thus allows you to have broken code in your SCMS, so long as you haven't published it, at no penalty to anyone but yourself.
** Whole Hog
@@ -130,7 +134,9 @@ Once you've published, however, not much changes. Almost everything except upda
*** Natural Backup
-Because every developer has a copy of the repository, every developer you add adds an extra failure point. The more developers you have, the more backups you have of the repository.
+Because every developer has a copy of the repository, every developer you add adds an extra layer of redundancy. The more developers you have, the more backups you have of the repository.
+
+An important point to make clear here is that you only are backing up what everyone is duplicating. If you have 10 unpublished branches that no one else has cloned, then those are obviously not backed up. However, the idea here would be that anything that is being developed actively by multiple people is backed up by as many developers. Other than that, your private data must be backed up by you (which is what you do anyway, right? ;).
*** Must Learn New Work Flows.
@@ -148,6 +154,8 @@ This bears some explanation. Within a distributed system, you can have a single
Git's implementation just happens to be wickedly fast. It's faster than mercurial, it's faster than bazaar, etc. Everything, committing, merging, viewing history, branching, and even updating and and pushing are all faster.
+This is much more important than just shaving a few seconds off the operations. Because Git is so much faster, you begin to do things differently because of how fast it is. Git's blazing fast branching and merging wouldn't matter at all if you never branched and merged (which is possible), but because their blazing fast you _should_ begin to branch and merge much more often, which __does__ fundamentally change the way you develop your code (hopefully for the better).
+
** Tracks Content, not Files
Git tracks content, not files, and it's the only SCMS at the moment that does this. This has many effects internally, but the most apparent effect I know of is that for the first time Git can easily tell you the history of even a function in a file because Git can tell you which files that function existed (or does exist) in over the course of development.
@@ -171,9 +179,9 @@ This is very powerful yet somewhat awkward to grasp. Basically, the upshot of t
I've found this to be particularly useful when working with an existing code base that was not properly formatted. Often, I'll come to a file that has a bunch of wonky white space choices and improperly indented logical constructs and I'll just quickly run through it correcting that stuff before continuing with the feature I was working on. Afterwords, I'll stage the formatting and commit it, and then stage the feature I was working on and commit that. You may not want that kind of control (and if you don't, you don't need to use it), but I like it.
-** Excellent Merge algorithms
+** Stupid but _Fast_ Merge Algorithms
-Git has excellent merge algorithms. This is widely attributed and doesn't require much explanation. It was one of Git's original design goals, and it has been proven by Git's implementation. Merging in Git is _much_ less painful than in other systems.
+Merging in Git is _much_ less painful than in other systems. This is mainly because of how fast it is and how much data it remembers when it does a merge. As opposed to CVS which can't merge a branch twice because it doesn't remember where the last merge happened, Git keeps track of that information so you can merge between branches as much as you want. Git's philosophy is to make mergining as fast and painless as possible so that you merge early and often enough to not develop really bad conflicts that are nearly impossible to resolve.
** Has powerful 'maintainer tools'
@@ -196,3 +204,4 @@ Git guarantees absolutely that if corruption happens, you will know about it. I
- <http://svnbook.red-bean.com/> - Rolling publish book on Subversion. Chapter 1 is a good introduction to general centralized SCM concepts and principles.
- <http://www.perforce.com/perforce/bestpractices.html> - An excellent set of best practices from the Perforce team. Some of it (especially the branches) has a distinct centralized lean, but most of it is quite good.
- <http://www.bobev.com/PresentationsAndPapers/Common%20SCM%20Patterns.pdf> - Interesting presentation by Pretzel Logic from 2001 attempting to outline some common SCM best practices as Patterns.
+- <http://members.cox.net/junkio/200607-ols.pdf> - A presentation by Junio Hamano (the Git maintainer) at a Linux symposium on what Git is with some tutorials.
^ permalink raw reply related
* Re: [PATCH/RFC] Allow writing loose objects that are corrupted in a pack file
From: Linus Torvalds @ 2009-01-07 16:07 UTC (permalink / raw)
To: R. Tyler Ballance; +Cc: Nicolas Pitre, Jan Krüger, Git ML
In-Reply-To: <1231314099.8870.415.camel@starfruit>
On Tue, 6 Jan 2009, R. Tyler Ballance wrote:
> >
> > The thing to do is
> >
> > - untar it on some trusted machine with a local disk and a known-good
> > filesystem.
> >
> > IOW, not that networked samba share.
> >
> > - verify that it really does happen on that machine, with that untarred
> > image. Because maybe it doesn't.
>
> Unfortunately it doesn't
Well, that's not necessarily "unfortunate". It does actually end up
showing that the objects themselves were apparently never really corrupt.
So there is no fundamental data structure corrupttion - because when you
copy the repository, it's all good agin!
In other words, that's not a worthless piece of information at all, and it
does tell us a lot, namely that the corruption was never real long-term
data corruption of the git object archive, but something local and
temporary. Again, we're really back to either:
- it could be some _temporary_ git corruption caused internally inside a
git process - ie a wild pointer, or perhaps a race condition (but we
don't really use threading in 1.6.0.4 unless you ask for it, and even
then just for pack-file generation)
- or it's the disk cache corruption, and the tar/untar ended up flushing
it.
And quite frankly, since the corruption seems to be site-specific, I
really do suspect the second case. Although it's possible, of course, that
it could be some compiler issue that makes _your_ binaries have issues
even when nobody else sees it.
> what I did notice was this when I did a `git
> status` in the directory right after untarring:
> tyler@grapefruit:~/jburgess_main> git status
> #
> # ---impressive amount of file names fly by---
> # ----snip---
> #
> # Untracked files:
> # (use "git add <file>..." to include in what will be
> committed)
> #
> # artwork/
> # bt/
> # flash/
Hmm. That's actually _normal_ under some circumstances. At least with
older git versions, or if your .git/index file couldn't be rewritten for
some reason - your existing index file contains all the old stat
information, and if git cannot (or, in the case of older git version, just
will not) refresh it automatically, it will show all the files as changed,
even if it's just the inode number that really changed.
A _normal_ git install should have auto-refreshed the index, though.
Unless the tar archive only contained the ".git" directory, and not the
checkout?
> tyler@grapefruit:~/jburgess_main>
>
> Basically, somehow Git thinks that *every* file in the repository is
> deleted at this point. I went ahead and performed a `git reset --hard`
> to see if the issue would manifest itself thereafter, but it did not.
That would be what I'd expect if you had only tarred up .git, although
then I wouldn't have expected those "Untracked files:". Hmm. Without being
able to look at the archive, I'm just guessing randomly.
> I did try to do a git-fsck(1), and this is what I got:
> tyler@grapefruit:~/jburgess_main> /usr/local/bin/git fsck --full
> [1] 19381 segmentation fault /usr/local/bin/git fsck --full
> tyler@grapefruit:~/jburgess_main>
.. and that's the unrelated fsck bug that got fixed later.
> > The hope is that you caught the corruption in the cache, and it
> > actually got written out to the tar-file. But if it _is_ a disk cache
> > (well, network cache) issue, maybe the IO required to tar everything up
> > was enough to flush it, and the tar-file actually _works_ because it
> > got repopulated correctly.
>
> When I was working through this with Jan, one of the things that we did
> was move the actual object file in .git/objects, they existed so maybe I
> could look into those to check?
Yes. If you have any bad loose objects, if you compare them to the good
objects with the same name, that's going to be interesting information.
The pattern of corruption can be very telling. For example, on Linux, a
disk cache corruption would usually be at 4kB block boundaries, because
that's the granularity of the cache. While a bit error would be obvious
etc etc.
> I checked with our operations team, and contrary to my suspicion (your
> NFS comment piqued my curiosity), these disks that are actually on the
> machines are not NFS mounts but rather local disk arrays.
Ok, that generally makes caching much simpler. What filesystem?
Is there anything else that you do that is site-specific and/or slightly
different? For example, a long time ago we had a bug related to CRLF
conversion which would cause a use-after-free problem, and that would
corrupt the data internally to git.
And dobody else saw it than this one person, and it was a total mystery to
everybody until we realized that he used this one feature that nobody else
was using. So as you're on OS X, I assume you don't have CRLF conversion,
but maybe you use some other feature that we support but nobody really
actually uses. Like keyword expansion or something?
Oh - that would also explain why you got all those entries in "git status"
that went away when you did a "git reset --hard": if you had some keyword
expansion (or CRLF) enabled in the original users "~/.gitconfig", that
checkout would have had expansion/CRLF/whatever conversion, but then when
you tarred/untarred it on another setup, the expansion would be seen as a
difference because it wasn't enabled.
Hmm?
Linus
^ permalink raw reply
* Re: [PATCH/RFC] Allow writing loose objects that are corrupted in a pack file
From: Linus Torvalds @ 2009-01-07 16:08 UTC (permalink / raw)
To: R. Tyler Ballance; +Cc: Nicolas Pitre, Jan Krüger, Git ML
In-Reply-To: <alpine.LFD.2.00.0901070743070.3057@localhost.localdomain>
On Wed, 7 Jan 2009, Linus Torvalds wrote:
>
> And dobody else saw it than this one person, and it was a total mystery to
> everybody until we realized that he used this one feature that nobody else
> was using. So as you're on OS X, I assume you don't have CRLF conversion,
> but maybe you use some other feature that we support but nobody really
> actually uses. Like keyword expansion or something?
>
> Oh - that would also explain why you got all those entries in "git status"
> that went away when you did a "git reset --hard": if you had some keyword
> expansion (or CRLF) enabled in the original users "~/.gitconfig", that
> checkout would have had expansion/CRLF/whatever conversion, but then when
> you tarred/untarred it on another setup, the expansion would be seen as a
> difference because it wasn't enabled.
Btw, if you untar it again, and just do a "git diff", that should show any
such effects. Rather than showing just that something changed, it should
show _how_ it changed.
Linus
^ permalink raw reply
* Re: git rebase orthodontics
From: Thomas Rast @ 2009-01-07 16:31 UTC (permalink / raw)
To: jidanni; +Cc: git
In-Reply-To: <87sknvxje8.fsf@jidanni.org>
[-- Attachment #1: Type: text/plain, Size: 2083 bytes --]
jidanni@jidanni.org wrote:
> wherein he discovers there are no guard rails
Good thing you learned this before getting to git-reset.
> $ EDITOR=cat git rebase --interactive master
> pick 07aef4a This is a commit with No files, wow. bla.
> # Rebase 3ad166e..07aef4a onto 3ad166e ...
> Successfully rebased and updated refs/heads/jidanni.
> (But it didn't. git show shows no change. ls -l shows
> refs/heads/jidanni was not touched.
> OK, it seems like all I am doing is changing
> A jidanni
> /
> D---E---F---G master
> into the same thing, a noop. But shouldn't it warn and quit, instead
> of rewarding me with the success message?
You asked for an interactive rebase of the range master..jidanni,
which consists of A, so it gave you an editor offering 'pick A' and
the chance to change that.
Non-interactive rebase indeed checks if you attempt to rebase, but are
already up to date. Interactive doesn't; the assumption is that
interactive rebases aren't used "blindly" to update. (Rebasing
changes committer and commit time, so there is a difference between
not rebasing at all, and merely ending up with the same history.)
> Let's try it the other way
> around:
> $ git checkout master
> $ git rebase --interactive jidanni #Wherein one sees:
> noop
> # Rebase 07aef4a..3ad166e onto 07aef4a
> Successfully rebased and updated refs/heads/master.
> OK, now I have achieved
> D---E---F---G---A master, jidanni
> Observations:
> When I tried a noop, it didn't say noop in the editor.
> When I tried a yesop, it did say noop in the editor.
The 'noop' means that there are no commits in the range you asked to
rebase, which is jidanni..master. It's telling you that it is going
to update the branch pointer, but not carry over any of the commits.
This can happen even if jidanni..master is nonempty, but all commits
in it are already contained in jidanni.
> In both cases it gave the same success message.
It successfully did what you told it to do.
--
Thomas Rast
trast@{inf,student}.ethz.ch
[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 197 bytes --]
^ permalink raw reply
* Re: [PATCH 0/3] Teach Git about the patience diff algorithm
From: Johannes Schindelin @ 2009-01-07 17:01 UTC (permalink / raw)
To: Pierre Habouzit; +Cc: Linus Torvalds, davidel, Francis Galiegue, Git ML
In-Reply-To: <20090107143926.GB831@artemis.corp>
Hi,
On Wed, 7 Jan 2009, Pierre Habouzit wrote:
> On Tue, Jan 06, 2009 at 07:40:02PM +0000, Johannes Schindelin wrote:
>
> > Although I would like to see it in once it is fleshed out -- even if
> > it does not meet our usefulness standard -- because people said Git is
> > inferior for not providing a patience diff. If we have --patience, we
> > can say "but we have it, it's just not useful, check for yourself".
>
> Well I believe it's useful, but maybe the standard algorithm could be
> tweaked the way Linus proposes to make the "long" lines weight louder or
> so.
I think this "weighting idea" is a bit too much of handwaving to start
anything close to a design; as I pointed out, anything that has something
different than a 1 for a deleted/added line affects performance
negatively.
> WRT the leaks, you want to squash the attached patch on the proper
> patches of your series (maybe the xdl_free on map.entries could be put
> in a hasmap_destroy or similar btw, but valgrind reports no more leaks
> in xdiff now).
Thanks!
I also squashed in a patch that avoids calling xdl_cleanup_records() and
then memset()ing the rchg array to 0 (which worked around the segmentation
fault).
Patch 1/3 v3 follows,
Dscho
^ permalink raw reply
* [PATCH v3 1/3] Implement the patience diff algorithm
From: Johannes Schindelin @ 2009-01-07 17:04 UTC (permalink / raw)
To: Pierre Habouzit; +Cc: Linus Torvalds, davidel, Francis Galiegue, Git ML
In-Reply-To: <alpine.DEB.1.00.0901071610290.7496@intel-tinevez-2-302>
The patience diff algorithm produces slightly more intuitive output
than the classic Myers algorithm, as it does not try to minimize the
number of +/- lines first, but tries to preserve the lines that are
unique.
To this end, it first determines lines that are unique in both files,
then the maximal sequence which preserves the order (relative to both
files) is extracted.
Starting from this initial set of common lines, the rest of the lines
is handled recursively, with Myers' algorithm as a fallback when
the patience algorithm fails (due to no common unique lines).
This patch includes memory leak fixes by Pierre Habouzit.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
This comes close to 'next' quality, IMHO.
Changes vs v2: Pierre's memory leak fixes, and it now avoids
calling xdl_cleanup_records() and then throwing away the
results for patience diff.
Pierre, could you do the performance tests again? I _think_ it
might be somewhat faster now because of the xdl_cleanup_records()
avoidance.
xdiff/xdiff.h | 1 +
xdiff/xdiffi.c | 3 +
xdiff/xdiffi.h | 2 +
xdiff/xpatience.c | 381 +++++++++++++++++++++++++++++++++++++++++++++++++++++
xdiff/xprepare.c | 3 +-
5 files changed, 389 insertions(+), 1 deletions(-)
create mode 100644 xdiff/xpatience.c
diff --git a/xdiff/xdiff.h b/xdiff/xdiff.h
index 361f802..4da052a 100644
--- a/xdiff/xdiff.h
+++ b/xdiff/xdiff.h
@@ -32,6 +32,7 @@ extern "C" {
#define XDF_IGNORE_WHITESPACE (1 << 2)
#define XDF_IGNORE_WHITESPACE_CHANGE (1 << 3)
#define XDF_IGNORE_WHITESPACE_AT_EOL (1 << 4)
+#define XDF_PATIENCE_DIFF (1 << 5)
#define XDF_WHITESPACE_FLAGS (XDF_IGNORE_WHITESPACE | XDF_IGNORE_WHITESPACE_CHANGE | XDF_IGNORE_WHITESPACE_AT_EOL)
#define XDL_PATCH_NORMAL '-'
diff --git a/xdiff/xdiffi.c b/xdiff/xdiffi.c
index 9d0324a..3e97462 100644
--- a/xdiff/xdiffi.c
+++ b/xdiff/xdiffi.c
@@ -329,6 +329,9 @@ int xdl_do_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
xdalgoenv_t xenv;
diffdata_t dd1, dd2;
+ if (xpp->flags & XDF_PATIENCE_DIFF)
+ return xdl_do_patience_diff(mf1, mf2, xpp, xe);
+
if (xdl_prepare_env(mf1, mf2, xpp, xe) < 0) {
return -1;
diff --git a/xdiff/xdiffi.h b/xdiff/xdiffi.h
index 3e099dc..ad033a8 100644
--- a/xdiff/xdiffi.h
+++ b/xdiff/xdiffi.h
@@ -55,5 +55,7 @@ int xdl_build_script(xdfenv_t *xe, xdchange_t **xscr);
void xdl_free_script(xdchange_t *xscr);
int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb,
xdemitconf_t const *xecfg);
+int xdl_do_patience_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
+ xdfenv_t *env);
#endif /* #if !defined(XDIFFI_H) */
diff --git a/xdiff/xpatience.c b/xdiff/xpatience.c
new file mode 100644
index 0000000..e42c16a
--- /dev/null
+++ b/xdiff/xpatience.c
@@ -0,0 +1,381 @@
+/*
+ * LibXDiff by Davide Libenzi ( File Differential Library )
+ * Copyright (C) 2003-2009 Davide Libenzi, Johannes E. Schindelin
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Davide Libenzi <davidel@xmailserver.org>
+ *
+ */
+#include "xinclude.h"
+#include "xtypes.h"
+#include "xdiff.h"
+
+/*
+ * The basic idea of patience diff is to find lines that are unique in
+ * both files. These are intuitively the ones that we want to see as
+ * common lines.
+ *
+ * The maximal ordered sequence of such line pairs (where ordered means
+ * that the order in the sequence agrees with the order of the lines in
+ * both files) naturally defines an initial set of common lines.
+ *
+ * Now, the algorithm tries to extend the set of common lines by growing
+ * the line ranges where the files have identical lines.
+ *
+ * Between those common lines, the patience diff algorithm is applied
+ * recursively, until no unique line pairs can be found; these line ranges
+ * are handled by the well-known Myers algorithm.
+ */
+
+#define NON_UNIQUE ULONG_MAX
+
+/*
+ * This is a hash mapping from line hash to line numbers in the first and
+ * second file.
+ */
+struct hashmap {
+ int nr, alloc;
+ struct entry {
+ unsigned long hash;
+ /*
+ * 0 = unused entry, 1 = first line, 2 = second, etc.
+ * line2 is NON_UNIQUE if the line is not unique
+ * in either the first or the second file.
+ */
+ unsigned long line1, line2;
+ /*
+ * "next" & "previous" are used for the longest common
+ * sequence;
+ * initially, "next" reflects only the order in file1.
+ */
+ struct entry *next, *previous;
+ } *entries, *first, *last;
+ /* were common records found? */
+ unsigned long has_matches;
+ mmfile_t *file1, *file2;
+ xdfenv_t *env;
+ xpparam_t const *xpp;
+};
+
+/* The argument "pass" is 1 for the first file, 2 for the second. */
+static void insert_record(int line, struct hashmap *map, int pass)
+{
+ xrecord_t **records = pass == 1 ?
+ map->env->xdf1.recs : map->env->xdf2.recs;
+ xrecord_t *record = records[line - 1], *other;
+ /*
+ * After xdl_prepare_env() (or more precisely, due to
+ * xdl_classify_record()), the "ha" member of the records (AKA lines)
+ * is _not_ the hash anymore, but a linearized version of it. In
+ * other words, the "ha" member is guaranteed to start with 0 and
+ * the second record's ha can only be 0 or 1, etc.
+ *
+ * So we multiply ha by 2 in the hope that the hashing was
+ * "unique enough".
+ */
+ int index = (int)((record->ha << 1) % map->alloc);
+
+ while (map->entries[index].line1) {
+ other = map->env->xdf1.recs[map->entries[index].line1 - 1];
+ if (map->entries[index].hash != record->ha ||
+ !xdl_recmatch(record->ptr, record->size,
+ other->ptr, other->size,
+ map->xpp->flags)) {
+ if (++index >= map->alloc)
+ index = 0;
+ continue;
+ }
+ if (pass == 2)
+ map->has_matches = 1;
+ if (pass == 1 || map->entries[index].line2)
+ map->entries[index].line2 = NON_UNIQUE;
+ else
+ map->entries[index].line2 = line;
+ return;
+ }
+ if (pass == 2)
+ return;
+ map->entries[index].line1 = line;
+ map->entries[index].hash = record->ha;
+ if (!map->first)
+ map->first = map->entries + index;
+ if (map->last) {
+ map->last->next = map->entries + index;
+ map->entries[index].previous = map->last;
+ }
+ map->last = map->entries + index;
+ map->nr++;
+}
+
+/*
+ * This function has to be called for each recursion into the inter-hunk
+ * parts, as previously non-unique lines can become unique when being
+ * restricted to a smaller part of the files.
+ *
+ * It is assumed that env has been prepared using xdl_prepare().
+ */
+static int fill_hashmap(mmfile_t *file1, mmfile_t *file2,
+ xpparam_t const *xpp, xdfenv_t *env,
+ struct hashmap *result,
+ int line1, int count1, int line2, int count2)
+{
+ result->file1 = file1;
+ result->file2 = file2;
+ result->xpp = xpp;
+ result->env = env;
+
+ /* We know exactly how large we want the hash map */
+ result->alloc = count1 * 2;
+ result->entries = (struct entry *)
+ xdl_malloc(result->alloc * sizeof(struct entry));
+ if (!result->entries)
+ return -1;
+ memset(result->entries, 0, result->alloc * sizeof(struct entry));
+
+ /* First, fill with entries from the first file */
+ while (count1--)
+ insert_record(line1++, result, 1);
+
+ /* Then search for matches in the second file */
+ while (count2--)
+ insert_record(line2++, result, 2);
+
+ return 0;
+}
+
+/*
+ * Find the longest sequence with a smaller last element (meaning a smaller
+ * line2, as we construct the sequence with entries ordered by line1).
+ */
+static int binary_search(struct entry **sequence, int longest,
+ struct entry *entry)
+{
+ int left = -1, right = longest;
+
+ while (left + 1 < right) {
+ int middle = (left + right) / 2;
+ /* by construction, no two entries can be equal */
+ if (sequence[middle]->line2 > entry->line2)
+ right = middle;
+ else
+ left = middle;
+ }
+ /* return the index in "sequence", _not_ the sequence length */
+ return left;
+}
+
+/*
+ * The idea is to start with the list of common unique lines sorted by
+ * the order in file1. For each of these pairs, the longest (partial)
+ * sequence whose last element's line2 is smaller is determined.
+ *
+ * For efficiency, the sequences are kept in a list containing exactly one
+ * item per sequence length: the sequence with the smallest last
+ * element (in terms of line2).
+ */
+static struct entry *find_longest_common_sequence(struct hashmap *map)
+{
+ struct entry **sequence = xdl_malloc(map->nr * sizeof(struct entry *));
+ int longest = 0, i;
+ struct entry *entry;
+
+ for (entry = map->first; entry; entry = entry->next) {
+ if (!entry->line2 || entry->line2 == NON_UNIQUE)
+ continue;
+ i = binary_search(sequence, longest, entry);
+ entry->previous = i < 0 ? NULL : sequence[i];
+ sequence[++i] = entry;
+ if (i == longest)
+ longest++;
+ }
+
+ /* No common unique lines were found */
+ if (!longest) {
+ xdl_free(sequence);
+ return NULL;
+ }
+
+ /* Iterate starting at the last element, adjusting the "next" members */
+ entry = sequence[longest - 1];
+ entry->next = NULL;
+ while (entry->previous) {
+ entry->previous->next = entry;
+ entry = entry->previous;
+ }
+ xdl_free(sequence);
+ return entry;
+}
+
+static int match(struct hashmap *map, int line1, int line2)
+{
+ xrecord_t *record1 = map->env->xdf1.recs[line1 - 1];
+ xrecord_t *record2 = map->env->xdf2.recs[line2 - 1];
+ return xdl_recmatch(record1->ptr, record1->size,
+ record2->ptr, record2->size, map->xpp->flags);
+}
+
+static int patience_diff(mmfile_t *file1, mmfile_t *file2,
+ xpparam_t const *xpp, xdfenv_t *env,
+ int line1, int count1, int line2, int count2);
+
+static int walk_common_sequence(struct hashmap *map, struct entry *first,
+ int line1, int count1, int line2, int count2)
+{
+ int end1 = line1 + count1, end2 = line2 + count2;
+ int next1, next2;
+
+ for (;;) {
+ /* Try to grow the line ranges of common lines */
+ if (first) {
+ next1 = first->line1;
+ next2 = first->line2;
+ while (next1 > line1 && next2 > line2 &&
+ match(map, next1 - 1, next2 - 1)) {
+ next1--;
+ next2--;
+ }
+ } else {
+ next1 = end1;
+ next2 = end2;
+ }
+ while (line1 < next1 && line2 < next2 &&
+ match(map, line1, line2)) {
+ line1++;
+ line2++;
+ }
+
+ /* Recurse */
+ if (next1 > line1 || next2 > line2) {
+ struct hashmap submap;
+
+ memset(&submap, 0, sizeof(submap));
+ if (patience_diff(map->file1, map->file2,
+ map->xpp, map->env,
+ line1, next1 - line1,
+ line2, next2 - line2))
+ return -1;
+ }
+
+ if (!first)
+ return 0;
+
+ while (first->next &&
+ first->next->line1 == first->line1 + 1 &&
+ first->next->line2 == first->line2 + 1)
+ first = first->next;
+
+ line1 = first->line1 + 1;
+ line2 = first->line2 + 1;
+
+ first = first->next;
+ }
+}
+
+static int fall_back_to_classic_diff(struct hashmap *map,
+ int line1, int count1, int line2, int count2)
+{
+ /*
+ * This probably does not work outside Git, since
+ * we have a very simple mmfile structure.
+ *
+ * Note: ideally, we would reuse the prepared environment, but
+ * the libxdiff interface does not (yet) allow for diffing only
+ * ranges of lines instead of the whole files.
+ */
+ mmfile_t subfile1, subfile2;
+ xpparam_t xpp;
+ xdfenv_t env;
+
+ subfile1.ptr = (char *)map->env->xdf1.recs[line1 - 1]->ptr;
+ subfile1.size = map->env->xdf1.recs[line1 + count1 - 2]->ptr +
+ map->env->xdf1.recs[line1 + count1 - 2]->size - subfile1.ptr;
+ subfile2.ptr = (char *)map->env->xdf2.recs[line2 - 1]->ptr;
+ subfile2.size = map->env->xdf2.recs[line2 + count2 - 2]->ptr +
+ map->env->xdf2.recs[line2 + count2 - 2]->size - subfile2.ptr;
+ xpp.flags = map->xpp->flags & ~XDF_PATIENCE_DIFF;
+ if (xdl_do_diff(&subfile1, &subfile2, &xpp, &env) < 0)
+ return -1;
+
+ memcpy(map->env->xdf1.rchg + line1 - 1, env.xdf1.rchg, count1);
+ memcpy(map->env->xdf2.rchg + line2 - 1, env.xdf2.rchg, count2);
+
+ xdl_free_env(&env);
+
+ return 0;
+}
+
+/*
+ * Recursively find the longest common sequence of unique lines,
+ * and if none was found, ask xdl_do_diff() to do the job.
+ *
+ * This function assumes that env was prepared with xdl_prepare_env().
+ */
+static int patience_diff(mmfile_t *file1, mmfile_t *file2,
+ xpparam_t const *xpp, xdfenv_t *env,
+ int line1, int count1, int line2, int count2)
+{
+ struct hashmap map;
+ struct entry *first;
+ int result = 0;
+
+ /* trivial case: one side is empty */
+ if (!count1) {
+ while(count2--)
+ env->xdf2.rchg[line2++ - 1] = 1;
+ return 0;
+ } else if (!count2) {
+ while(count1--)
+ env->xdf1.rchg[line1++ - 1] = 1;
+ return 0;
+ }
+
+ memset(&map, 0, sizeof(map));
+ if (fill_hashmap(file1, file2, xpp, env, &map,
+ line1, count1, line2, count2))
+ return -1;
+
+ /* are there any matching lines at all? */
+ if (!map.has_matches) {
+ while(count1--)
+ env->xdf1.rchg[line1++ - 1] = 1;
+ while(count2--)
+ env->xdf2.rchg[line2++ - 1] = 1;
+ xdl_free(map.entries);
+ return 0;
+ }
+
+ first = find_longest_common_sequence(&map);
+ if (first)
+ result = walk_common_sequence(&map, first,
+ line1, count1, line2, count2);
+ else
+ result = fall_back_to_classic_diff(&map,
+ line1, count1, line2, count2);
+
+ xdl_free(map.entries);
+ return result;
+}
+
+int xdl_do_patience_diff(mmfile_t *file1, mmfile_t *file2,
+ xpparam_t const *xpp, xdfenv_t *env)
+{
+ if (xdl_prepare_env(file1, file2, xpp, env) < 0)
+ return -1;
+
+ /* environment is cleaned up in xdl_diff() */
+ return patience_diff(file1, file2, xpp, env,
+ 1, env->xdf1.nrec, 1, env->xdf2.nrec);
+}
diff --git a/xdiff/xprepare.c b/xdiff/xprepare.c
index a43aa72..1689085 100644
--- a/xdiff/xprepare.c
+++ b/xdiff/xprepare.c
@@ -290,7 +290,8 @@ int xdl_prepare_env(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
xdl_free_classifier(&cf);
- if (xdl_optimize_ctxs(&xe->xdf1, &xe->xdf2) < 0) {
+ if (!(xpp->flags & XDF_PATIENCE_DIFF) &&
+ xdl_optimize_ctxs(&xe->xdf1, &xe->xdf2) < 0) {
xdl_free_ctx(&xe->xdf2);
xdl_free_ctx(&xe->xdf1);
--
1.6.0.2.GIT
^ permalink raw reply related
* Re: Error: unable to unlink ... when using "git gc"
From: Sitaram Chamarty @ 2009-01-07 18:00 UTC (permalink / raw)
To: git
In-Reply-To: <200901070948.34117.bss@iguanasuicide.net>
On 2009-01-07, Boyd Stephen Smith Jr. <bss@iguanasuicide.net> wrote:
> On Wednesday 2009 January 07 04:55:56 you wrote:
>> So when you say "group", you're saying "0660", and when you
>> say "0660", you're overriding users umask value.
> it could just have been the version of git I was using (1.4.4.4, IIRC) --=20
> still using that in at least one place, as it is the current version in=20
> Debian Etch.
1.4.4.4 is 2 years and 2 days old today! [I've heard
stories about Debian, but never thought it was this
conservative!]
and I think this was fixed in 06cbe85, last April.
^ permalink raw reply
* Re: [PATCH] gitweb: support the rel=vcs microformat
From: Giuseppe Bilotta @ 2009-01-07 18:03 UTC (permalink / raw)
To: Joey Hess; +Cc: git
In-Reply-To: <20090107155023.GA16540@gnu.kitenet.net>
On Wed, Jan 7, 2009 at 4:50 PM, Joey Hess <joey@kitenet.net> wrote:
> Giuseppe Bilotta wrote:
>> In this patch you do NOT add titles to the rel=vcs links, which means that
>> everything works fine only if there is a single URL for each project. If a
>> project has different URLs, it's going to appear multiple times as _different_
>> projects to a spec-compliant reader.
>>
>> A possible solution would be to make @git_url_list into a map keyed by the
>> project name and having the description and repo URL(s) as values.
>
> Yes. I considered doing that, but didn't immediatly see a way to get the
> project description w/o additional overhead (of looking it up a second
> time).
The solution I have in mind would be something like this: in summary
or projects list view (which are the views in which we put the links,
and also the views in which we loop up the repo URL and the
description anyway), you fill up former @git_url_list (now
%project_metadata) looking up the repo description and URLs. You then
use this information both in the link tag and in the appropriate
places for the visible part of the webpage: you don't have a
significant overhead, because you're just moving the project
description retrieval early on.
You probably want to refactor the code by making a
git_get_project_metadata() sub that extends the current URL retrieval
by retrieving description and URLs. The routine can then be used
either for one or for all the projects, as needed.
> Thanks for the feedback. There are some changes happening to the
> microformat that should make gitweb's job slightly easier, I'll respin
> the patch soon.
Let me know about this too, I very much like the idea of this microformat.
--
Giuseppe "Oblomov" Bilotta
^ permalink raw reply
* Re: [PATCH v3 1/3] Implement the patience diff algorithm
From: Davide Libenzi @ 2009-01-07 18:10 UTC (permalink / raw)
To: Johannes Schindelin
Cc: Pierre Habouzit, Linus Torvalds, Francis Galiegue, Git ML
In-Reply-To: <alpine.DEB.1.00.0901071802190.7496@intel-tinevez-2-302>
On Wed, 7 Jan 2009, Johannes Schindelin wrote:
>
> The patience diff algorithm produces slightly more intuitive output
> than the classic Myers algorithm, as it does not try to minimize the
> number of +/- lines first, but tries to preserve the lines that are
> unique.
Johannes, sorry I had not time to follow this one. A couple of minor
comments that arose just at glancing at the patch.
> +/*
> + * LibXDiff by Davide Libenzi ( File Differential Library )
> + * Copyright (C) 2003-2009 Davide Libenzi, Johannes E. Schindelin
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * This library is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this library; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
> + *
> + * Davide Libenzi <davidel@xmailserver.org>
You do not need to give me credit for something I don't even know how it
works ;)
> +static int fall_back_to_classic_diff(struct hashmap *map,
> + int line1, int count1, int line2, int count2)
> +{
> + /*
> + * This probably does not work outside Git, since
> + * we have a very simple mmfile structure.
> + *
> + * Note: ideally, we would reuse the prepared environment, but
> + * the libxdiff interface does not (yet) allow for diffing only
> + * ranges of lines instead of the whole files.
> + */
> + mmfile_t subfile1, subfile2;
> + xpparam_t xpp;
> + xdfenv_t env;
> +
> + subfile1.ptr = (char *)map->env->xdf1.recs[line1 - 1]->ptr;
> + subfile1.size = map->env->xdf1.recs[line1 + count1 - 2]->ptr +
> + map->env->xdf1.recs[line1 + count1 - 2]->size - subfile1.ptr;
> + subfile2.ptr = (char *)map->env->xdf2.recs[line2 - 1]->ptr;
> + subfile2.size = map->env->xdf2.recs[line2 + count2 - 2]->ptr +
> + map->env->xdf2.recs[line2 + count2 - 2]->size - subfile2.ptr;
> + xpp.flags = map->xpp->flags & ~XDF_PATIENCE_DIFF;
> + if (xdl_do_diff(&subfile1, &subfile2, &xpp, &env) < 0)
> + return -1;
xdiff allows for diffing ranges, and the most efficent method is exactly
how you did ;) Once you know the lines pointers, there's no need to pass
it the whole file and have it scan it whole to find the lines range it has
to diff. Just pass the limited view like you did.
- Davide
^ permalink raw reply
* Re: Problems getting rid of large files using git-filter-branch
From: Sitaram Chamarty @ 2009-01-07 18:18 UTC (permalink / raw)
To: git
In-Reply-To: <alpine.DEB.1.00.0901071101480.7496@intel-tinevez-2-302>
On 2009-01-07, Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:
>> $ git verify-pack -v
>> .git/objects/pack/pack-1e039b82d8ae53ef5ec3614a3021466663cc70a4
>> Terminated
>
> I did
>
> $ git grep Terminated
>
> and came up empty :-)
It comes from libc, afaik.
^ permalink raw reply
* Google Summer of Code 2009
From: Shawn O. Pearce @ 2009-01-07 18:30 UTC (permalink / raw)
To: git
Google just pre-announced that Summer of Code 2009 will run. Its
going to be a bit smaller than last year's program due to the poor
worldwide economic climate, but the open source community is quite
fortunate that Google is footing the bill for yet another summer of
students hacking on open source projects.
Given our success last year, I think we should try applying again
this year as a mentoring organization. I've started to put the
wiki pages together by cloning last year's stuff:
Organization application:
http://git.or.cz/gitwiki/SoC2009Application
Organization ideas page:
http://git.or.cz/gitwiki/SoC2009Ideas
FWIW, the folks who organize GSoC thought our ideas page is among
the better ones they've seen year-after-year. So I'm largely
keeping the same format. :-)
The application answers really need to be reworked; we need to
address our 2008 results in these parts.
The ideas box is once again open for suggestions. Please start
proposing student projects, and possible mentors.
Since the program is smaller, there is a chance we won't be accepted
this year due to space constraints. But I think its still worthwhile
to prepare everything and hope for the best. And before you can
ask, no, my employee status with OSPO doesn't improve our odds
for acceptance. :-)
--
Shawn.
^ permalink raw reply
* Re: [PATCH v3 1/3] Implement the patience diff algorithm
From: Johannes Schindelin @ 2009-01-07 18:32 UTC (permalink / raw)
To: Davide Libenzi; +Cc: Pierre Habouzit, Linus Torvalds, Francis Galiegue, Git ML
In-Reply-To: <alpine.DEB.1.10.0901071001360.16651@alien.or.mcafeemobile.com>
Hi,
On Wed, 7 Jan 2009, Davide Libenzi wrote:
> On Wed, 7 Jan 2009, Johannes Schindelin wrote:
>
> > The patience diff algorithm produces slightly more intuitive output
> > than the classic Myers algorithm, as it does not try to minimize the
> > number of +/- lines first, but tries to preserve the lines that are
> > unique.
>
> Johannes, sorry I had not time to follow this one.
What? You mean you actually took some time off around Christmas???
:-)
> A couple of minor comments that arose just at glancing at the patch.
Thanks.
> > +/*
> > + * LibXDiff by Davide Libenzi ( File Differential Library )
> > + * Copyright (C) 2003-2009 Davide Libenzi, Johannes E. Schindelin
> > + *
> > + * This library is free software; you can redistribute it and/or
> > + * modify it under the terms of the GNU Lesser General Public
> > + * License as published by the Free Software Foundation; either
> > + * version 2.1 of the License, or (at your option) any later version.
> > + *
> > + * This library is distributed in the hope that it will be useful,
> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> > + * Lesser General Public License for more details.
> > + *
> > + * You should have received a copy of the GNU Lesser General Public
> > + * License along with this library; if not, write to the Free Software
> > + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
> > + *
> > + * Davide Libenzi <davidel@xmailserver.org>
>
> You do not need to give me credit for something I don't even know how it
> works ;)
Well, I meant to pass the copyright to you, or at least share it.
> > +static int fall_back_to_classic_diff(struct hashmap *map,
> > + int line1, int count1, int line2, int count2)
> > +{
> > + /*
> > + * This probably does not work outside Git, since
> > + * we have a very simple mmfile structure.
> > + *
> > + * Note: ideally, we would reuse the prepared environment, but
> > + * the libxdiff interface does not (yet) allow for diffing only
> > + * ranges of lines instead of the whole files.
> > + */
> > + mmfile_t subfile1, subfile2;
> > + xpparam_t xpp;
> > + xdfenv_t env;
> > +
> > + subfile1.ptr = (char *)map->env->xdf1.recs[line1 - 1]->ptr;
> > + subfile1.size = map->env->xdf1.recs[line1 + count1 - 2]->ptr +
> > + map->env->xdf1.recs[line1 + count1 - 2]->size - subfile1.ptr;
> > + subfile2.ptr = (char *)map->env->xdf2.recs[line2 - 1]->ptr;
> > + subfile2.size = map->env->xdf2.recs[line2 + count2 - 2]->ptr +
> > + map->env->xdf2.recs[line2 + count2 - 2]->size - subfile2.ptr;
> > + xpp.flags = map->xpp->flags & ~XDF_PATIENCE_DIFF;
> > + if (xdl_do_diff(&subfile1, &subfile2, &xpp, &env) < 0)
> > + return -1;
>
> xdiff allows for diffing ranges, and the most efficent method is exactly
> how you did ;) Once you know the lines pointers, there's no need to pass
> it the whole file and have it scan it whole to find the lines range it
> has to diff. Just pass the limited view like you did.
Heh.
Could it be that you misread my patch, and assumed that I faked an
xdfenv?
I did not, but instead faked two mmfiles, which is only as simple as I did
it because in git.git, we only have contiguous mmfiles. (I recall that
libxdiff allows for ropes instead of arrays.)
The way I did it has one big shortcoming: I need to prepare an xdfenv for
the subfiles even if I already prepared one for the complete files. IOW
the lines are rehashed all over again.
Ciao,
Dscho
^ permalink raw reply
* Re: [PATCH] gitweb: support the rel=vcs microformat
From: Joey Hess @ 2009-01-07 18:41 UTC (permalink / raw)
To: Giuseppe Bilotta; +Cc: git
In-Reply-To: <cb7bb73a0901071003m77482a99wf6f3988beb5b5e78@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 748 bytes --]
Giuseppe Bilotta wrote:
> > Thanks for the feedback. There are some changes happening to the
> > microformat that should make gitweb's job slightly easier, I'll respin
> > the patch soon.
>
> Let me know about this too, I very much like the idea of this microformat.
FYI, I've updated the microformat's page with the changes. The
significant one for gitweb is that it can now be applied to <a> links.
So on the project page, the display of the git URL could be converted to
a link using the microformat, and there's no need to get the info
earlier to put it in the header. Unfortunatly, the same can't be done to
the project list page, unless it's changed to have "git" links as seen
on vger.kernel.org's gitweb.
--
see shy jo
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* Re: [PATCH] gitweb: support the rel=vcs microformat
From: Joey Hess @ 2009-01-07 18:45 UTC (permalink / raw)
To: Giuseppe Bilotta; +Cc: git
In-Reply-To: <cb7bb73a0901071003m77482a99wf6f3988beb5b5e78@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 976 bytes --]
Giuseppe Bilotta wrote:
> The solution I have in mind would be something like this: in summary
> or projects list view (which are the views in which we put the links,
> and also the views in which we loop up the repo URL and the
> description anyway), you fill up former @git_url_list (now
> %project_metadata) looking up the repo description and URLs. You then
> use this information both in the link tag and in the appropriate
> places for the visible part of the webpage: you don't have a
> significant overhead, because you're just moving the project
> description retrieval early on.
>
> You probably want to refactor the code by making a
> git_get_project_metadata() sub that extends the current URL retrieval
> by retrieving description and URLs. The routine can then be used
> either for one or for all the projects, as needed.
Another approach would be to just memoize git_get_project_description
and git_get_project_url_list.
--
see shy jo
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* Re: [PATCH v3 1/3] Implement the patience diff algorithm
From: Linus Torvalds @ 2009-01-07 18:59 UTC (permalink / raw)
To: Davide Libenzi
Cc: Johannes Schindelin, Pierre Habouzit, Francis Galiegue, Git ML
In-Reply-To: <alpine.DEB.1.10.0901071001360.16651@alien.or.mcafeemobile.com>
On Wed, 7 Jan 2009, Davide Libenzi wrote:
>
> xdiff allows for diffing ranges, and the most efficent method is exactly
> how you did ;)
No, the performance problem is how it needs to re-hash everything. xdiff
doesn't seem to have any way to use a "subset of the hash", so what the
patience diff does is to use a subset of the mmfile, and then that will
force all the rehashing to take place, which is kind of sad.
It would be nice (for patience diff) if it could partition the _hashes_
instead of partitioning the _data_. That way it wouldn't need to rehash.
See?
Linus
^ permalink raw reply
* Re: [PATCH] gitweb: support the rel=vcs microformat
From: Joey Hess @ 2009-01-07 19:02 UTC (permalink / raw)
To: Giuseppe Bilotta; +Cc: git
In-Reply-To: <20090107184515.GB31795@gnu.kitenet.net>
[-- Attachment #1: Type: text/plain, Size: 241 bytes --]
Joey Hess wrote:
> Another approach would be to just memoize git_get_project_description
> and git_get_project_url_list.
Especially since git_get_project_description is already called more than
once for some pages.
--
see shy jo
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* Re: Error: unable to unlink ... when using "git gc"
From: Boyd Stephen Smith Jr. @ 2009-01-07 19:46 UTC (permalink / raw)
To: Sitaram Chamarty; +Cc: git
In-Reply-To: <slrngm9rdm.gcv.sitaramc@sitaramc.homelinux.net>
[-- Attachment #1: Type: text/plain, Size: 1691 bytes --]
On Wednesday 2009 January 07 12:00:22 Sitaram Chamarty wrote:
> On 2009-01-07, Boyd Stephen Smith Jr. <bss@iguanasuicide.net> wrote:
> > On Wednesday 2009 January 07 04:55:56 you wrote:
> >> So when you say "group", you're saying "0660", and when you
> >> say "0660", you're overriding users umask value.
> >
> > it could just have been the version of git I was using (1.4.4.4, IIRC)
> > -- still using that in at least one place, as it is the current
> > version in Debian Etch.
>
> 1.4.4.4 is 2 years and 2 days old today! [I've heard
> stories about Debian, but never thought it was this
> conservative!]
Once a stable is released, no new versions of packages come in, only
backported bug and security fixes. The pre-release freeze also limits new
versions from being considered. Lenny should be out RSN, so I can move up to
1.5.6.5. :)
$ apt-cache policy git-core
git-core:
Installed: 1:1.4.4.4-4
Candidate: 1:1.4.4.4-4
Version table:
1:1.6.0.6-1 0
300 http://localhost experimental/main Packages
1:1.5.6.5-2 0
700 http://localhost testing/main Packages
500 http://localhost unstable/main Packages
1:1.5.6.5-1~bpo40+1 0
800 http://localhost etch-backports/main Packages
*** 1:1.4.4.4-4 0
900 http://localhost stable/main Packages
100 /var/lib/dpkg/status
1:1.4.4.4-2.1+etch1 0
900 http://localhost stable/updates/main Packages
--
Boyd Stephen Smith Jr. ,= ,-_-. =.
bss@iguanasuicide.net ((_/)o o(\_))
ICQ: 514984 YM/AIM: DaTwinkDaddy `-'(. .)`-'
http://iguanasuicide.net/ \_/
[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 197 bytes --]
^ 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