* Re: [PATCH 3/3] diff --stat: sometimes use non-linear scaling.
From: Junio C Hamano @ 2006-09-27 6:19 UTC (permalink / raw)
To: David Rientjes; +Cc: git
In-Reply-To: <Pine.LNX.4.64N.0609262216390.12560@attu2.cs.washington.edu>
David Rientjes <rientjes@cs.washington.edu> writes:
> When I read "x > 0", my mind parses that very easily. When I read "0 <
> x", it takes me a few cycles longer. I think the goal of any software
> project is to not only emit efficient and quality code, but also code that
> can be read and deciphered with ease unless it's impossible otherwise.
Well, the thing is, I end up being the guy who needs to stare at
git code longer than you do ;-).
Before --stat-width was introduced there was code like this:
if (max + len > 70)
max = 70 - len;
Here "len" is the width of the filename part, and "max" is the
number of changes we need to express. The code is saying "if we
use one column for each changed line, does graph and name exceed
70 columns -- if so use the remainder of the line after we write
name for the graph". Your "constant at right" rule makes this
kosher.
If we make that to a variable, say line_width, we can still
write:
if (max + len > line_width)
...
I however tend to think "if line_width cannot fit (max + len)
then we do this", which would be more naturally expressed with:
if (line_width < max + len)
...
Now, at this point, it is really the matter of taste and there
is no real reason to prefer one over the other. Textual
ordering lets my eyes coast while reading the code without
taxing the brain. I can see that the expression compares two
quantities, "line_width" and "max + len", and the boolean holds
true if line_width _comes_ _before_ "max + len" on the number
line (having number line in your head helps visualizing what is
compared with what). If you write the comparison the wrong way,
it forces me to stop and think -- because on my number line
smaller numbers appear left, and cannot help me reading the
comparison written in "a > b" order.
I could try writing constants on the right hand side when
constants are involved, but I do not think it makes much sense.
It means that I would end up doing:
- if (max + len > 70)
- max = 70 - len;
+ if (line_width < max + len)
+ max = line_width - len;
Consistency counts not only while reading the finished code, but
also it helps reviewing the diff between the earlier version
that used constant (hence forced to have it on the right hand
side by your rule) and the version that made it into a variable.
> To change the code itself because of a hard 80-column limit or because
> you're tired of hitting the tab key is poor style.
Well, the program _firstly_ matches the logic flow better, and
_in_ _addition_ if you write it another way it becomes
unnecessarily too deeply indented. So while I agree with you as a
general principle that indentation depth should not dictate how
we code it does not apply to this particular example.
^ permalink raw reply
* Re: [PATCH] gitweb: tree view: eliminate redundant "blob"
From: Junio C Hamano @ 2006-09-27 6:42 UTC (permalink / raw)
To: ltuikov; +Cc: git, Jakub Narebski
In-Reply-To: <20060926213236.79160.qmail@web31815.mail.mud.yahoo.com>
Luben Tuikov <ltuikov@yahoo.com> writes:
>> And "invisible links" _especially_ if the link is not convenience only
>> (i.e. it is not provided clearly as link somewhere else) is so called
>> "mystery meat navigation" and is one of the most common mistakes in
>> web development.
>>
>> And is not as if "plain |" takes much space...
>
> I think you would agree that gitweb is quite different than what is
> commonly defined as "mystery meat navigation".
>
> Gitweb is very well thought out interface, and self-contained.
> There isn't much pondering about what and where to click, have newbies
> too.
>
> Think about the removal of the redundant "blob" and "tree" as database
> schema normalization if you will.
>...
> Either that or you can think of it as "shortening" the line.
Very well put. I think this and removal of redundant "tree"
would be worthy changes -- it unclutters things.
If the only objection is that it is harder to realize that the
remaining one (the other one that did not get removed by this
redundancy elimination) is clickable, maybe that is what needs
to be fixed.
^ permalink raw reply
* Re: [PATCH] gitweb: tree view: hash_base and hash are now context sensitive
From: Junio C Hamano @ 2006-09-27 6:48 UTC (permalink / raw)
To: Jakub Narebski; +Cc: git, ltuikov
In-Reply-To: <20060926211720.21355.qmail@web31808.mail.mud.yahoo.com>
Luben Tuikov <ltuikov@yahoo.com> writes:
> --- Jakub Narebski <jnareb@gmail.com> wrote:
>> I think that this need some thinking over. For blob we have two
>> "base" objects: tree which have specified blob, and commit which
>> have tree which have specified blob. We might want to specify
>> that all hash*base are to the commit-ish.
>
> Agreed, we should always refer to the commit-ish, for obvious
> reasons.
>
> This patch doesn't make this decision though. It simply
> sets hash_base to HEAD if not defined.
>
> Now, since "git-ls-tree" works on both commit-ish and
> tree-ish, we are ok.
I think so, too. Jakub?
^ permalink raw reply
* Re: [PATCH 3/3] diff --stat: sometimes use non-linear scaling.
From: David Rientjes @ 2006-09-27 6:49 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7vejtxhlv6.fsf@assigned-by-dhcp.cox.net>
On Tue, 26 Sep 2006, Junio C Hamano wrote:
> Well, the thing is, I end up being the guy who needs to stare at
> git code longer than you do ;-).
>
Really? This is the only community that hacks git? There _are_ people
out there that make their own changes specifically tailored to their
purposes or that of their organization.
> Before --stat-width was introduced there was code like this:
>
> if (max + len > 70)
> max = 70 - len;
>
> Here "len" is the width of the filename part, and "max" is the
> number of changes we need to express. The code is saying "if we
> use one column for each changed line, does graph and name exceed
> 70 columns -- if so use the remainder of the line after we write
> name for the graph". Your "constant at right" rule makes this
> kosher.
>
> If we make that to a variable, say line_width, we can still
> write:
>
> if (max + len > line_width)
> ...
>
> I however tend to think "if line_width cannot fit (max + len)
> then we do this", which would be more naturally expressed with:
>
> if (line_width < max + len)
> ...
>
First of all, it's not my "constant at right" rule, it's a preference that
the _majority_ of computer programmers have used in virtually every
language that you see source code for.
The grammar for C is
relational-expression:
shift-expression
relational-expression < shift-expression
in this case. Now while this supports both your variations above, it
_suggests_ that the higher degree of computation is associated on the left
side because the less-than operator associates that way.
What happens here:
a < b < c
it turns out that this is equivalent to:
(a < b) < c
so if you want your entire code base to conform to a particular style,
it's _preferable_ to place the constant on the right. And that's what the
majority of programmers do. Your taste is in the minority and out of
respect to the code base you should make your code conform to what is most
popular in the surrounding code.
Your argument of saying to yourself "if line_width cannot fit max + len
then we do this" has no relevance at all. I can say "if max + len is too
big for line_width we do this" just the same.
If we're going by what sounds better in your head, then I expect _no_
argument when I write a function called conseguir_la_linea_longitud
instead of get_line_length because Spanish is my first language.
Please respect what the majority of computer programmers write and unify
the code base so that it's a similar style everywhere.
> > To change the code itself because of a hard 80-column limit or because
> > you're tired of hitting the tab key is poor style.
>
> Well, the program _firstly_ matches the logic flow better, and
> _in_ _addition_ if you write it another way it becomes
> unnecessarily too deeply indented. So while I agree with you as a
> general principle that indentation depth should not dictate how
> we code it does not apply to this particular example.
>
This is a ridiculous argument. The C code will emit the exact same
assembly regardless of how you write it. You say that you wrote it that
way to avoid idents which is an absolutely horrible way to dictate the
code you use. There are tons of opportunities where you can write cryptic
source code that functions great with the least number of tokens and least
number of lines to get the job done in every large project. But, given
that there are no assembler or performance tradeoffs, it should be written
as clearly and nicely as possible for the reader. I assert again what I
did previously: if that if clause runs the length of my screen the indents
will help me later to remember we're still in a conditional. That's the
SOLE purpose of indents: to make it easy for the reader to tell you're
inside a block.
And in one of your patches you had:
if (...)
;
else {
...
}
without any other if statements. If you're supporting that type of code,
I'll simply consider this entire thread a lost cause.
David
^ permalink raw reply
* Re: [PATCH 3/3] diff --stat: sometimes use non-linear scaling.
From: Junio C Hamano @ 2006-09-27 7:05 UTC (permalink / raw)
To: David Rientjes; +Cc: git
In-Reply-To: <Pine.LNX.4.64N.0609262320260.9088@attu4.cs.washington.edu>
David Rientjes <rientjes@cs.washington.edu> writes:
> Your argument of saying to yourself "if line_width cannot fit max + len
> then we do this" has no relevance at all. I can say "if max + len is too
> big for line_width we do this" just the same.
Actually that is exactly my point. "Just the same". There is
no reason to choose one way or the other from purely logical or
mathematical point of view.
Comparisons written always in textual order, when one gets used
to, takes less thinking to parse and understand, and that is
what I'm used to. Have number line handy in your head and you
will hopefully like it too ;-).
>> Well, the program _firstly_ matches the logic flow better, and
>> _in_ _addition_ if you write it another way it becomes
>> unnecessarily too deeply indented. So while I agree with you as a
>> general principle that indentation depth should not dictate how
>> we code it does not apply to this particular example.
>
> This is a ridiculous argument. The C code will emit the exact same
> assembly regardless of how you write it. You say that you wrote it that
> way to avoid idents which is an absolutely horrible way to dictate the
> code you use.
I guess probably I was unclear (I did not talk anything about
code generation -- where did it come from?). I say I wrote it
that way _firstly_ because the flow of the program matches
exactly what I saw the code needed to do -- if A I do not have
to do anything else if B I do this else I do that. In addition
not having that "do nothing" made the code indent unnecessarily
deep but that is "in addition" and not the primary cause. It
was an added bonus.
> And in one of your patches you had:
> if (...)
> ;
> else {
> ...
> }
>
> without any other if statements.
Yes, indeed that was very funny looking.
It was refactored from the final one that had "else if" in the
middle (else if was to add the non-linear scaling). I agree
that any sane would not have done that if that was the real
first version.
^ permalink raw reply
* Re: [PATCH 3/3] diff --stat: sometimes use non-linear scaling.
From: David Rientjes @ 2006-09-27 7:19 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7vfyedg56m.fsf@assigned-by-dhcp.cox.net>
On Wed, 27 Sep 2006, Junio C Hamano wrote:
> David Rientjes <rientjes@cs.washington.edu> writes:
>
> > Your argument of saying to yourself "if line_width cannot fit max + len
> > then we do this" has no relevance at all. I can say "if max + len is too
> > big for line_width we do this" just the same.
>
> Actually that is exactly my point. "Just the same". There is
> no reason to choose one way or the other from purely logical or
> mathematical point of view.
>
Nothing about this is "mathematical" at all and I never claimed it was.
But there _is_ a reason to choose one way over the other and that is
because the MAJORITY of programmers do it one way and YOU do it another
way. Why is it so hard to write all the code in the same style so that
there is as little variation in the code as possible?
> Comparisons written always in textual order, when one gets used
> to, takes less thinking to parse and understand, and that is
> what I'm used to. Have number line handy in your head and you
> will hopefully like it too ;-).
>
Doing what you prefer and not what the majority of your developers do is
the first step to a stagnant source tree.
> >> Well, the program _firstly_ matches the logic flow better, and
> >> _in_ _addition_ if you write it another way it becomes
> >> unnecessarily too deeply indented. So while I agree with you as a
> >> general principle that indentation depth should not dictate how
> >> we code it does not apply to this particular example.
> >
> > This is a ridiculous argument. The C code will emit the exact same
> > assembly regardless of how you write it. You say that you wrote it that
> > way to avoid idents which is an absolutely horrible way to dictate the
> > code you use.
>
> I guess probably I was unclear (I did not talk anything about
> code generation -- where did it come from?). I say I wrote it
> that way _firstly_ because the flow of the program matches
> exactly what I saw the code needed to do -- if A I do not have
> to do anything else if B I do this else I do that. In addition
> not having that "do nothing" made the code indent unnecessarily
> deep but that is "in addition" and not the primary cause. It
> was an added bonus.
>
The concept of code generation is the whole point. Both of our styles
emits the same assembly code so by definition there is no difference since
it achieves the exact same goal. But there's a reason git is written in C
and not in assembly and that reason is not just for portability. A
.c source file is the bridge between most programmers and assembly and
since our coding styles differ but emit the same assembly, then it
inherently comes with a freedom in how it's written. And on a
collaborative project such as git, that freedom should be confined to
resembling the surrounding source code.
David
^ permalink raw reply
* Re: [PATCH 3/3] update a few Porcelain-ish for ref lock safety.
From: Junio C Hamano @ 2006-09-27 7:25 UTC (permalink / raw)
To: Andy Whitcroft; +Cc: git
In-Reply-To: <45196CAB.6030903@shadowen.org>
Andy Whitcroft <apw@shadowen.org> writes:
>> +prev=0000000000000000000000000000000000000000
>
> It seems a little odd to need to use such a large 'none' thing. Will
> linus' updates start returning this when there is no tag? If so then it
> makes sense. Else perhaps it would be nice to have a short cut for it.
> Such as 'none'.
True. It probably is better to accept something shorter, like
an empty string, or token "none". But this is a plumbing
command, and I was not too concerned about having to say 40 "0"
in the Porcelain scripts.
^ permalink raw reply
* Re: [PATCH 3/3] diff --stat: sometimes use non-linear scaling.
From: Johannes Schindelin @ 2006-09-27 7:36 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, Jan Engelhardt, Linus Torvalds, Adrian Bunk
In-Reply-To: <7vfyeejakq.fsf@assigned-by-dhcp.cox.net>
Hi,
On Tue, 26 Sep 2006, Junio C Hamano wrote:
> When some files have big changes and others are touched only
> slightly, diffstat graph did not show differences among smaller
> changes that well. This changes the graph scaling to non-linear
> algorithm in such a case.
I want to say something about the purpose of the patch, not some totally
unimportant superficialities.
In your example, a three line change has more than three plusses, and I
find that wrong.
But I would actually find another change very useful: still linear, but
such that if lines were added, at least one plus should be shown, and
likewise with minus. (Often I ask myself, was this file removed, or just
dramatically reduced, when I only see minusses).
Ciao,
Dscho
^ permalink raw reply
* Re: [PATCH 3/3] diff --stat: sometimes use non-linear scaling.
From: Johannes Schindelin @ 2006-09-27 7:50 UTC (permalink / raw)
To: David Rientjes; +Cc: Junio C Hamano, git
In-Reply-To: <Pine.LNX.4.64N.0609270006020.9602@attu4.cs.washington.edu>
Hi,
On Wed, 27 Sep 2006, David Rientjes wrote:
> On Wed, 27 Sep 2006, Junio C Hamano wrote:
>
> > David Rientjes <rientjes@cs.washington.edu> writes:
> >
> > > Your argument of saying to yourself "if line_width cannot fit max + len
> > > then we do this" has no relevance at all. I can say "if max + len is too
> > > big for line_width we do this" just the same.
> >
> > Actually that is exactly my point. "Just the same". There is
> > no reason to choose one way or the other from purely logical or
> > mathematical point of view.
> >
>
> Nothing about this is "mathematical" at all and I never claimed it was.
> But there _is_ a reason to choose one way over the other and that is
> because the MAJORITY of programmers do it one way and YOU do it another
> way. Why is it so hard to write all the code in the same style so that
> there is as little variation in the code as possible?
Could you stop it already?
Git's source code is very clean and readable, even if there are inversions
you might not be used to.
Besides, always doing it the same way is boring. _Boring_. Or do you make
love to your girl-friend the same way over and over again?
Ciao,
Dscho
^ permalink raw reply
* [RFC] git-split: Split the history of a git repository by subdirectories and ranges
From: Josh Triplett @ 2006-09-27 8:05 UTC (permalink / raw)
To: git; +Cc: Jamey Sharp
[-- Attachment #1.1: Type: text/plain, Size: 1334 bytes --]
Hello,
I co-maintain the X C Binding (XCB) project with Jamey Sharp.
Previously, several XCB-related projects all existed under the umbrella
of a single monolithic GIT repository with per-project subdirectories.
We have split this repository into individual per-project repositories.
Jamey Sharp and I wrote a script called git-split to accomplish this
repository split. git-split reconstructs the history of a sub-project
previously stored in a subdirectory of a larger repository. It
constructs new commit objects based on the existing tree objects for the
subtree in each commit, and discards commits which do not affect the
history of the sub-project, as well as merges made unnecessary due to
these discarded commits. When git-split finishes, it will output the
sha1 for the new head commit, suitable for redirection into a file in
.git/refs/heads. At that point, you can clone the new head, or copy the
repository and prune out undesired heads, tags, and objects.
I have attached git-split for review. If the GIT community has any
interest in seeing git-split become a part of GIT, we can write up the
necessary documentation and patch.
We would like to acknowledge the work of the gobby team in creating a
collaborative editor which greatly aided the development of git-split.
- Josh Triplett
[-- Attachment #1.2: git-split --]
[-- Type: text/plain, Size: 4980 bytes --]
#!/usr/bin/python
# git-split: Split the history of a git repository by subdirectories and ranges
# Copyright (C) 2006 Jamey Sharp, Josh Triplett
#
# You can redistribute this software and/or modify it under the terms of
# the GNU General Public License as published by the Free Software
# Foundation; version 2 dated June, 1991.
#
# This program 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
# General Public License for more details.
from itertools import izip
from subprocess import Popen, PIPE
import os, sys
def run(cmd, stdin=None, env={}):
newenv = os.environ.copy()
newenv.update(env)
return Popen(cmd, stdin=PIPE, stdout=PIPE, env=newenv).communicate(stdin)[0]
def parse_author_date(s):
"""Given a GIT author or committer string, return (name, email, date)"""
(name, email, time, timezone) = s.rsplit(None, 3)
return (name, email[1:-1], time + " " + timezone)
def get_subtree(tree, name):
output = run(["git-ls-tree", tree, name])
if not output:
return None
return output.split()[2]
def is_ancestor(new_commits, cur, other):
"""Return True if cur has other as an ancestor, or False otherwise."""
return run(["git-merge-base", cur, other]).strip() == other
def walk(commits, new_commits, commit_hash, project):
commit = commits[commit_hash]
if not(commit.has_key("new_hash")):
tree = get_subtree(commit["tree"], project)
commit["new_tree"] = tree
if not tree:
raise Exception("Did not find project in tree for commit " + commit_hash)
new_parents = list(set([walk(commits, new_commits, parent, project)
for parent in commit["parents"]]))
new_hash = None
if len(new_parents) == 1:
new_hash = new_parents[0]
elif len(new_parents) == 2: # Check for unnecessary merge
if is_ancestor(new_commits, new_parents[0], new_parents[1]):
new_hash = new_parents[0]
elif is_ancestor(new_commits, new_parents[1], new_parents[0]):
new_hash = new_parents[1]
if new_hash and new_commits[new_hash]["new_tree"] != tree:
new_hash = None
if not new_hash:
args = ["git-commit-tree", tree]
for new_parent in new_parents:
args.extend(["-p", new_parent])
env = dict(zip(["GIT_AUTHOR_"+n for n in ["NAME", "EMAIL", "DATE"]],
parse_author_date(commit["author"]))
+zip(["GIT_COMMITTER_"+n for n in ["NAME", "EMAIL", "DATE"]],
parse_author_date(commit["committer"])))
new_hash = run(args, commit["message"], env).strip()
commit["new_parents"] = new_parents
commit["new_hash"] = new_hash
if new_hash not in new_commits:
new_commits[new_hash] = commit
return commit["new_hash"]
def main(args):
if not(1 <= len(args) <= 3):
print "Usage: git-split subdir [newest [oldest]]"
return 1
project = args[0]
if len(args) > 1:
newest = args[1]
else:
newest = "HEAD"
newest_hash = run(["git-rev-parse", newest]).strip()
if len(args) > 2:
oldest = args[2]
oldest_hash = run(["git-rev-parse", oldest]).strip()
else:
oldest_hash = None
grafts = {}
try:
for line in file(".git/info/grafts").read().split("\n"):
if line:
child, parents = line.split(None, 1)
parents = parents.split()
grafts[child] = parents
except IOError:
pass
temp = run(["git-log", "--pretty=raw", newest_hash]).split("\n\n")
commits = {}
for headers,message in izip(temp[0::2], temp[1::2]):
commit = {}
commit_hash = None
headers = [header.split(None, 1) for header in headers.split("\n")]
for key,value in headers:
if key == "parent":
commit.setdefault("parents", []).append(value)
elif key == "commit":
commit_hash = value
else:
if key in commit:
raise Exception('Duplicate key "%s"' % key)
commit[key] = value
commit["message"] = "".join([line[4:]+"\n"
for line in message.split("\n")])
if commit_hash is None:
raise Exception("Commit without hash")
if commit_hash in grafts:
commit["parents"] = grafts[commit_hash]
if commit_hash == oldest_hash or "parents" not in commit:
commit["parents"] = []
commits[commit_hash] = commit
print walk(commits, dict(), newest_hash, project)
try:
import psyco
psyco.full()
except ImportError:
pass
if __name__ == "__main__": sys.exit(main(sys.argv[1:]))
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 252 bytes --]
^ permalink raw reply
* Re: Notes on Using Git with Subprojects
From: Martin Waitz @ 2006-09-27 8:06 UTC (permalink / raw)
To: A Large Angry SCM; +Cc: Shawn Pearce, Daniel Barkalow, git
In-Reply-To: <4519AACD.7020508@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 2526 bytes --]
hoi :)
On Tue, Sep 26, 2006 at 03:33:49PM -0700, A Large Angry SCM wrote:
> So, for each subproject of a parent project, you want to record branch,
> version (commit ID), and directory location. Not quite as easy to do in
> a makefile but do-able.
I've been playing with this kind of subprojects a little bit.
My current approach is like this:
* create a .gitmodules file which lists all the directories
which contain a submodule.
* the .git/refs/heads directory of the submodule gets stored in
.gitmodule/<modulename> inside the parent project
* both things above should be tracked in the parent project.
This way you always store the current state of each submodule
in each commit of the parent project. And you don't have to
create a new parent commit for each change. You can commit
to the parent project when you think that all your modules are
in a good state.
* When checking out a project, all submodules listen in .gitmodules
get checked out, too.
* If there is a merge conflict in the module list or its refs/heads,
this is handled specially, e.g. by triggering a new merge inside
the submodule.
* The object directory is shared between the parent and all modules.
To make fsck-objects happy, the parent gets a refs/module link
pointing to .gitmodule/ and all submodules get a refs/parent
link pointing to the refs directory of the parent.
The concept is similiar to the gitlink objects which have been floating
around, but it is easier to prototype as no new git object type has to
be created. If it works well we can later move the information stored
in .gitmodule* into an object type of its own.
By storing the complete refs/heads directory for each submodule instead
of only one head, it is possible to track multiple branches of a
subproject. I'm don't know yet how this works out in praktice but I
think that it can be nice to be able to atomically commit to several
branches of one submodule (perhaps one branch per customer, per
hardware platform, whatever).
So, what have I done up to now? Not much. I created a little
script to set up a submodule as described above:
http://git.admingilde.org/?p=tali/git.git;a=blob;f=git-init-module.sh;h=0108873fd3aa8a42035039b19e8555513c075fca;hb=module
Next steps would be to modify clone and checkout to actually be able
to work in such a setup. If this works then merging of subprojects
has to be done (the most complex part I guess).
--
Martin Waitz
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* Re: [PATCH 3/3] diff --stat: sometimes use non-linear scaling.
From: Johannes Schindelin @ 2006-09-27 8:35 UTC (permalink / raw)
To: Sean; +Cc: David Rientjes, Junio C Hamano, git
In-Reply-To: <BAYC1-PASMTP024D1DA4730F9DF93F857FAE1A0@CEZ.ICE>
Hi,
On Wed, 27 Sep 2006, Sean wrote:
> On Wed, 27 Sep 2006 09:50:11 +0200 (CEST)
> Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:
>
> > Could you stop it already?
>
> Well i'd like to offer some support for David.
>
> In English you'd never say "if 10 is less than the number of girls"
> you'd always say "if the number of girls is greater than 10".
>
> Why on earth would you ever write C code different than the way you'd
> express the same question in natural language? Maybe this is only common
> in English and other languages are different; that would explain why this
> seems more natural to some.
In this case, though, "English" is utterly, totally irrelevant. The
question is a mathematical one, and thus, the solution is a mathematical
one.
So, in essence, if you do not understand a conditional with a constant on
the left side, just because it happens to honour the mathematical view of
"left is small, right is large", you do not stand a chance of
understanding the formula, right?
> > Git's source code is very clean and readable, even if there are inversions
> > you might not be used to.
>
> Not to me. I find it very annoying to have to figure out what
> "if ( 10 < x ) ..." is really trying to do.
Oh, come on! You cannot possibly spend even _seconds_ on this particular
construct!
'nough said.
Ciao,
Dscho
^ permalink raw reply
* Re: [PATCH 3/3] diff --stat: sometimes use non-linear scaling.
From: Sean @ 2006-09-27 8:41 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: David Rientjes, Junio C Hamano, git
In-Reply-To: <Pine.LNX.4.63.0609271030180.14200@wbgn013.biozentrum.uni-wuerzburg.de>
On Wed, 27 Sep 2006 10:35:16 +0200 (CEST)
Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:
> In this case, though, "English" is utterly, totally irrelevant. The
> question is a mathematical one, and thus, the solution is a mathematical
> one.
Well, no.. At least for me, I "think" in english, not mathematics. And
thus I have to understand each condition in my native language. And i'm
being honest with you when I tell you that my parser hiccups every time
I see such a construct.
> So, in essence, if you do not understand a conditional with a constant on
> the left side, just because it happens to honour the mathematical view of
> "left is small, right is large", you do not stand a chance of
> understanding the formula, right?
It's not a matter of being able to understand, it's being able to digest
at a glance, almost without a thought as opposed to consciously having
to rearrange the arguments into something that "feels" right.
> Oh, come on! You cannot possibly spend even _seconds_ on this particular
> construct!
>
> 'nough said.
I'm telling you that it is disconcerting and annoying to have to rejig such
a construct. Whereas when expressed in the opposite format it makes reading
simple and natural. Making the code easier and more pleasurable to read.
And if you find it so easy to read either way, then why not bend for those
of us who have trouble reading it your way instead of just telling us to get
stuffed?
Sean
^ permalink raw reply
* Re: git and time
From: Andreas Ericsson @ 2006-09-27 8:42 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Matthew L Foster, git, Jeff King, Jakub Narebski
In-Reply-To: <7vodt2nmft.fsf@assigned-by-dhcp.cox.net>
Junio C Hamano wrote:
> Matthew L Foster <mfoster167@yahoo.com> writes:
>
>>> PS Nit: Git doesn't work with changesets, it works with snapshots,
>>> building a directed graph of snapshots. Maybe that is the source of your
>>> confusion
>> It's true I don't know much about git, what is the difference
>> between a changeset and a snapshot? Are you saying timestamps
>> should be tracked separately or tracked by an scm system built
>> on top of git? Does/should git care about the when of a
>> snapshot?
>
> I do not know what Jeff meant by snapshot vs changeset, so I
> would not comment on this part.
>
Me neither, but I've seen this distinction before on the mailing-list.
To my mind, a changeset is the patch that brings some form of data from
one state (snapshot) to another. In this respect, git is certainly both
snapshot- and changeset-based.
--
Andreas Ericsson andreas.ericsson@op5.se
OP5 AB www.op5.se
Tel: +46 8-230225 Fax: +46 8-230231
^ permalink raw reply
* Re: [PATCH 3/3] diff --stat: sometimes use non-linear scaling.
From: Martin Waitz @ 2006-09-27 9:16 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, Jan Engelhardt, Linus Torvalds, Adrian Bunk
In-Reply-To: <7vfyeejakq.fsf@assigned-by-dhcp.cox.net>
[-- Attachment #1: Type: text/plain, Size: 789 bytes --]
hoi :)
On Tue, Sep 26, 2006 at 07:40:53PM -0700, Junio C Hamano wrote:
> .gitignore | 1
> Documentation/git-tar-tree.txt | 3 +++++++++
> Documentation/git-upload-tar.txt | 39 -----------------------------
> Documentation/git.txt | 4 -----------
> Makefile | 1
> builtin-tar-tree.c | 130 +++++++++++++++-----------------------
> builtin-upload-tar.c | 74 ----------------------------------
> git.c | 1
> 8 files changed, 53 insertions(+), 200 deletions(-)
hmm, the small changes (1 line) are still not shown :-(.
I like the idea of non-linear display, but we have to fine-tune the
algorithm a little bit more.
--
Martin Waitz
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* Re: [PATCH] perl bindings fix compilation errors
From: Johannes Schindelin @ 2006-09-27 9:42 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Andy Whitcroft, git
In-Reply-To: <7vwt7qjal5.fsf@assigned-by-dhcp.cox.net>
Hi,
On Tue, 26 Sep 2006, Junio C Hamano wrote:
> The worst part is that the version bisect suggests that does not
> have Git.xs may be a version in the past -- which we obviously
> cannot apply your patch to.
Okay, just forget about my patch.
Ciao,
Dscho
^ permalink raw reply
* Re: Notes on Using Git with Subprojects
From: Johannes Schindelin @ 2006-09-27 9:55 UTC (permalink / raw)
To: Martin Waitz; +Cc: A Large Angry SCM, Shawn Pearce, Daniel Barkalow, git
In-Reply-To: <20060927080652.GA8056@admingilde.org>
Hi,
On Wed, 27 Sep 2006, Martin Waitz wrote:
> On Tue, Sep 26, 2006 at 03:33:49PM -0700, A Large Angry SCM wrote:
> > So, for each subproject of a parent project, you want to record branch,
> > version (commit ID), and directory location. Not quite as easy to do in
> > a makefile but do-able.
>
> I've been playing with this kind of subprojects a little bit.
>
> My current approach is like this:
>
> * create a .gitmodules file which lists all the directories
> which contain a submodule.
> * the .git/refs/heads directory of the submodule gets stored in
> .gitmodule/<modulename> inside the parent project
Taking this a step further, you could make subproject/.git/refs/heads a
symbolic link to .git/refs/heads/subproject, with the benefit that fsck
Just Works.
Nevertheless, you have to take care of the fact that you need to commit
the state of the root project just after committing to any subproject.
Ciao,
Dscho
^ permalink raw reply
* Re: [RFC] git-split: Split the history of a git repository by subdirectories and ranges
From: Junio C Hamano @ 2006-09-27 10:13 UTC (permalink / raw)
To: Josh Triplett; +Cc: git
In-Reply-To: <451A30E4.50801@freedesktop.org>
Josh Triplett <josh@freedesktop.org> writes:
> Jamey Sharp and I wrote a script called git-split to accomplish this
> repository split. git-split reconstructs the history of a sub-project
> previously stored in a subdirectory of a larger repository. It
> constructs new commit objects based on the existing tree objects for the
> subtree in each commit, and discards commits which do not affect the
> history of the sub-project, as well as merges made unnecessary due to
> these discarded commits.
Very nicely done.
> We would like to acknowledge the work of the gobby team in creating a
> collaborative editor which greatly aided the development of git-split.
> from itertools import izip
> from subprocess import Popen, PIPE
> import os, sys
How recent a Python are we assuming here? Is late 2.4 recent
enough?
> def walk(commits, new_commits, commit_hash, project):
> commit = commits[commit_hash]
> if not(commit.has_key("new_hash")):
> tree = get_subtree(commit["tree"], project)
> commit["new_tree"] = tree
> if not tree:
> raise Exception("Did not find project in tree for commit " + commit_hash)
> new_parents = list(set([walk(commits, new_commits, parent, project)
> for parent in commit["parents"]]))
>
> new_hash = None
> if len(new_parents) == 1:
> new_hash = new_parents[0]
> elif len(new_parents) == 2: # Check for unnecessary merge
> if is_ancestor(new_commits, new_parents[0], new_parents[1]):
> new_hash = new_parents[0]
> elif is_ancestor(new_commits, new_parents[1], new_parents[0]):
> new_hash = new_parents[1]
> if new_hash and new_commits[new_hash]["new_tree"] != tree:
> new_hash = None
This is a real gem. I really like reading well-written Python
programs.
When git-rev-list (or "git-log --pretty=raw" that you use in
your main()) simplifies the merge history based on subtree, we
look at the merge and if the tree matches any of the parent we
discard other parents and make the history a single strand of
pearls. However for this application that is not what you want,
so I can see why you run full "git-log" and prune history by
hand here like this.
I wonder if using "git-log --full-history -- $project" to let
the core side omit commits that do not change the $project (but
still give you all merged branches) would have made your job any
easier?
You are handling grafts by hand because --pretty=raw is special
in that it displays the real parents (although traversal does
use grafts). Maybe it would have helped if we had a --pretty
format that is similar to raw but rewrites the parents?
^ permalink raw reply
* Re: git and time
From: Junio C Hamano @ 2006-09-27 10:13 UTC (permalink / raw)
To: Shawn Pearce; +Cc: git
In-Reply-To: <20060927042850.GB9460@spearce.org>
Shawn Pearce <spearce@spearce.org> writes:
> However people are ignoring the fact that receive-pack doesn't
> update the reflog. As of current `next` its *still* doing the ref
> updates by hand, rather than going through the common library code
> in refs.c.
This is unfortunately on top of many things, but judging from
the number of deleted lines and added lines, I think it is going
in the right direction.
One thing that makes "the common library code" less useful is
that lock_ref_sha1() and its cousin lock_any_ref_for_update() do
not let the caller to tell why a ref could not be locked ("did
it not exist? did the old_sha1 not match?" and in
lock_ref_sha1()'s case "did the ref have funny characters?").
-- >8 --
[PATCH] Teach receive-pack about ref-log
This converts receive-pack to use the standard ref locking code
instead of its own. As a side effect, it automatically records
the "push" event to ref-log if enabled.
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
receive-pack.c | 88 ++++++++++----------------------------------------------
1 files changed, 15 insertions(+), 73 deletions(-)
diff --git a/receive-pack.c b/receive-pack.c
index abbcb6a..f0b4cb4 100644
--- a/receive-pack.c
+++ b/receive-pack.c
@@ -41,34 +41,6 @@ struct command {
static struct command *commands;
-static int is_all_zeroes(const char *hex)
-{
- int i;
- for (i = 0; i < 40; i++)
- if (*hex++ != '0')
- return 0;
- return 1;
-}
-
-static int verify_old_ref(const char *name, char *hex_contents)
-{
- int fd, ret;
- char buffer[60];
-
- if (is_all_zeroes(hex_contents))
- return 0;
- fd = open(name, O_RDONLY);
- if (fd < 0)
- return -1;
- ret = read(fd, buffer, 40);
- close(fd);
- if (ret != 40)
- return -1;
- if (memcmp(buffer, hex_contents, 40))
- return -1;
- return 0;
-}
-
static char update_hook[] = "hooks/update";
static int run_update_hook(const char *refname,
@@ -105,8 +77,8 @@ static int update(struct command *cmd)
const char *name = cmd->ref_name;
unsigned char *old_sha1 = cmd->old_sha1;
unsigned char *new_sha1 = cmd->new_sha1;
- char new_hex[60], *old_hex, *lock_name;
- int newfd, namelen, written;
+ char new_hex[41], old_hex[41];
+ struct ref_lock *lock;
cmd->error_string = NULL;
if (!strncmp(name, "refs/", 5) && check_ref_format(name + 5)) {
@@ -115,59 +87,27 @@ static int update(struct command *cmd)
name);
}
- namelen = strlen(name);
- lock_name = xmalloc(namelen + 10);
- memcpy(lock_name, name, namelen);
- memcpy(lock_name + namelen, ".lock", 6);
-
strcpy(new_hex, sha1_to_hex(new_sha1));
- old_hex = sha1_to_hex(old_sha1);
+ strcpy(old_hex, sha1_to_hex(old_sha1));
if (!has_sha1_file(new_sha1)) {
cmd->error_string = "bad pack";
return error("unpack should have generated %s, "
"but I can't find it!", new_hex);
}
- safe_create_leading_directories(lock_name);
-
- newfd = open(lock_name, O_CREAT | O_EXCL | O_WRONLY, 0666);
- if (newfd < 0) {
- cmd->error_string = "can't lock";
- return error("unable to create %s (%s)",
- lock_name, strerror(errno));
- }
-
- /* Write the ref with an ending '\n' */
- new_hex[40] = '\n';
- new_hex[41] = 0;
- written = write(newfd, new_hex, 41);
- /* Remove the '\n' again */
- new_hex[40] = 0;
-
- close(newfd);
- if (written != 41) {
- unlink(lock_name);
- cmd->error_string = "can't write";
- return error("unable to write %s", lock_name);
- }
- if (verify_old_ref(name, old_hex) < 0) {
- unlink(lock_name);
- cmd->error_string = "raced";
- return error("%s changed during push", name);
- }
if (run_update_hook(name, old_hex, new_hex)) {
- unlink(lock_name);
cmd->error_string = "hook declined";
return error("hook declined to update %s", name);
}
- else if (rename(lock_name, name) < 0) {
- unlink(lock_name);
- cmd->error_string = "can't rename";
- return error("unable to replace %s", name);
- }
- else {
- fprintf(stderr, "%s: %s -> %s\n", name, old_hex, new_hex);
- return 0;
+
+ lock = lock_any_ref_for_update(name, old_sha1);
+ if (!lock) {
+ cmd->error_string = "failed to lock";
+ return error("failed to lock %s", name);
}
+ write_ref_sha1(lock, new_sha1, "push");
+
+ fprintf(stderr, "%s: %s -> %s\n", name, old_hex, new_hex);
+ return 0;
}
static char update_post_hook[] = "hooks/post-update";
@@ -318,9 +258,11 @@ int main(int argc, char **argv)
if (!dir)
usage(receive_pack_usage);
- if(!enter_repo(dir, 0))
+ if (!enter_repo(dir, 0))
die("'%s': unable to chdir or not a git archive", dir);
+ git_config(git_default_config);
+
write_head_info();
/* EOF */
--
1.4.2.1.gf80a
^ permalink raw reply related
* [PATCH] runstatus: do not recurse into subdirectories if not needed
From: Johannes Schindelin @ 2006-09-27 11:16 UTC (permalink / raw)
To: git, junkio
This speeds up the case when you run git-status, having an untracked
subdirectory containing huge amounts of files.
It also clarifies the handling of hide_empty_directories; the old version
worked, but was hard to understand.
Signed-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
---
dir.c | 24 +++++++++++++++---------
1 files changed, 15 insertions(+), 9 deletions(-)
diff --git a/dir.c b/dir.c
index e2f472b..e69663c 100644
--- a/dir.c
+++ b/dir.c
@@ -274,6 +274,15 @@ static int dir_exists(const char *dirnam
return !strncmp(active_cache[pos]->name, dirname, len);
}
+static int dir_is_empty(const char *dirname)
+{
+ DIR *fdir = opendir(dirname);
+ int result = (readdir(fdir) == NULL);
+
+ closedir(fdir);
+ return result;
+}
+
/*
* Read a directory tree. We currently ignore anything but
* directories, regular files and symlinks. That's because git
@@ -314,7 +323,6 @@ static int read_directory_recursive(stru
switch (DTYPE(de)) {
struct stat st;
- int subdir, rewind_base;
default:
continue;
case DT_UNKNOWN:
@@ -328,18 +336,16 @@ static int read_directory_recursive(stru
case DT_DIR:
memcpy(fullname + baselen + len, "/", 2);
len++;
- rewind_base = dir->nr;
- subdir = read_directory_recursive(dir, fullname, fullname,
- baselen + len);
if (dir->show_other_directories &&
- (subdir || !dir->hide_empty_directories) &&
!dir_exists(fullname, baselen + len)) {
- /* Rewind the read subdirectory */
- while (dir->nr > rewind_base)
- free(dir->entries[--dir->nr]);
+ if (dir->hide_empty_directories &&
+ dir_is_empty(fullname))
+ continue;
break;
}
- contents += subdir;
+
+ contents += read_directory_recursive(dir,
+ fullname, fullname, baselen + len);
continue;
case DT_REG:
case DT_LNK:
--
1.4.2.1.g78cd-dirty
^ permalink raw reply related
* Re: Notes on Using Git with Subprojects
From: Martin Waitz @ 2006-09-27 11:38 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: A Large Angry SCM, Shawn Pearce, Daniel Barkalow, git
In-Reply-To: <Pine.LNX.4.63.0609271152270.14200@wbgn013.biozentrum.uni-wuerzburg.de>
[-- Attachment #1: Type: text/plain, Size: 967 bytes --]
hoi :)
On Wed, Sep 27, 2006 at 11:55:22AM +0200, Johannes Schindelin wrote:
> > My current approach is like this:
> >
> > * create a .gitmodules file which lists all the directories
> > which contain a submodule.
> > * the .git/refs/heads directory of the submodule gets stored in
> > .gitmodule/<modulename> inside the parent project
>
> Taking this a step further, you could make subproject/.git/refs/heads a
> symbolic link to .git/refs/heads/subproject, with the benefit that fsck
> Just Works.
in fact it is done this way (more or less).
> Nevertheless, you have to take care of the fact that you need to commit
> the state of the root project just after committing to any subproject.
why?
You can accumulate as many changes in different subprojects until you
get to a state that is worth committing in the parent project.
All these changes are then seen as one atomic change to the whole
project.
--
Martin Waitz
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* Re: [RFC] git-split: Split the history of a git repository by subdirectories and ranges
From: Andy Whitcroft @ 2006-09-27 11:59 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Josh Triplett, git
In-Reply-To: <7vlko5d3bx.fsf@assigned-by-dhcp.cox.net>
Junio C Hamano wrote:
> Josh Triplett <josh@freedesktop.org> writes:
>
>> Jamey Sharp and I wrote a script called git-split to accomplish this
>> repository split. git-split reconstructs the history of a sub-project
>> previously stored in a subdirectory of a larger repository. It
>> constructs new commit objects based on the existing tree objects for the
>> subtree in each commit, and discards commits which do not affect the
>> history of the sub-project, as well as merges made unnecessary due to
>> these discarded commits.
>
> Very nicely done.
>
>> We would like to acknowledge the work of the gobby team in creating a
>> collaborative editor which greatly aided the development of git-split.
>
>> from itertools import izip
>> from subprocess import Popen, PIPE
>> import os, sys
>
> How recent a Python are we assuming here? Is late 2.4 recent
> enough?
>
>> def walk(commits, new_commits, commit_hash, project):
>> commit = commits[commit_hash]
>> if not(commit.has_key("new_hash")):
>> tree = get_subtree(commit["tree"], project)
>> commit["new_tree"] = tree
>> if not tree:
>> raise Exception("Did not find project in tree for commit " + commit_hash)
>> new_parents = list(set([walk(commits, new_commits, parent, project)
>> for parent in commit["parents"]]))
>>
>> new_hash = None
>> if len(new_parents) == 1:
>> new_hash = new_parents[0]
>> elif len(new_parents) == 2: # Check for unnecessary merge
>> if is_ancestor(new_commits, new_parents[0], new_parents[1]):
>> new_hash = new_parents[0]
>> elif is_ancestor(new_commits, new_parents[1], new_parents[0]):
>> new_hash = new_parents[1]
>> if new_hash and new_commits[new_hash]["new_tree"] != tree:
>> new_hash = None
>
> This is a real gem. I really like reading well-written Python
> programs.
>
> When git-rev-list (or "git-log --pretty=raw" that you use in
> your main()) simplifies the merge history based on subtree, we
> look at the merge and if the tree matches any of the parent we
> discard other parents and make the history a single strand of
> pearls. However for this application that is not what you want,
> so I can see why you run full "git-log" and prune history by
> hand here like this.
>
> I wonder if using "git-log --full-history -- $project" to let
> the core side omit commits that do not change the $project (but
> still give you all merged branches) would have made your job any
> easier?
>
> You are handling grafts by hand because --pretty=raw is special
> in that it displays the real parents (although traversal does
> use grafts). Maybe it would have helped if we had a --pretty
> format that is similar to raw but rewrites the parents?
I have wondered recently why grafts are hidden in this way. I feel they
are something I want to know is occuring in my history as this history
is being manipulated. Perhaps we could emit a graft record in the
output, indeed have a graft object there? Someone could commit a
change, then graft over it in the history so I'd not see it even though
its in my working copy.
For instance in my historical git tree I have the following, note the
lack of a parent. If I move the graft up one commit, then I get a
parent, but not a parent that points at the next commit.
commit 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2
tree 0bba044c4ce775e45a88a51686b5d9f90697ea9d
author Linus Torvalds <torvalds@ppc970.osdl.org> 1113690036 -0700
committer Linus Torvalds <torvalds@ppc970.osdl.org> 1113690036 -0700
[...]
commit e7e173af42dbf37b1d946f9ee00219cb3b2bea6a
tree 0bba044c4ce775e45a88a51686b5d9f90697ea9d
parent 607899e17218b485a021c6ebb1cff771fd690eec
author Linus Torvalds <torvalds@ppc970.osdl.org> 1112580513 -0700
committer Linus Torvalds <torvalds@ppc970.osdl.org> 1112580513 -0700
It might be nice to have it more like the following, with a graft in
there, N*40 would obviously be fakes in the first instance as the object
isn't modified. M*40 would refer to the old parent if there was one,
else NONE or 0*40 perhaps.
commit 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2
tree 0bba044c4ce775e45a88a51686b5d9f90697ea9d
parent NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
author Linus Torvalds <torvalds@ppc970.osdl.org> 1113690036 -0700
committer Linus Torvalds <torvalds@ppc970.osdl.org> 1113690036 -0700
[...]
graft NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
parent e7e173af42dbf37b1d946f9ee00219cb3b2bea6a
OLD: MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
commit e7e173af42dbf37b1d946f9ee00219cb3b2bea6a
tree 0bba044c4ce775e45a88a51686b5d9f90697ea9d
parent 607899e17218b485a021c6ebb1cff771fd690eec
author Linus Torvalds <torvalds@ppc970.osdl.org> 1112580513 -0700
committer Linus Torvalds <torvalds@ppc970.osdl.org> 1112580513 -0700
I guess the other option would be to annotate the previous commit,
perhaps on the parent line so we can see the 'right' data in the normal
place, but the overridden data is right there and grepable.
parent e7e173af42dbf37b1d946f9ee00219cb3b2bea6a GRAFT M*40
or
parent e7e173af42dbf37b1d946f9ee00219cb3b2bea6a GRAFT NONE
-apw
^ permalink raw reply
* Re: Notes on Using Git with Subprojects
From: Johannes Schindelin @ 2006-09-27 12:01 UTC (permalink / raw)
To: Martin Waitz; +Cc: A Large Angry SCM, Shawn Pearce, Daniel Barkalow, git
In-Reply-To: <20060927113813.GC8056@admingilde.org>
Hi.
On Wed, 27 Sep 2006, Martin Waitz wrote:
> On Wed, Sep 27, 2006 at 11:55:22AM +0200, Johannes Schindelin wrote:
> > > My current approach is like this:
> > >
> > > * create a .gitmodules file which lists all the directories
> > > which contain a submodule.
> > > * the .git/refs/heads directory of the submodule gets stored in
> > > .gitmodule/<modulename> inside the parent project
> >
> > Taking this a step further, you could make subproject/.git/refs/heads a
> > symbolic link to .git/refs/heads/subproject, with the benefit that fsck
> > Just Works.
>
> in fact it is done this way (more or less).
With the difference, that if you store the refs outside of
<root>/.git/refs, you have to take extra care that prune does not delete
the corresponding objects.
> > Nevertheless, you have to take care of the fact that you need to commit
> > the state of the root project just after committing to any subproject.
>
> why?
>
> You can accumulate as many changes in different subprojects until you
> get to a state that is worth committing in the parent project.
> All these changes are then seen as one atomic change to the whole
> project.
AFAICT this is not the idea of subprojects-in-git. If you have to track
the subprojects in the root project manually anyway, you don't need _any_
additional tool (you _can_ track files in a subdirectory containing a .git
subdirectory).
Ciao,
Dscho
^ permalink raw reply
* Re: Notes on Using Git with Subprojects
From: Sven Verdoolaege @ 2006-09-27 12:44 UTC (permalink / raw)
To: Johannes Schindelin
Cc: Martin Waitz, A Large Angry SCM, Shawn Pearce, Daniel Barkalow,
git
In-Reply-To: <Pine.LNX.4.63.0609271358100.14200@wbgn013.biozentrum.uni-wuerzburg.de>
On Wed, Sep 27, 2006 at 02:01:11PM +0200, Johannes Schindelin wrote:
> On Wed, 27 Sep 2006, Martin Waitz wrote:
> > On Wed, Sep 27, 2006 at 11:55:22AM +0200, Johannes Schindelin wrote:
> > > Nevertheless, you have to take care of the fact that you need to commit
> > > the state of the root project just after committing to any subproject.
So what happens if you pull some changes into a subproject?
Are you going to create a commit in the root project for each
intermediate commit that you pulled into your subproject?
If no, then why should you do so if you happen to do these change
in your local repo?
> AFAICT this is not the idea of subprojects-in-git.
As already pointed out by Daniel, there is no such thing as
"the idea of subprojects-in-git". There are many ideas of
subprojects-in-git.
I, for one, would want to commit the changed state of a subproject
to the superproject explicitly.
> If you have to track
> the subprojects in the root project manually anyway, you don't need _any_
> additional tool (you _can_ track files in a subdirectory containing a .git
> subdirectory).
If I switch to a different branch or bisect in the superproject,
then the states of the subprojects should be changed accordingly.
skimo
^ permalink raw reply
* Re: Notes on Using Git with Subprojects
From: Martin Waitz @ 2006-09-27 12:46 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: A Large Angry SCM, Shawn Pearce, Daniel Barkalow, git
In-Reply-To: <Pine.LNX.4.63.0609271358100.14200@wbgn013.biozentrum.uni-wuerzburg.de>
[-- Attachment #1: Type: text/plain, Size: 1914 bytes --]
hoi :)
On Wed, Sep 27, 2006 at 02:01:11PM +0200, Johannes Schindelin wrote:
> On Wed, 27 Sep 2006, Martin Waitz wrote:
> > On Wed, Sep 27, 2006 at 11:55:22AM +0200, Johannes Schindelin wrote:
> > > > My current approach is like this:
> > > >
> > > > * create a .gitmodules file which lists all the directories
> > > > which contain a submodule.
> > > > * the .git/refs/heads directory of the submodule gets stored in
> > > > .gitmodule/<modulename> inside the parent project
> > >
> > > Taking this a step further, you could make subproject/.git/refs/heads a
> > > symbolic link to .git/refs/heads/subproject, with the benefit that fsck
> > > Just Works.
> >
> > in fact it is done this way (more or less).
>
> With the difference, that if you store the refs outside of
> <root>/.git/refs, you have to take extra care that prune does not delete
> the corresponding objects.
that's why there is .git/refs/module/modulname -> .gitmodule/modulename.
> > You can accumulate as many changes in different subprojects until you
> > get to a state that is worth committing in the parent project.
> > All these changes are then seen as one atomic change to the whole
> > project.
>
> AFAICT this is not the idea of subprojects-in-git. If you have to track
> the subprojects in the root project manually anyway, you don't need _any_
> additional tool (you _can_ track files in a subdirectory containing a .git
> subdirectory).
But then you loose the fine grained commits of your subprojects.
You only store the tree of the subproject when committing to the parent,
not the entire history.
I think having the "commit subproject changes to parent" step as a
manual action makes sense in the same way as you have to trigger a
commit to a repository by hand, too. You are not storing every little
change to your filesystem in the database.
--
Martin Waitz
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 189 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