* Re: Clean up sha1 file writing
From: Linus Torvalds @ 2006-05-24 18:52 UTC (permalink / raw)
To: Matthias Lederhofer; +Cc: Git Mailing List
In-Reply-To: <E1Fixs4-0005pD-10@moooo.ath.cx>
On Wed, 24 May 2006, Matthias Lederhofer wrote:
> > checking for partial writes
>
> Just out of interest: is this to be safe on any OS or should this
> be checked always?
Any POSIX-conformant OS/filesystem should always do a full write for a
regular file, unless a serious error happens.
HOWEVER.
In practice, you can get partial writes at least over NFS (hey, it may not
be posix, but it's _common_) when the filesystem has been mounted soft
(and/or interruptible). And obviously if your file descriptor isn't a
regular file, you can easily get partial writes.
Doing the loop is always safe, so it's worth doing it that way.
> > + size = write(fd, buf, len);
> > + if (!size)
> > + return error("file write: disk full");
>
> Shouldn't write to a full disk return -1 with ENOSPC?
In that case, the "size < 0" check will catch it. The "return zero for
full" case is an alternate error return (it happens for block device files
at the end, it could happen for other things too). So the "returns zero
means full" is the portable/safe thing to do.
Linus
^ permalink raw reply
* Re: Slow fetches of tags
From: Junio C Hamano @ 2006-05-24 19:06 UTC (permalink / raw)
To: Linus Torvalds; +Cc: git, Ralf Baechle
In-Reply-To: <Pine.LNX.4.64.0605240947580.5623@g5.osdl.org>
Linus Torvalds <torvalds@osdl.org> writes:
> Junio? Any ideas? I didn't want to do that tag-auto-following, and while I
> admit it's damn convenient, it's really quite broken, methinks.
I think the current setup is broken on two counts. If you fetch
without remote tracking branch, I suspect that we end up asking
for the tip of the remote again -- because there is no ref that
says "this commit is known to be complete -- we just fetched
from them successfully".
But I think what Ralf is seeing is a bit different. The example
given:
git fetch git://git.kernel.org/pub/scm/linux/kernel/git/stable/\
linux-2.6.16.y.git master:v2.6.16-stable
does use a tracking branch, and when the tag following kicks in,
v2.6.16-stable head should have been updated. I suspect it is
just its head commit is older than tips of other branches, and
purely date based sorting done by fetch-pack.c::get_rev() ends
up walking them before it gets to the tip of the branch we just
fetched.
I wonder if we can do a dirty hack to give bias to commits
coming from refs that are newer (on the local filesystem -- that
is, mtime of .git/refs/heads/v2.6.16-stable must be a lot newer
than .git/refs/heads/master in this case because we just fetched
it)...
^ permalink raw reply
* Re: [PATCH 0/2] tagsize < 8kb restriction
From: Björn Engelmann @ 2006-05-24 19:16 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7vzmh81gfa.fsf@assigned-by-dhcp.cox.net>
>> 2.) Searching for a way to add objects to the database I spent quite a
>> while to find the right command. Don't you think it would be much more
>> intuitive having an
>>
>> git-create-object [-t <type>] [-n] [-f] [-z] [--stdin] <file> [-r
>> <ref-name>]
>>
>> command for creating any type of object (-t blob as default).
>>
>
> No, I do not think we would want to make it too easy and relaxed
> to create arbitrary object-looking thing. Each type have
> defined format and semantics, and creation of an object of each
> type should be validated. I do not want to encourage bypassing
> it by introducing such a backdoor. The backdoor is easy to
> write, but I suspect it would actively harm us, instead of
> helping us, by encouraging "let's build a custom type of object,
> we do not care if other people would not understand it"
> mentality.
>
Well, this is exactly what you have now in
git-hash-object -w -t foo
That is why I said, all input should be validated by default. All I
proposed was
a) unify the tools in order to have less duplicate code (git-mktag,
git-mktree & git-hash-object do merely the same except for the
validating part)
b) remove the possibility to introduce unchecked objects of arbitrary
type (or only allow it with the -f = "force, use with caution"-option)
maybe I should have written "blob, tag, tree or commit" instead of
"arbitrary". I did not mean really arbitrary like it is implemented
right now in git-hash-object.
Bj
^ permalink raw reply
* Re: Slow fetches of tags
From: Linus Torvalds @ 2006-05-24 19:17 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Ralf Baechle, Git Mailing List
In-Reply-To: <7v64jv8fdx.fsf@assigned-by-dhcp.cox.net>
On Wed, 24 May 2006, Junio C Hamano wrote:
>
> A "have" object is not just has_sha1_file(), but it needs to be
> reachable from one of our tips we have already verified as
> complete
You're right.
And the strange part is that the commit we should give for the tag thing
_should_ actually be pretty recent, and I wonder why we end up walking the
whole damn tree history and saying "want" to basically them all.
IOW, I think there's something more fundamentally wrong with the tag
following. We _should_ have figured out much more quickly that we have it
all.
I'm starting to suspect that it's actually a tag-specific problem: we do
that reachability crud all by commit history, so the tags are a total
special case, and if we don't send the proper HAVE/WANT for those or mark
them properly with THEY_HAVE/COMMON etc, maybe the algorithm just gets
confused.
I need to go pick up my youngest, so I'll be off-line on this for a while.
Will try to think it through.
Linus
^ permalink raw reply
* Re: [PATCH 0/2] tagsize < 8kb restriction
From: Junio C Hamano @ 2006-05-24 19:39 UTC (permalink / raw)
To: Björn Engelmann; +Cc: git
In-Reply-To: <4474B10A.1020704@gmx.de>
Björn Engelmann <BjEngelmann@gmx.de> writes:
> That is why I said, all input should be validated by default. All I
> proposed was
> a) unify the tools in order to have less duplicate code
> (git-mktag, git-mktree & git-hash-object do merely the same
> except for the validating part)
> b) remove the possibility to introduce unchecked objects of arbitrary
> type (or only allow it with the -f = "force, use with caution"-option)
> maybe I should have written "blob, tag, tree or commit" instead of
> "arbitrary". I did not mean really arbitrary like it is implemented
> right now in git-hash-object.
Sorry, I forgot all about hash-objects X-<. It was a convenient
way to try out new things such as 'gitlink'. Thanks for the
clarification.
As to unification, I am not sure if there are a lot to unify.
Everybody starts with type, length and a LF, but after that each
type has its own format constraints. A grand unified command
that knows about format constraints of every type under the sun
does not sound like a good approach. While we have only handful
types (and I expect things will stay that way) it is not a big
deal either way, though.
And the common part is already shared (write_sha1_file_prepare()
and write_sha1_file() from sha1_file.c).
^ permalink raw reply
* Re: Clean up sha1 file writing
From: Junio C Hamano @ 2006-05-24 20:46 UTC (permalink / raw)
To: Linus Torvalds; +Cc: git
In-Reply-To: <Pine.LNX.4.64.0605240820560.5623@g5.osdl.org>
Linus Torvalds <torvalds@osdl.org> writes:
> ... On the other hand, from a longer-term
> maintenance standpoint and from a "be much more careful when doing file
> writes" standpoint, I think it's worth it.
>
> The re-write is "obviously correct" (famous last words) and is mostly
> just moving code around and getting rid of a few temporaries that become
> unnecessary as a result.
>
> The patch looks a bit messy: the changes aren't actually that big, but the
> split-up and the resulting re-indentation makes the patch fairly
> unreadable, so the cleanups are more obvious when you look at the
> before-and-after side by side rather than when looking at the unified
> diff..)
I usually work in text-only terminal, but with the above
warning, I did this:
git cat-file -p HEAD^:sha1_file.c >/var/tmp/1
xxdiff /var/tmp/1 sha1_file.c
with ignorespace and stuff enabled. It was very pleasant to
read the changes that way, especially around write_sha1_to_fd()
vs repack_object(). xxdiff is my new friend.
^ permalink raw reply
* Re: A few stgit bugfixes
From: Catalin Marinas @ 2006-05-24 21:10 UTC (permalink / raw)
To: Karl Hasselström; +Cc: git
In-Reply-To: <20060524060537.GA1173@diana.vm.bytemark.co.uk>
Karl Hasselström wrote:
> Fixes for a few bugs recently introduced in stgit by yours truly.
Applied. Thanks,
Catalin
^ permalink raw reply
* [PATCH] A Perforce importer for git.
From: Sean @ 2006-05-24 22:04 UTC (permalink / raw)
To: git
Signed-off-by: Sean Estabrooks <seanlkml@sympatico.ca>
---
Documentation/git-p4import.txt | 165 ++++++++++++++++++
git-p4import.py | 357 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 522 insertions(+), 0 deletions(-)
diff --git a/Documentation/git-p4import.txt b/Documentation/git-p4import.txt
new file mode 100644
index 0000000..b8ff1e9
--- /dev/null
+++ b/Documentation/git-p4import.txt
@@ -0,0 +1,165 @@
+git-p4import(1)
+===============
+
+NAME
+----
+git-p4import - Import a Perforce repository into git
+
+
+SYNOPSIS
+--------
+`git-p4import` [-q|-v] [--authors <file>] [-t <timezone>] <//p4repo/path> <branch>
+
+`git-p4import` --stitch <//p4repo/path>
+
+`git-p4import`
+
+
+DESCRIPTION
+-----------
+Import a Perforce repository into an existing git repository. When
+a <//p4repo/path> and <branch> are specified a new branch with the
+given name will be created and the initial import will begin.
+
+Once the initial import is complete you can do an incremental import
+of new commits from the Perforce repository. You do this by checking
+out the appropriate git branch and then running `git-p4import` without
+any options.
+
+The standard p4 client is used to communicate with the Perforce
+repository; it must be configured correctly in order for `git-p4import`
+to operate (see below).
+
+
+OPTIONS
+-------
+-q::
+ Do not display any progress information.
+
+-v::
+ Give extra progress information.
+
+\--authors::
+ Specify an authors file containing a mapping of Perforce user
+ ids to full names and email addresses (see Notes below).
+
+\--stitch::
+ Import the contents of the given perforce branch into the
+ currently checked out git branch.
+
+\--log::
+ Store debugging information in the specified file.
+
+-t::
+ Specify that the remote repository is in the specified timezone.
+ Timezone must be in the format "US/Pacific" or "Europe/London"
+ etc. You only need to specify this once, it will be saved in
+ the git config file for the repository.
+
+<//p4repo/path>::
+ The Perforce path that will be imported into the specified branch.
+
+<branch>::
+ The new branch that will be created to hold the Perforce imports.
+
+
+P4 Client
+---------
+You must make the `p4` client command available in your $PATH and
+configure it to communicate with the target Perforce repository.
+Typically this means you must set the "$P4PORT" and "$P4CLIENT"
+environment variables.
+
+You must also configure a `p4` client "view" which maps the Perforce
+branch into the top level of your git repository, for example:
+
+------------
+Client: myhost
+
+Root: /home/sean/import
+
+Options: noallwrite clobber nocompress unlocked modtime rmdir
+
+View:
+ //public/jam/... //myhost/jam/...
+------------
+
+With the above `p4` client setup, you could import the "jam"
+perforce branch into a branch named "jammy", like so:
+
+------------
+$ mkdir -p /home/sean/import/jam
+$ cd /home/sean/import/jam
+$ git init-db
+$ git p4import //public/jam jammy
+------------
+
+
+Multiple Branches
+-----------------
+Note that by creating multiple "views" you can use `git-p4import`
+to import additional branches into the same git repository.
+However, the `p4` client has a limitation in that it silently
+ignores all but the last "view" that maps into the same local
+directory. So the following will *not* work:
+
+------------
+View:
+ //public/jam/... //myhost/jam/...
+ //public/other/... //myhost/jam/...
+ //public/guest/... //myhost/jam/...
+------------
+
+If you want more than one Perforce branch to be imported into the
+same directory you must employ a workaround. A simple option is
+to adjust your `p4` client before each import to only include a
+single view.
+
+Another option is to create multiple symlinks locally which all
+point to the same directory in your git repository and then use
+one per "view" instead of listing the actual directory.
+
+
+Tags
+----
+A git tag of the form p4/xx is created for every change imported from
+the Perforce repository where xx is the Perforce changeset number.
+Therefore after the import you can use git to access any commit by its
+Perforce number, eg. git show p4/327.
+
+The tag associated with the HEAD commit is also how `git-p4import`
+determines if their are new changes to incrementally import from the
+Perforce repository.
+
+If you import from a repository with many thousands of changes
+you will have an equal number of p4/xxxx git tags. Git tags can
+be expensive in terms of disk space and repository operations.
+If you don't need to perform further incremental imports, you
+may delete the tags.
+
+
+Notes
+-----
+You can interrupt the import (eg. ctrl-c) at any time and restart it
+without worry.
+
+Author information is automatically determined by querying the
+Perforce "users" table using the id associated with each change.
+However, if you want to manually supply these mappings you can do
+so with the "--authors" option. It accepts a file containing a list
+of mappings with each line containing one mapping in the format:
+
+------------
+ perforce_id = Full Name <email@address.com>
+------------
+
+
+Author
+------
+Written by Sean Estabrooks <seanlkml@sympatico.ca>
+
+
+GIT
+---
+Part of the gitlink:git[7] suite
+
diff --git a/git-p4import.py b/git-p4import.py
new file mode 100644
index 0000000..74172ab
--- /dev/null
+++ b/git-p4import.py
@@ -0,0 +1,357 @@
+#!/usr/bin/python
+#
+# This tool is copyright (c) 2006, Sean Estabrooks.
+# It is released under the Gnu Public License, version 2.
+#
+# Import Perforce branches into Git repositories.
+# Checking out the files is done by calling the standard p4
+# client which you must have properly configured yourself
+#
+
+import marshal
+import os
+import sys
+import time
+import getopt
+
+from signal import signal, \
+ SIGPIPE, SIGINT, SIG_DFL, \
+ default_int_handler
+
+signal(SIGPIPE, SIG_DFL)
+s = signal(SIGINT, SIG_DFL)
+if s != default_int_handler:
+ signal(SIGINT, s)
+
+
+def die(msg, *args):
+ for a in args:
+ msg = "%s %s" % (msg, a)
+ print "git-p4import fatal error:", msg
+ sys.exit(1)
+
+def usage():
+ print "USAGE: git-p4import [-q|-v] [--authors=<file>] [-t <timezone>] [//p4repo/path <branch>]"
+ sys.exit(1)
+
+verbosity = 1
+logfile = "/dev/null"
+ignore_warnings = False
+stitch = 0
+
+def report(level, msg, *args):
+ global verbosity
+ global logfile
+ for a in args:
+ msg = "%s %s" % (msg, a)
+ fd = open(logfile, "a")
+ fd.writelines(msg)
+ fd.close()
+ if level <= verbosity:
+ print msg
+
+class p4_command:
+ def __init__(self, _repopath):
+ try:
+ global logfile
+ self.userlist = {}
+ if _repopath[-1] == '/':
+ self.repopath = _repopath[:-1]
+ else:
+ self.repopath = _repopath
+ if self.repopath[-4:] != "/...":
+ self.repopath= "%s/..." % self.repopath
+ f=os.popen('p4 -V 2>>%s'%logfile, 'rb')
+ a = f.readlines()
+ if f.close():
+ raise
+ except:
+ die("Could not find the \"p4\" command")
+
+ def p4(self, cmd, *args):
+ global logfile
+ cmd = "%s %s" % (cmd, ' '.join(args))
+ report(2, "P4:", cmd)
+ f=os.popen('p4 -G %s 2>>%s' % (cmd,logfile), 'rb')
+ list = []
+ while 1:
+ try:
+ list.append(marshal.load(f))
+ except EOFError:
+ break
+ self.ret = f.close()
+ return list
+
+ def sync(self, id, force=False, trick=False, test=False):
+ if force:
+ ret = self.p4("sync -f %s@%s"%(self.repopath, id))[0]
+ elif trick:
+ ret = self.p4("sync -k %s@%s"%(self.repopath, id))[0]
+ elif test:
+ ret = self.p4("sync -n %s@%s"%(self.repopath, id))[0]
+ else:
+ ret = self.p4("sync %s@%s"%(self.repopath, id))[0]
+ if ret['code'] == "error":
+ data = ret['data'].upper()
+ if data.find('VIEW') > 0:
+ die("Perforce reports %s is not in client view"% self.repopath)
+ elif data.find('UP-TO-DATE') < 0:
+ die("Could not sync files from perforce", self.repopath)
+
+ def changes(self, since=0):
+ try:
+ list = []
+ for rec in self.p4("changes %s@%s,#head" % (self.repopath, since+1)):
+ list.append(rec['change'])
+ list.reverse()
+ return list
+ except:
+ return []
+
+ def authors(self, filename):
+ f=open(filename)
+ for l in f.readlines():
+ self.userlist[l[:l.find('=')].rstrip()] = \
+ (l[l.find('=')+1:l.find('<')].rstrip(),l[l.find('<')+1:l.find('>')])
+ f.close()
+ for f,e in self.userlist.items():
+ report(2, f, ":", e[0], " <", e[1], ">")
+
+ def _get_user(self, id):
+ if not self.userlist.has_key(id):
+ try:
+ user = self.p4("users", id)[0]
+ self.userlist[id] = (user['FullName'], user['Email'])
+ except:
+ self.userlist[id] = (id, "")
+ return self.userlist[id]
+
+ def _format_date(self, ticks):
+ symbol='+'
+ name = time.tzname[0]
+ offset = time.timezone
+ if ticks[8]:
+ name = time.tzname[1]
+ offset = time.altzone
+ if offset < 0:
+ offset *= -1
+ symbol = '-'
+ localo = "%s%02d%02d %s" % (symbol, offset / 3600, offset % 3600, name)
+ tickso = time.strftime("%a %b %d %H:%M:%S %Y", ticks)
+ return "%s %s" % (tickso, localo)
+
+ def where(self):
+ try:
+ return self.p4("where %s" % self.repopath)[-1]['path']
+ except:
+ return ""
+
+ def describe(self, num):
+ desc = self.p4("describe -s", num)[0]
+ self.msg = desc['desc']
+ self.author, self.email = self._get_user(desc['user'])
+ self.date = self._format_date(time.localtime(long(desc['time'])))
+ return self
+
+class git_command:
+ def __init__(self):
+ try:
+ self.version = self.git("--version")[0][12:].rstrip()
+ except:
+ die("Could not find the \"git\" command")
+ try:
+ self.gitdir = self.get_single("rev-parse --git-dir")
+ report(2, "gdir:", self.gitdir)
+ except:
+ die("Not a git repository... did you forget to \"git init-db\" ?")
+ try:
+ self.cdup = self.get_single("rev-parse --show-cdup")
+ if self.cdup != "":
+ os.chdir(self.cdup)
+ self.topdir = os.getcwd()
+ report(2, "topdir:", self.topdir)
+ except:
+ die("Could not find top git directory")
+
+ def git(self, cmd):
+ global logfile
+ report(2, "GIT:", cmd)
+ f=os.popen('git %s 2>>%s' % (cmd,logfile), 'rb')
+ r=f.readlines()
+ self.ret = f.close()
+ return r
+
+ def get_single(self, cmd):
+ return self.git(cmd)[0].rstrip()
+
+ def current_branch(self):
+ try:
+ testit = self.git("rev-parse --verify HEAD")[0]
+ return self.git("symbolic-ref HEAD")[0][11:].rstrip()
+ except:
+ return None
+
+ def get_config(self, variable):
+ try:
+ return self.git("repo-config --get %s" % variable)[0].rstrip()
+ except:
+ return None
+
+ def set_config(self, variable, value):
+ try:
+ self.git("repo-config %s %s"%(variable, value) )
+ except:
+ die("Could not set %s to " % variable, value)
+
+ def make_tag(self, name, head):
+ self.git("tag -f %s %s"%(name,head))
+
+ def top_change(self, branch):
+ try:
+ a=self.get_single("name-rev --tags refs/heads/%s" % branch)
+ loc = a.find(' tags/') + 6
+ if a[loc:loc+3] != "p4/":
+ raise
+ return int(a[loc+3:][:-2])
+ except:
+ return 0
+
+ def update_index(self):
+ self.git("ls-files -m -d -o -z | git update-index --add --remove -z --stdin")
+
+ def checkout(self, branch):
+ self.git("checkout %s" % branch)
+
+ def repoint_head(self, branch):
+ self.git("symbolic-ref HEAD refs/heads/%s" % branch)
+
+ def remove_files(self):
+ self.git("ls-files | xargs rm")
+
+ def clean_directories(self):
+ self.git("clean -d")
+
+ def fresh_branch(self, branch):
+ report(1, "Creating new branch", branch)
+ self.git("ls-files | xargs rm")
+ os.remove(".git/index")
+ self.repoint_head(branch)
+ self.git("clean -d")
+
+ def basedir(self):
+ return self.topdir
+
+ def commit(self, author, email, date, msg, id):
+ self.update_index()
+ fd=open(".msg", "w")
+ fd.writelines(msg)
+ fd.close()
+ try:
+ current = self.get_single("rev-parse --verify HEAD")
+ head = "-p HEAD"
+ except:
+ current = ""
+ head = ""
+ tree = self.get_single("write-tree")
+ for r,l in [('DATE',date),('NAME',author),('EMAIL',email)]:
+ os.environ['GIT_AUTHOR_%s'%r] = l
+ os.environ['GIT_COMMITTER_%s'%r] = l
+ commit = self.get_single("commit-tree %s %s < .msg" % (tree,head))
+ os.remove(".msg")
+ self.make_tag("p4/%s"%id, commit)
+ self.git("update-ref HEAD %s %s" % (commit, current) )
+
+
+try:
+ opts, args = getopt.getopt(sys.argv[1:], "qhvt:",
+ ["authors=","help","stitch=","timezone=","log=","ignore"])
+except getopt.GetoptError:
+ usage()
+
+for o, a in opts:
+ if o == "-q":
+ verbosity = 0
+ if o == "-v":
+ verbosity += 1
+ if o in ("--log"):
+ logfile = a
+ if o in ("-h", "--help"):
+ usage()
+ if o in ("--ignore"):
+ ignore_warnings = True
+
+git = git_command()
+branch=git.current_branch()
+
+for o, a in opts:
+ if o in ("-t", "--timezone"):
+ git.set_config("perforce.timezone", a)
+ if o in ("--stitch"):
+ git.set_config("perforce.%s.path" % branch, a)
+ stitch = 1
+
+if len(args) == 2:
+ branch = args[1]
+ git.checkout(branch)
+ if branch == git.current_branch():
+ die("Branch %s already exists!" % branch)
+ report(1, "Setting perforce to ", args[0])
+ git.set_config("perforce.%s.path" % branch, args[0])
+elif len(args) != 0:
+ die("You must specify the perforce //depot/path and git branch")
+
+p4path = git.get_config("perforce.%s.path" % branch)
+if p4path == None:
+ die("Do not know Perforce //depot/path for git branch", branch)
+
+p4 = p4_command(p4path)
+
+for o, a in opts:
+ if o in ("-a", "--authors"):
+ p4.authors(a)
+
+localdir = git.basedir()
+if p4.where()[:len(localdir)] != localdir:
+ report(1, "**WARNING** Appears p4 client is misconfigured")
+ report(1, " for sync from %s to %s" % (p4.repopath, localdir))
+ if ignore_warnings != True:
+ die("Reconfigure or use \"--ignore\" on command line")
+
+if stitch == 0:
+ top = git.top_change(branch)
+else:
+ top = 0
+changes = p4.changes(top)
+count = len(changes)
+if count == 0:
+ report(1, "Already up to date...")
+ sys.exit(0)
+
+ptz = git.get_config("perforce.timezone")
+if ptz:
+ report(1, "Setting timezone to", ptz)
+ os.environ['TZ'] = ptz
+ time.tzset()
+
+if stitch == 1:
+ git.remove_files()
+ git.clean_directories()
+ p4.sync(changes[0], force=True)
+elif top == 0 and branch != git.current_branch():
+ p4.sync(changes[0], test=True)
+ report(1, "Creating new initial commit");
+ git.fresh_branch(branch)
+ p4.sync(changes[0], force=True)
+else:
+ p4.sync(changes[0], trick=True)
+
+report(1, "processing %s changes from p4 (%s) to git (%s)" % (count, p4.repopath, branch))
+for id in changes:
+ report(1, "Importing changeset", id)
+ change = p4.describe(id)
+ p4.sync(id)
+ git.commit(change.author, change.email, change.date, change.msg, id)
+ if stitch == 1:
+ git.clean_directories()
+ stitch = 0
+
--
1.3.3.g17cf3
^ permalink raw reply related
* What's in git.git
From: Junio C Hamano @ 2006-05-24 22:40 UTC (permalink / raw)
To: git
* The 'master' branch has these since the last announcement.
- lift length limits from mktag (Björn Engelmann)
- misc fixes and cleanups (Alex Riesen, Björn Engelmann,
Linus, Martin Waitz, Peter Eriksen, Sean Estabrooks)
- git-svn updates, ignores svn:keywords (Eric Wong)
- documentation updates (J. Bruce Fields)
- cvsimport updates (Jeff King, Martin Langhoff)
- built-in format-patch (Johannes Schindelin)
- built-in many commands (Linus, Peter Eriksen, Timo Hirvonen, me)
- remote tar-tree
- "git status -u" (Matthias Lederhofer)
- more cygwin portability bits (Yakov Lerner)
* The 'next' branch, in addition, has these.
- handle patches at the beginning and the end of file properly
(Catalin Marinas, Linus)
- mailinfo updates (Eric W. Biederman).
- cache-tree to speed up "apply & write-tree" cycle.
- http-fetch possible segfault fix (Sean Estabrooks)
- ref-log (Shawn Pearce)
^ permalink raw reply
* Re: [PATCH 5/5] Enable ref log creation in git checkout -b.
From: Junio C Hamano @ 2006-05-24 23:18 UTC (permalink / raw)
To: Shawn Pearce; +Cc: git
In-Reply-To: <20060524035234.GA13329@spearce.org>
Shawn Pearce <spearce@spearce.org> writes:
> Junio C Hamano <junkio@cox.net> wrote:
>> I've swallowed all 10 and pushed them out in "pu", but could you
>> add tests to check the Porcelainish commands you touched with
>> this series to make sure they all log correctly?
>
> Sure. I've been putting it off as I've been busy the past few days
> and have also been thinking about trying to rebuild reflog using a
> tag/annotation branch style, which might be more generally useful
> to others.
It appears that there is more serious breakage caused by the
lock_ref change. http-fetch in "next" fails to clone, because
the call to lock-ref-sha1 in fetch.c::pull() forgets that the
program might be creating a new ref.
Another breakage I found (not related to ref-log) is that it
appears fetch.c, even in "master" branch [*1*], has current_ref
variable and does things depending on it, but nobody seems to
set that variable, so there are a lot of dead code that looks as
if they are doing something useful, enclosed in sections like:
if (somethingelse && current_ref) {
dead code
}
I'll probably revert the ref-log series from "next" in the next
round of updates, while killing the current_ref variable from
"master".
[Footnotes]
*1* It actually is worse than that. Commit cd541a6 introduced
this variable but nobody touches it ever in the development
history of that variable. I wonder what the original author and
the maintainer were smoking back then...
^ permalink raw reply
* Re: [PATCH 5/5] Enable ref log creation in git checkout -b.
From: Shawn Pearce @ 2006-05-24 23:25 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7vy7wr3tc3.fsf@assigned-by-dhcp.cox.net>
Junio C Hamano <junkio@cox.net> wrote:
> Shawn Pearce <spearce@spearce.org> writes:
>
> > Junio C Hamano <junkio@cox.net> wrote:
> >> I've swallowed all 10 and pushed them out in "pu", but could you
> >> add tests to check the Porcelainish commands you touched with
> >> this series to make sure they all log correctly?
> >
> > Sure. I've been putting it off as I've been busy the past few days
> > and have also been thinking about trying to rebuild reflog using a
> > tag/annotation branch style, which might be more generally useful
> > to others.
>
> It appears that there is more serious breakage caused by the
> lock_ref change. http-fetch in "next" fails to clone, because
> the call to lock-ref-sha1 in fetch.c::pull() forgets that the
> program might be creating a new ref.
Hmm. I thought I was doing the same thing fetch used to do which
appeared to only work on refs which already exist, and not creating
new refs...
> Another breakage I found (not related to ref-log) is that it
> appears fetch.c, even in "master" branch [*1*], has current_ref
> variable and does things depending on it, but nobody seems to
> set that variable, so there are a lot of dead code that looks as
> if they are doing something useful, enclosed in sections like:
>
> if (somethingelse && current_ref) {
> dead code
> }
I wondered about that code...
--
Shawn.
^ permalink raw reply
* Re: Clean up sha1 file writing
From: Linus Torvalds @ 2006-05-24 23:35 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7vslmz5ewt.fsf@assigned-by-dhcp.cox.net>
On Wed, 24 May 2006, Junio C Hamano wrote:
>
> It was very pleasant to read the changes that way, especially around
> write_sha1_to_fd() vs repack_object(). xxdiff is my new friend.
I think "kompare" (the KDE diff tool) is nicer.
I'm tolf xxdiff integrates with some of the other SCM tools well (svn and
tla), so it people use xxdiff, maybe it could support the git way of doing
things too..
Linus
^ permalink raw reply
* Re: [PATCH 5/5] Enable ref log creation in git checkout -b.
From: Shawn Pearce @ 2006-05-24 23:36 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7vy7wr3tc3.fsf@assigned-by-dhcp.cox.net>
Junio C Hamano <junkio@cox.net> wrote:
> Shawn Pearce <spearce@spearce.org> writes:
>
> > Junio C Hamano <junkio@cox.net> wrote:
> >> I've swallowed all 10 and pushed them out in "pu", but could you
> >> add tests to check the Porcelainish commands you touched with
> >> this series to make sure they all log correctly?
> >
> > Sure. I've been putting it off as I've been busy the past few days
> > and have also been thinking about trying to rebuild reflog using a
> > tag/annotation branch style, which might be more generally useful
> > to others.
>
> It appears that there is more serious breakage caused by the
> lock_ref change. http-fetch in "next" fails to clone, because
> the call to lock-ref-sha1 in fetch.c::pull() forgets that the
> program might be creating a new ref.
The breakage is because of current_ref always being null. The old
code would allow locking a non-existant ref in this case while the
new code was failing. A simple change such as the following should
fix it:
-->8--
Fix fetch when using reflog.
Previously fetch was permitted to create refs if they did not exist;
this only worked as current_ref was always NULL and thus never
would get compared against the existing ref.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
2dad4178db978c01257fde949d808361589ee003
fetch.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
2dad4178db978c01257fde949d808361589ee003
diff --git a/fetch.c b/fetch.c
index fd57684..15110b8 100644
--- a/fetch.c
+++ b/fetch.c
@@ -213,7 +213,7 @@ int pull(char *target)
save_commit_buffer = 0;
track_object_refs = 0;
if (write_ref) {
- lock = lock_ref_sha1(write_ref, current_ref, 1);
+ lock = lock_ref_sha1(write_ref, current_ref, 0);
if (!lock) {
error("Can't lock ref %s", write_ref);
return -1;
--
1.3.3.gfad60
^ permalink raw reply related
* Re: Slow fetches of tags
From: Linus Torvalds @ 2006-05-24 23:43 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Ralf Baechle, Git Mailing List
In-Reply-To: <Pine.LNX.4.64.0605241200110.5623@g5.osdl.org>
On Wed, 24 May 2006, Linus Torvalds wrote:
>
> IOW, I think there's something more fundamentally wrong with the tag
> following. We _should_ have figured out much more quickly that we have it
> all.
Actually, maybe the problem is that Ralf's tree has two roots, because of
the old CVS history. It might be following the other root down for the
"have" part, since that one doesn't exist at all in the target and the
other side will never acknowledge any of it.
I'll play with it.
Linus
^ permalink raw reply
* Re: Clean up sha1 file writing
From: Junio C Hamano @ 2006-05-25 0:19 UTC (permalink / raw)
To: Linus Torvalds; +Cc: git
In-Reply-To: <Pine.LNX.4.64.0605241631340.5623@g5.osdl.org>
Linus Torvalds <torvalds@osdl.org> writes:
> On Wed, 24 May 2006, Junio C Hamano wrote:
>>
>> It was very pleasant to read the changes that way, especially around
>> write_sha1_to_fd() vs repack_object(). xxdiff is my new friend.
>
> I think "kompare" (the KDE diff tool) is nicer.
I'd love to give it a whirl, but aptitude says it will consume
73.5MB diskspace to install it, with download size 22.4MB, which
makes me go ... hmmmm (my machines are currently KDE free so the
above counts slurping in the kdelibs essentials).
^ permalink raw reply
* Re: Clean up sha1 file writing
From: Sean @ 2006-05-25 0:31 UTC (permalink / raw)
To: Junio C Hamano; +Cc: torvalds, git
In-Reply-To: <7virnv3qi6.fsf@assigned-by-dhcp.cox.net>
On Wed, 24 May 2006 17:19:29 -0700
Junio C Hamano <junkio@cox.net> wrote:
> Linus Torvalds <torvalds@osdl.org> writes:
>
> > On Wed, 24 May 2006, Junio C Hamano wrote:
> >>
> >> It was very pleasant to read the changes that way, especially around
> >> write_sha1_to_fd() vs repack_object(). xxdiff is my new friend.
> >
> > I think "kompare" (the KDE diff tool) is nicer.
>
> I'd love to give it a whirl, but aptitude says it will consume
> 73.5MB diskspace to install it, with download size 22.4MB, which
> makes me go ... hmmmm (my machines are currently KDE free so the
> above counts slurping in the kdelibs essentials).
>
"meld" works great too, and lets you do hunk-level merging etc; very
handy. The bash <( ... ) feature is quite handy too, it will create
a temp file for you and clean it up afterward.
$ meld sha1_file.c <(git cat-file -p c2f493a4ae:sha1_file.c)
Sean
^ permalink raw reply
* [PATCH] cat-file: document -p option
From: Jeff King @ 2006-05-25 1:22 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <20060524203108.70b6c596.seanlkml@sympatico.ca>
---
On Wed, May 24, 2006 at 08:31:08PM -0400, Sean wrote:
> $ meld sha1_file.c <(git cat-file -p c2f493a4ae:sha1_file.c)
I had never seen the -p option, and it wasn't in the Documentation. Let
me know if I've gotten its function completely wrong. :)
-Peff
Documentation/git-cat-file.txt | 9 +++++++--
1 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/Documentation/git-cat-file.txt b/Documentation/git-cat-file.txt
index 504eb1b..5e9cbf8 100644
--- a/Documentation/git-cat-file.txt
+++ b/Documentation/git-cat-file.txt
@@ -8,12 +8,12 @@ git-cat-file - Provide content or type i
SYNOPSIS
--------
-'git-cat-file' [-t | -s | -e | <type>] <object>
+'git-cat-file' [-t | -s | -e | -p | <type>] <object>
DESCRIPTION
-----------
Provides content or type of objects in the repository. The type
-is required unless '-t' is used to find the object type,
+is required unless '-t' or '-p' is used to find the object type,
or '-s' is used to find the object size.
OPTIONS
@@ -33,6 +33,9 @@ OPTIONS
Suppress all output; instead exit with zero status if <object>
exists and is a valid object.
+-p::
+ Pretty-print the contents of <object> based on its type.
+
<type>::
Typically this matches the real type of <object> but asking
for a type that can trivially be dereferenced from the given
@@ -49,6 +52,8 @@ If '-s' is specified, the size of the <o
If '-e' is specified, no output.
+If '-p' is specified, the contents of <object> are pretty-printed.
+
Otherwise the raw (though uncompressed) contents of the <object> will
be returned.
--
1.3.3.g4d548
^ permalink raw reply related
* Re: Slow fetches of tags
From: Junio C Hamano @ 2006-05-25 1:32 UTC (permalink / raw)
To: Linus Torvalds; +Cc: git
In-Reply-To: <Pine.LNX.4.64.0605241641250.5623@g5.osdl.org>
Linus Torvalds <torvalds@osdl.org> writes:
> On Wed, 24 May 2006, Linus Torvalds wrote:
>>
>> IOW, I think there's something more fundamentally wrong with the tag
>> following. We _should_ have figured out much more quickly that we have it
>> all.
>
> Actually, maybe the problem is that Ralf's tree has two roots, because of
> the old CVS history. It might be following the other root down for the
> "have" part, since that one doesn't exist at all in the target and the
> other side will never acknowledge any of it.
>
> I'll play with it.
I think I know what is going on. You are exactly right -- the
two-root ness is what is causing this.
We used to stop sending "have" immediately after we get an ACK.
This was troublesome for trees with many long branches, so we
introduced multi_ack protocol extension to let the server side
(upload-pack) say "Ok, enough on this branch -- I know this
object so do not tell me any more about objects reachable from
it, but do tell me about other development tracks if you have
one". If you run "fetch-pack -v" after priming a repository
with Ralf's tree and Chris's tree, you will see many "have" with
occasional "got ack 2 [0-9a-f]{40}". The latter is upload-pack
acking this way.
This was done to prevent already-known-to-be-common objects
filling up the list of known common commits on the server side.
The remaining slots can be used to discover common commits on
other branches, so that we can minimize the transfer. It was an
important optimization when dealing with sets of branches that
are long.
This unfortunately breaks down quite badly in this case, since
the remaining "branch" it keeps following is the other history
Chris's tree has never heard of down to its root in vain.
It might be worth changing fetch-pack to note that it has sent
many "have"s after it got an "continue" ACK, and give up early,
say using a heuristic between the age of the commit that did got
an ACK and the one we are about to send out as a "have".
^ permalink raw reply
* [PATCH 1/2] Fix cg-patch hanging on terminals with TOSTOP flag
From: Pavel Roskin @ 2006-05-25 1:40 UTC (permalink / raw)
To: Petr Baudis; +Cc: git
From: Pavel Roskin <proski@gnu.org>
Terminals with TOSTOP flag don't allow background processes to write to
the terminal. This flag is used e.g. by the subshell in GNU Midnight
Commander. It can also be set by "stty tostop".
Redirect stdout and strerr of the "patch" command to a temporary file
and show it once "patch" terminates.
Signed-off-by: Pavel Roskin <proski@gnu.org>
---
cg-patch | 6 ++++--
1 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/cg-patch b/cg-patch
index 9ea7de4..115869e 100755
--- a/cg-patch
+++ b/cg-patch
@@ -337,6 +337,7 @@ # parts of the tree from inadverent poll
[ "$unidiff" ] && newsfile="$(mktemp -t gitapply.XXXXXX)"
gonefile="$(mktemp -t gitapply.XXXXXX)"
todo="$(mktemp -t gitapply.XXXXXX)"
+patchout="$(mktemp -t gitapply.XXXXXX)"
patchfifo="$(mktemp -t gitapply.XXXXXX)"
rm "$patchfifo" && mkfifo -m 600 "$patchfifo"
@@ -347,7 +348,7 @@ # patch file removal behaviour cannot be
# just handle it all ourselves.
patch_args="-p$strip -N"
[ "$reverse" ] && patch_args="$patch_args -R"
-patch $patch_args <"$patchfifo" &
+patch $patch_args <"$patchfifo" >"$patchout" 2>&1 &
tee "$patchfifo" | {
redzone_reset
@@ -407,6 +408,7 @@ tee "$patchfifo" | {
} >$todo
wait %1; ret=$?
+cat "$patchout"
IFS=$'\n' emptyfiles=($(git-ls-files --deleted | join -v 2 "$gonefile" -))
if [ "$unidiff" ]; then
@@ -441,7 +443,7 @@ while [ "$1" ]; do
done
' padding
-rm "$patchfifo" "$todo" "$gonefile"
+rm "$patchfifo" "$todo" "$gonefile" "$patchout"
[ "$unidiff" ] && rm "$newsfile"
exit $ret
^ permalink raw reply related
* [PATCH 2/2] Improve the tutorial script
From: Pavel Roskin @ 2006-05-25 1:40 UTC (permalink / raw)
To: Petr Baudis; +Cc: git
In-Reply-To: <20060525014001.27814.23082.stgit@dv.roinet.com>
From: Pavel Roskin <proski@gnu.org>
Use a function to imitate differern users. Set environment variables so
the the names of the users are actually used in the commits.
Further limit direct use of git. Stop using git for patch transmission.
Use cg-mkpatch and cg-patch instead. Don't even attempt octopus merge
to avoid confusing users.
Don't use obsolete "-d" flag for cg-tag.
Rewrite many comments to make the tutorial more coherent. Group
commands in a more logical way.
Suppress "ed" output. Strip trailing spaces.
Signed-off-by: Pavel Roskin <proski@gnu.org>
---
Documentation/tutorial-script/0000-playground.sh | 6 -
Documentation/tutorial-script/script.sh | 237 ++++++++++++----------
2 files changed, 129 insertions(+), 114 deletions(-)
diff --git a/Documentation/tutorial-script/0000-playground.sh b/Documentation/tutorial-script/0000-playground.sh
deleted file mode 100755
index cdfb442..0000000
--- a/Documentation/tutorial-script/0000-playground.sh
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/bin/sh
-
-rm -rf Playground
-mkdir Playground
-cd Playground
-mkdir Alice Bob Charlie
diff --git a/Documentation/tutorial-script/script.sh b/Documentation/tutorial-script/script.sh
index 5b7fc6d..b99e3c9 100755
--- a/Documentation/tutorial-script/script.sh
+++ b/Documentation/tutorial-script/script.sh
@@ -1,15 +1,14 @@
#!/bin/bash
#
-# FIXME: This script has some GITisms. They stem from missing Cogito
-# features, such as exporting patches to mbox format, applying patches
-# from e-mail, merging multiple tags at once, verifying signed tags and
-# repacking the repository.
+# This script serves both as a tutorial explaining how to use Cogito and
+# as a test for Cogito. It's uses as part of the testsuite.
#
-# Not that there would be anything wrong per se with this; GIT and Cogito
-# can interoperate fine (except few quite special situations; see the README
-# for details) and you can mix the commands; Cogito might never provide
-# wrappers for some of the GIT features which are nevertheless awesomely
-# useful, like `git bisect`.
+# This script has a few direct calls to git. They are used when Cogito
+# doesn't provide needed functionality, such as verifying signed tags
+# and repacking the repository.
+#
+# There is anything wrong with this; git and Cogito can interoperate
+# just fine, especially if you don't use git for things Cogito can do.
# This function is appended as "&& should_fail" to commands which should
@@ -28,100 +27,132 @@ set -e
trap 'echo >&2 "Unexpected error $? on line $LINENO"; exit 1' exit
-### Set up playground
-sh 0000-playground.sh
-export PATH=$(pwd)/../..:$PATH # Use the local Cogito version
+# Since this script doubles as a test, prefer the local Cogito version
+# so it can be tested before installation
TOP=$(pwd)
+export PATH=$TOP/../..:$PATH
+
+### Set up the playground
+rm -rf Playground
+mkdir Playground
+cd Playground
+
+# Suppose we have three users: Alice, Bob and Charlie
+mkdir Alice Bob Charlie
ALICE=$TOP/Playground/Alice
BOB=$TOP/Playground/Bob
CHARLIE=$TOP/Playground/Charlie
-cd Playground
-### Alice's first version
-cd $ALICE
+# This function imitates becoming one of the users
+switch_user () {
+ case $1 in
+ Alice) cd "$ALICE";;
+ Bob) cd "$BOB";;
+ Charlie) cd "$CHARLIE";;
+ *) echo "I don't know you, $1"; exit 1;;
+ esac
+ HOME=$(pwd)
+ GIT_AUTHOR_NAME="$1"
+ GIT_AUTHOR_EMAIL="$1@example.com"
+ GIT_COMMITTER_NAME="$1"
+ GIT_COMMITTER_EMAIL="$1@example.com"
+}
+
+
+### Let's start. Pretend you are Alice
+switch_user Alice
+
+# Alice has written an RPN calculator program
tar xf $TOP/0001-alice.tar
cd rpn
# Being a tidy girl, she places it under Cogito
echo "Alice's first version" | cg-init
-cg-tag -d "First ever version of RPN" rpn-0.1
-
-# Alice decides on OSL-2.1
-cd $ALICE/rpn
+# Let it be known as version 0.1
+cg-tag -m "First ever version of RPN" rpn-0.1
+
+# Alice decides to add the license file to the code
cp $TOP/0002-alice-license.txt osl-2.1.txt
-# The new file has to be added
+# Cogito should know that it's a new file to be added
cg-add osl-2.1.txt
-# Fix up the files
+# Notices should be added to the existing files
patch -p1 -i $TOP/0003-alice-osl.patch
-# Now save all, and tag it for later reference
+# Alice commits the changes and tags the result as version 0.2
cg-commit -m "Place under OSL-2.1"
-cg-tag -d "Place under OSL-2.1" rpn-0.2
+cg-tag -m "Place under OSL-2.1" rpn-0.2
-# Alice creates a public repository for the new toy
+# Now Alice creates a public repository for the new toy
cg-admin-setuprepo $ALICE/rpn.git
-cg-branch-add public "$ALICE/rpn.git" # Shortcut for the public repository
-# Alice pushes her master _and_ the two tags to the public repository
+
+# Alice will refer to it as the "public" branch
+cg-branch-add public "$ALICE/rpn.git"
+
+# Alice pushes her master branch and both tags to the public repository
cg-push public -t rpn-0.1 -t rpn-0.2
-### Bob hears about this exciting new program, gets a copy from Alice
-cd $BOB
+### Bob hears about this exciting new program and gets a copy from Alice
+switch_user Bob
cg-clone $ALICE/rpn.git
-
cd rpn
-# Bob thinks the declarations for the stack should go in a header file
+# Bob thinks the declarations for the stack belong to a header file
cp $TOP/0004-bob-stack_h stack.h
patch -p1 -i $TOP/0005-bob-stack_h.patch
-
cg-add stack.h
cg-commit -m "Place stack declarations in header file" \
-m "Create stack.h, move declarations of stack manipulation into it" \
- -m "Include stack.h in rpn.c and stack.h"
+ -m "Include stack.h in rpn.c and stack.h"
-# Later, he remembers he didn't fix the Makefile
+# Just after commit, Bob realizes he didn't fix the Makefile
patch -p1 -i $TOP/0006-bob-Makefile.patch
-
cg-commit -m "Update dependencies for stack.h in Makefile"
### Alice has been busy too...
-cd $ALICE/rpn
+switch_user Alice
+cd rpn
# She adds the 'd'rop operation
patch -p1 -i $TOP/0007-alice-drop.patch
-
cg-commit -m "Add drop command" \
-m "Change rpn.c to add handling for 'd'rop"
# Then she adds 'C'lear, and a first stab at documentation
patch -p1 -i $TOP/0008-alice-clear.patch
cp $TOP/0009-alice-README.txt README
-
cg-add README
cg-commit -m "Add clear stack command" \
-m "Change rpn.c to add handling for 'C'lear" \
-m "Add README file with fist stab at documentation"
# The result works fine, so she prepares to release it
-cg-tag -d "First public release" rpn-0.3
+cg-tag -m "First public release" rpn-0.3
cg-push public -t rpn-0.3
cg-export ../rpn-0.3.tar.bz2
### Bob tells Alice of his changes, Alice prepares to get them.
-cd $ALICE/rpn
+switch_user Alice
+cd rpn
+# Alice creates local branch "bob" to integrate Bob's changes.
cg-switch -r master bob
+
+# Now Alice has branches "master", "public" and "bob" ("bob" is active).
cg-status -g
-# Alice needs to register his remote branch
+# Remote branch "bobswork" is a shortcut to the Bob's master branch
cg-branch-add bobswork $BOB/rpn
-# Now try to merge Bob's work to the bob branch
+
+# Remote branches are "public" and "bobswork".
+cg-branch-ls
+
+# Alice tries to merge Bob's work to the "bob" branch
cg-update bobswork && should_fail
# There are conflicts in rpn.c. Looking at the file, Alice sees the
@@ -132,98 +163,82 @@ #: <<<<<<< bob
#: extern double pop(void);
#: extern void push(double);
#: extern void clear(void);
-#:
+#:
#: =======
#: >>>>>>> bobswork
#: extern int getsym(void);
#: ...
-
-# Alice keeps Bob's version
-ed rpn.c < $TOP/0010-alice-bob-fixup.ed
+
+# Alice keeps Bob's version, i.e. the one from the "bobswork" branch
+ed -s rpn.c < $TOP/0010-alice-bob-fixup.ed
# cg-commit after resolving conflicts from failed merge will autogenerate
# the commit message.
cg-commit </dev/null
-# She fixes up Makefile and stack.h a bit
+# While still on the "bob" branch, Alice fixes up Makefile and stack.h
patch -p1 -i $TOP/0011-alice-cleanup.patch
cg-commit -m "Fix Makefile and stack.h"
-## Charlie heard of RPN, and wants to hack too.
-cd $CHARLIE
-
+### Charlie heard of RPN, and wants to hack too
+switch_user Charlie
cg-clone $ALICE/rpn.git rpn
cd rpn
-# He hacks around, and messes up rpn.c. To restore the saved version:
-rm rpn.c
-cg-restore rpn.c
+# He hacks around, and messes up rpn.c
+echo "Oops!" > rpn.c
-# Finally, he has the changes he wants
+# Fortunately, cg-restore can take care of it
+cg-restore -f rpn.c
+
+# Finally, Charlie has the changes he wants
cp $TOP/0012-charlie-lexer_h lexer.h
patch -p1 -i $TOP/0013-charlie-lexer.patch
-
cg-add lexer.h
cg-commit -m "Add proper header file for lexer" \
-m "Create lexer.h, move lexer declarations into it." \
-m "Include lexer.h in rpn.c and lexer.c" \
-m "Update dependencies in Makefile"
-# Charlie emails the patch to Alice:
-# cg-mkpatch -d .. -r rpn-0.3..master
-git format-patch -o .. --mbox --signoff -r rpn-0.3
-# Only git can create mbox formatted output
-# Compare the result to 0014-charlie-email
+# Charlie prepares the patch and sends it to Alice
+cg-mkpatch -d ../patches -r rpn-0.3..master
+
+# Well, in real life Charlie is more likely to use e-mail than "cp"
+cp -r $CHARLIE/patches $ALICE/patches
### Alice is busy meanwhile...
-cd $ALICE/rpn
+switch_user Alice
+cd rpn
+# She returns to master branch, leaving "bob" for later merging
cg-switch master
+# The calculator gets a new operator
patch -p1 -i $TOP/0015-alice-mod.patch
-
cg-commit -m "Add mod operator" \
-m "Add handling for '%' (fmod(3)) in rpn.c"
+# And then another one
patch -p1 -i $TOP/0016-alice-dup.patch
-
cg-commit -m "Add duplication operator" \
-m "Add handling for 'D'up in rpn.c"
-
+
# Alice publishes her work-in-progress
cg-push public
-
-### Alice gets Charlie's fix, creates a new branch for his changes
-cd $ALICE/rpn
-
+# Alice gets Charlie's fix and creates a new branch for his changes.
+# This time, she starts the branch off the rpn-0.3 tag, which was
+# the base version for Charlie's changes.
cg-switch -r rpn-0.3 charlie
-cg-status -g
-
-# Check what's inside the patch. There is no Cogito equivalent yet.
-git apply --stat $TOP/0014-charlie-email
-git apply --summary $TOP/0014-charlie-email
-git apply --check $TOP/0014-charlie-email
-
-# Everything looks OK
-git applymbox $TOP/0014-charlie-email
-# This doesn't work well yet
-# cg-patch < $TOP/0014-charlie-email
-
-### Alice integrates the changes in the branches for the next release
-cd $ALICE/rpn
+cg-patch -d $ALICE/patches
+# Alice is going to integrate the changes in the "bob" and "charlie"
+# branches into "master" for the next release
cg-switch master
-# Alice tries "git merge" instead of "cg-merge" since she wanted to
-# merge both branches at once, which "cg-merge" cannot do.
-git merge "Integrate changes from Bob and Charlie" master bob charlie \
- && should_fail
-# Automatic 3-way merge fails! Have to do it step by step
-
-cg-reset
+# First, Alice tries to integrate Bob's changes
cg-merge bob && should_fail
# Merge fails:
@@ -239,34 +254,38 @@ #: stack.o: stack.h
#: lexer.o:
#: >>>>>>> bob
-ed Makefile < $TOP/0017-alice-bob-fixup.ed
-
+# Alice fixes Makefile and commits the changes
+ed -s Makefile < $TOP/0017-alice-bob-fixup.ed
cg-commit -m "Integrate Bob's changes"
+# Now it's time to integrate Charlie's changes
cg-merge charlie && should_fail
-# Merge conflicts!
+# Merge fails again! Makefile needs tweaking
#: ...
#: <<<<<<< master
#: $(CC) $(CFLAGS) $^ -lm -o $@
-#:
+#:
#: rpn.o: stack.h
#: stack.o: stack.h
#: lexer.o:
#: =======
#: $(CC) $(CFLAGS) $^ -o $@
-#:
+#:
#: rpn.o lexer.o: lexer.h
-#:
+#:
#: >>>>>>> charlie
-ed Makefile < $TOP/0018-alice-charlie-fixup1.ed
+# Alice fixes Makefile
+ed -s Makefile < $TOP/0018-alice-charlie-fixup1.ed
+
+# rpn.c needs fixing too
#: ...
#: <<<<<<< master
#: extern int getsym(void);
-#:
+#:
#: =======
#: extern double pop(void);
#: extern void push(double);
@@ -275,36 +294,37 @@ #:
#: >>>>>> charlie
#: ...
-ed rpn.c < $TOP/0019-alice-charlie-fixup2.ed
+ed -s rpn.c < $TOP/0019-alice-charlie-fixup2.ed
+# Finally, Charlie's changes can be committed
cg-commit -m "Integrate Charlie's changes"
-# Give proper credits
+# Alice gives proper credits to the contributors
cp $TOP/0020-alice-CONTRIBUTORS.txt CONTRIBUTORS
-
cg-add CONTRIBUTORS
cg-commit -m "Add CONTRIBUTORS"
-# Wrong file name...
+# But maybe it's better to call that file CREDITS?
cg-mv CONTRIBUTORS CREDITS
cg-commit -m "Rename CONTRIBUTORS to CREDITS"
-
-# Pack it so it uses less space
+# Alice packs the repository so it uses less space
git repack
git prune-packed
-# Second public release
-cg-tag -d "New public release" rpn-0.4
+# Now it's time for another public release
+cg-tag -m "Public release of version 0.4" rpn-0.4
cg-push public -t rpn-0.4
cg-export ../rpn-0.4.tar.bz2
-# Also pack public repository
+# The public repository needs packing too
GIT_DIR=$ALICE/rpn.git git repack
GIT_DIR=$ALICE/rpn.git git prune-packed
+
### Bob updates his version to Alice's
-cd $BOB/rpn
+switch_user Bob
+cd rpn
cg-fetch
@@ -314,9 +334,10 @@ # to set up a GPG key before running the
# scripts does not make much sense.)
git verify-tag rpn-0.4 && should_fail
-# Everything's OK, integrate the changes
+# Everything's OK, Bob integrate the changes
cg-merge
-# Great, we are done.
+
+### Great, we are done.
trap - exit
echo "Script completed successfully!"
^ permalink raw reply related
* [PATCH] Built git-upload-tar should be ignored.
From: Shawn Pearce @ 2006-05-25 2:48 UTC (permalink / raw)
To: Junio Hamano; +Cc: git
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
.gitignore | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/.gitignore b/.gitignore
index 18a7295..afd0876 100644
--- a/.gitignore
+++ b/.gitignore
@@ -116,6 +116,7 @@ git-update-index
git-update-ref
git-update-server-info
git-upload-pack
+git-upload-tar
git-var
git-verify-pack
git-verify-tag
--
1.3.3.g45d8
^ permalink raw reply related
* [PATCH] Verify git-commit provides a reflog message.
From: Shawn Pearce @ 2006-05-25 3:33 UTC (permalink / raw)
To: Junio Hamano; +Cc: git
The reflog message from git-commit should include the first line
of the commit message as supplied by the user.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
t/t1400-update-ref.sh | 38 ++++++++++++++++++++++++++------------
1 files changed, 26 insertions(+), 12 deletions(-)
diff --git a/t/t1400-update-ref.sh b/t/t1400-update-ref.sh
index f6b076b..2b1f4c8 100755
--- a/t/t1400-update-ref.sh
+++ b/t/t1400-update-ref.sh
@@ -178,22 +178,36 @@ rm -f .git/$m .git/logs/$m expect
test_expect_success \
'creating initial files' \
- 'cp ../../COPYING COPYING &&
- git-add COPYING &&
+ 'echo TEST >F &&
+ git-add F &&
+ GIT_AUTHOR_DATE="2005-05-26 23:30" \
GIT_COMMITTER_DATE="2005-05-26 23:30" git-commit -m add -a &&
- cp ../../Makefile COPYING &&
- GIT_COMMITTER_DATE="2005-05-26 23:41" git-commit -m change -a'
+ h_TEST=$(git-rev-parse --verify HEAD)
+ echo The other day this did not work. >M &&
+ echo And then Bob told me how to fix it. >>M &&
+ echo OTHER >F &&
+ GIT_AUTHOR_DATE="2005-05-26 23:41" \
+ GIT_COMMITTER_DATE="2005-05-26 23:41" git-commit -F m -a &&
+ h_OTHER=$(git-rev-parse --verify HEAD)
+ rm -f m'
+
+cat >expect <<EOF
+$Z $h_TEST $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150200 +0000 commit: add
+$h_TEST $h_OTHER $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150860 +0000 commit: The other day this did not work.
+EOF
+test_expect_success \
+ 'git-commit logged updates' \
+ 'diff expect .git/logs/$m'
+unset h_TEST h_OTHER
test_expect_success \
- 'git-cat-file blob master:COPYING (expect Makefile)' \
- 'git-cat-file blob master:COPYING | diff - ../../Makefile'
+ 'git-cat-file blob master:F (expect OTHER)' \
+ 'test OTHER = $(git-cat-file blob master:F)'
test_expect_success \
- 'git-cat-file blob master@{2005-05-26 23:30}:COPYING (expect COPYING)' \
- 'git-cat-file blob "master@{2005-05-26 23:30}:COPYING" \
- | diff - ../../COPYING'
+ 'git-cat-file blob master@{2005-05-26 23:30}:F (expect TEST)' \
+ 'test TEST = $(git-cat-file blob "master@{2005-05-26 23:30}:F")'
test_expect_success \
- 'git-cat-file blob master@{2005-05-26 23:42}:COPYING (expect Makefile)' \
- 'git-cat-file blob "master@{2005-05-26 23:42}:COPYING" \
- | diff - ../../Makefile'
+ 'git-cat-file blob master@{2005-05-26 23:42}:F (expect OTHER)' \
+ 'test OTHER = $(git-cat-file blob "master@{2005-05-26 23:42}:F")'
test_done
--
1.3.3.g45d8
^ permalink raw reply related
* [PATCH] Test that git-branch -l works.
From: Shawn Pearce @ 2006-05-25 3:34 UTC (permalink / raw)
To: Junio Hamano; +Cc: git
If the user supplies -l to git-branch when creating a new branch
then the new branch's log should be created automatically and the
branch creation should be logged in that log.
Further if a branch is being deleted and it had a log then also
verify that the log was deleted.
Test git-checkout -b foo -l for creating a new branch foo with a
log and checking out that branch.
Fixed git-checkout -b foo -l as the branch variable name was
incorrect in the script.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
git-checkout.sh | 4 ++--
t/t3200-branch.sh | 31 ++++++++++++++++++++++++++++++-
2 files changed, 32 insertions(+), 3 deletions(-)
diff --git a/git-checkout.sh b/git-checkout.sh
index 360aabf..564117f 100755
--- a/git-checkout.sh
+++ b/git-checkout.sh
@@ -197,8 +197,8 @@ #
if [ "$?" -eq 0 ]; then
if [ "$newbranch" ]; then
if [ "$newbranch_log" ]; then
- mkdir -p $(dirname "$GIT_DIR/logs/refs/heads/$branchname")
- touch "$GIT_DIR/logs/refs/heads/$branchname"
+ mkdir -p $(dirname "$GIT_DIR/logs/refs/heads/$newbranch")
+ touch "$GIT_DIR/logs/refs/heads/$newbranch"
fi
git-update-ref -m "checkout: Created from $new_name" "refs/heads/$newbranch" $new || exit
branch="$newbranch"
diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh
index c3de151..5b04efc 100755
--- a/t/t3200-branch.sh
+++ b/t/t3200-branch.sh
@@ -14,7 +14,8 @@ test_expect_success \
'prepare an trivial repository' \
'echo Hello > A &&
git-update-index --add A &&
- git-commit -m "Initial commit."'
+ git-commit -m "Initial commit." &&
+ HEAD=$(git-rev-parse --verify HEAD)'
test_expect_success \
'git branch --help should return success now.' \
@@ -32,4 +33,32 @@ test_expect_success \
'git branch a/b/c should create a branch' \
'git-branch a/b/c && test -f .git/refs/heads/a/b/c'
+cat >expect <<EOF
+0000000000000000000000000000000000000000 $HEAD $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150200 +0000 branch: Created from HEAD
+EOF
+test_expect_success \
+ 'git branch -l d/e/f should create a branch and a log' \
+ 'GIT_COMMITTER_DATE="2005-05-26 23:30" \
+ git-branch -l d/e/f &&
+ test -f .git/refs/heads/d/e/f &&
+ test -f .git/logs/refs/heads/d/e/f &&
+ diff expect .git/logs/refs/heads/d/e/f'
+
+test_expect_success \
+ 'git branch -d d/e/f should delete a branch and a log' \
+ 'git-branch -d d/e/f &&
+ test ! -f .git/refs/heads/d/e/f &&
+ test ! -f .git/logs/refs/heads/d/e/f'
+
+cat >expect <<EOF
+0000000000000000000000000000000000000000 $HEAD $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150200 +0000 checkout: Created from master^0
+EOF
+test_expect_success \
+ 'git checkout -b g/h/i -l should create a branch and a log' \
+ 'GIT_COMMITTER_DATE="2005-05-26 23:30" \
+ git-checkout -b g/h/i -l master &&
+ test -f .git/refs/heads/g/h/i &&
+ test -f .git/logs/refs/heads/g/h/i &&
+ diff expect .git/logs/refs/heads/g/h/i'
+
test_done
--
1.3.3.g45d8
^ permalink raw reply related
* [PATCH] ls-remote fix for rsync:// transport
From: Junio C Hamano @ 2006-05-25 4:22 UTC (permalink / raw)
To: git
I think this would fix the "cloning rsync:// clones repository fine but
does not check out the working tree" problem.
---
diff --git a/git-ls-remote.sh b/git-ls-remote.sh
index b6882a9..6b21879 100755
--- a/git-ls-remote.sh
+++ b/git-ls-remote.sh
@@ -58,7 +58,8 @@ http://* | https://* )
;;
rsync://* )
- mkdir $tmpdir
+ mkdir $tmpdir &&
+ rsync -rlq "$peek_repo/HEAD" $tmpdir &&
rsync -rq "$peek_repo/refs" $tmpdir || {
echo "failed slurping"
exit
@@ -69,6 +70,13 @@ rsync://* )
cat "$tmpdir/$path" | tr -d '\012'
echo " $path"
done &&
+ head=$(cat "$tmpdir/HEAD") &&
+ case "$head" in
+ ref:' '*)
+ head=$(expr "z$head" : 'zref: \(.*\)') &&
+ head=$(cat "$tmpdir/$head") || exit
+ esac &&
+ echo "$head HEAD"
rm -fr $tmpdir
;;
^ permalink raw reply related
* importing cvs logical modules
From: Geoff Russell @ 2006-05-25 4:48 UTC (permalink / raw)
To: git
Hi,
Firstly, the code to automagically
repack a git repository on-the-fly during a big load has solved one of
my problems - thanks, it is great. Unfortunately it has bought me to
showstopper number 2.
- cvs modules.
cvs allows you to define modules which rearrange the physical repository into
a different logical structure. This sounds great and we use it, but it gives
us other headaches because "cvs update" doesn't always do the right
thing with these modules.
Furthermore cvsps doesn't appear to handle this module feature at all and
is tricked into thinking that rearranged directories come from somewhere
else and issues its "file xxx doesn't match strip_path" message.
I have tried to hack cvsps to go around the problem, but without success.
Another alternative that I thought might be easier would be to unload the cvs
repository in clean pieces - each being a git repository. Then to join the
git repositories together in the desired way. I think this would be
generally useful and not just solve my problem.
e.g. Suppose I have 3 git repositories: Progs, xxxx, yyyy
Progs/.git
xxxx/.git
yyyy/.git
I'd like to make 1 git repository Progs with xxxx and yyyy as child trees.
Progs/.git
Progs/xxxx
Progs/yyyy
Does this sound useful to anyone else, or is it already possible?
Cheers,
Geoff Russell.
^ 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