Merge part of np/delta

maint
Junio C Hamano 2006-02-22 00:57:43 -08:00
commit 882e4dc183
16 changed files with 320 additions and 262 deletions

View File

@ -7,7 +7,7 @@ git-add - Add files to the index file.

SYNOPSIS
--------
'git-add' [-n] [-v] <file>...
'git-add' [-n] [-v] [--] <file>...

DESCRIPTION
-----------
@ -26,6 +26,11 @@ OPTIONS
-v::
Be verbose.

--::
This option can be used to separate command-line options from
the list of files, (useful when filenames might be mistaken
for command-line options).


DISCUSSION
----------

View File

@ -15,6 +15,7 @@ SYNOPSIS
[-x <pattern>|--exclude=<pattern>]
[-X <file>|--exclude-from=<file>]
[--exclude-per-directory=<file>]
[--error-unmatch]
[--full-name] [--] [<file>]\*

DESCRIPTION
@ -73,6 +74,10 @@ OPTIONS
read additional exclude patterns that apply only to the
directory and its subdirectories in <file>.

--error-unmatch::
If any <file> does not appear in the index, treat this as an
error (return 1).

-t::
Identify the file status with the following tags (followed by
a space) at the start of each line:

View File

@ -43,6 +43,12 @@ to fast forward the remote ref that matches <dst>. If
the optional plus `+` is used, the remote ref is updated
even if it does not result in a fast forward update.
+
Note: If no explicit refspec is found, (that is neither
on the command line nor in any Push line of the
corresponding remotes file---see below), then all the
refs that exist both on the local side and on the remote
side are updated.
+
Some short-cut notations are also supported.
+
* `tag <tag>` means the same as `refs/tags/<tag>:refs/tags/<tag>`.

View File

@ -7,14 +7,54 @@ git-rebase - Rebase local commits to new upstream head.

SYNOPSIS
--------
'git-rebase' <upstream> [<head>]
'git-rebase' [--onto <newbase>] <upstream> [<branch>]

DESCRIPTION
-----------
Rebases local commits to the new head of the upstream tree.
git-rebase applies to <upstream> (or optionally to <newbase>) commits
from <branch> that do not appear in <upstream>. When <branch> is not
specified it defaults to the current branch (HEAD).

When git-rebase is complete, <branch> will be updated to point to the
newly created line of commit objects, so the previous line will not be
accessible unless there are other references to it already.

Assume the following history exists and the current branch is "topic":

A---B---C topic
/
D---E---F---G master

From this point, the result of the following commands:

git-rebase master
git-rebase master topic

would be:

A'--B'--C' topic
/
D---E---F---G master

While, starting from the same point, the result of the following
commands:

git-rebase --onto master~1 master
git-rebase --onto master~1 master topic

would be:

A'--B'--C' topic
/
D---E---F---G master

OPTIONS
-------
<newbase>::
Starting point at which to create the new commits. If the
--onto option is not specified, the starting point is
<upstream>.

<upstream>::
Upstream branch to compare against.


View File

@ -518,15 +518,15 @@ git-ssh-upload$X: rsh.o
git-ssh-pull$X: rsh.o fetch.o
git-ssh-push$X: rsh.o

git-http-fetch$X: fetch.o http.o http-fetch.o
git-http-fetch$X: fetch.o http.o http-fetch.o $(LIB_FILE)
$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \
$(LIBS) $(CURL_LIBCURL)

git-http-push$X: http.o http-push.o
git-http-push$X: http.o http-push.o $(LIB_FILE)
$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \
$(LIBS) $(CURL_LIBCURL) $(EXPAT_LIBEXPAT)

git-rev-list$X: rev-list.o
git-rev-list$X: rev-list.o $(LIB_FILE)
$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \
$(LIBS) $(OPENSSL_LIBSSL)


View File

@ -56,20 +56,6 @@ def show_date(epoch, tz):

return time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(secs))

def get_sha1_from_tags(line):
fp = os.popen("git cat-file -t " + line)
entry = string.strip(fp.readline())
fp.close()
if (entry == "commit"):
return line
elif (entry == "tag"):
fp = os.popen("git cat-file tag "+ line)
entry = string.strip(fp.readline())
fp.close()
obj = re.split(" ", entry)
if (obj[0] == "object"):
return obj[1]
return None

class CellRendererGraph(gtk.GenericCellRenderer):
"""Cell renderer for directed graph.
@ -174,9 +160,9 @@ class CellRendererGraph(gtk.GenericCellRenderer):
names_len = 0
if (len(names) != 0):
for item in names:
names_len += len(item)/3
names_len += len(item)

width = box_size * (cols + 1 + names_len )
width = box_size * (cols + 1 ) + names_len
height = box_size

# FIXME I have no idea how to use cell_area properly
@ -258,6 +244,8 @@ class CellRendererGraph(gtk.GenericCellRenderer):
for item in names:
name = name + item + " "

ctx.select_font_face("Monospace")
ctx.set_font_size(13)
ctx.text_path(name)

self.set_colour(ctx, colour, 0.0, 0.5)
@ -465,32 +453,24 @@ class GitView:
respective sha1 details """

self.bt_sha1 = { }
ls_remote = re.compile('^(.{40})\trefs/([^^]+)(?:\\^(..))?$');
git_dir = os.getenv("GIT_DIR")
if (git_dir == None):
git_dir = ".git"

#FIXME the path seperator
ref_files = os.listdir(git_dir + "/refs/tags")
for file in ref_files:
fp = open(git_dir + "/refs/tags/"+file)
sha1 = get_sha1_from_tags(string.strip(fp.readline()))
try:
self.bt_sha1[sha1].append(file)
except KeyError:
self.bt_sha1[sha1] = [file]
fp.close()


#FIXME the path seperator
ref_files = os.listdir(git_dir + "/refs/heads")
for file in ref_files:
fp = open(git_dir + "/refs/heads/" + file)
sha1 = get_sha1_from_tags(string.strip(fp.readline()))
try:
self.bt_sha1[sha1].append(file)
except KeyError:
self.bt_sha1[sha1] = [file]
fp.close()
fp = os.popen('git ls-remote ' + git_dir)
while 1:
line = string.strip(fp.readline())
if line == '':
break
m = ls_remote.match(line)
if not m:
continue
(sha1, name) = (m.group(1), m.group(2))
if not self.bt_sha1.has_key(sha1):
self.bt_sha1[sha1] = []
self.bt_sha1[sha1].append(name)
fp.close()


def construct(self):
@ -537,8 +517,8 @@ class GitView:

cell = CellRendererGraph()
column = gtk.TreeViewColumn()
column.set_resizable(False)
column.pack_start(cell, expand=False)
column.set_resizable(True)
column.pack_start(cell, expand=True)
column.add_attribute(cell, "node", 1)
column.add_attribute(cell, "in-lines", 2)
column.add_attribute(cell, "out-lines", 3)

View File

@ -19,8 +19,9 @@
*/

#include <stdlib.h>
#include <string.h>
#include <zlib.h>
#include "delta.h"
#include "zlib.h"


/* block size: min = 16, max = 64k, power of 2 */
@ -29,149 +30,87 @@
#define MIN(a, b) ((a) < (b) ? (a) : (b))

#define GR_PRIME 0x9e370001
#define HASH(v, b) (((unsigned int)(v) * GR_PRIME) >> (32 - (b)))
static unsigned int hashbits(unsigned int size)
{
unsigned int val = 1, bits = 0;
while (val < size && bits < 32) {
val <<= 1;
bits++;
}
return bits ? bits: 1;
}
#define HASH(v, shift) (((unsigned int)(v) * GR_PRIME) >> (shift))

typedef struct s_chanode {
struct s_chanode *next;
int icurr;
} chanode_t;

typedef struct s_chastore {
int isize, nsize;
chanode_t *ancur;
} chastore_t;

static void cha_init(chastore_t *cha, int isize, int icount)
{
cha->isize = isize;
cha->nsize = icount * isize;
cha->ancur = NULL;
}

static void *cha_alloc(chastore_t *cha)
{
chanode_t *ancur;
void *data;

ancur = cha->ancur;
if (!ancur || ancur->icurr == cha->nsize) {
ancur = malloc(sizeof(chanode_t) + cha->nsize);
if (!ancur)
return NULL;
ancur->icurr = 0;
ancur->next = cha->ancur;
cha->ancur = ancur;
}

data = (void *)ancur + sizeof(chanode_t) + ancur->icurr;
ancur->icurr += cha->isize;
return data;
}

static void cha_free(chastore_t *cha)
{
chanode_t *cur = cha->ancur;
while (cur) {
chanode_t *tmp = cur;
cur = cur->next;
free(tmp);
}
}

typedef struct s_bdrecord {
struct s_bdrecord *next;
unsigned int fp;
struct index {
const unsigned char *ptr;
} bdrecord_t;
unsigned int val;
struct index *next;
};

typedef struct s_bdfile {
chastore_t cha;
unsigned int fphbits;
bdrecord_t **fphash;
} bdfile_t;

static int delta_prepare(const unsigned char *buf, int bufsize, bdfile_t *bdf)
static struct index ** delta_index(const unsigned char *buf,
unsigned long bufsize,
unsigned int *hash_shift)
{
unsigned int fphbits;
int i, hsize;
const unsigned char *data, *top;
bdrecord_t *brec;
bdrecord_t **fphash;
unsigned int hsize, hshift, entries, blksize, i;
const unsigned char *data;
struct index *entry, **hash;
void *mem;

fphbits = hashbits(bufsize / BLK_SIZE + 1);
hsize = 1 << fphbits;
fphash = malloc(hsize * sizeof(bdrecord_t *));
if (!fphash)
return -1;
for (i = 0; i < hsize; i++)
fphash[i] = NULL;
cha_init(&bdf->cha, sizeof(bdrecord_t), hsize / 4 + 1);
/* determine index hash size */
entries = (bufsize + BLK_SIZE - 1) / BLK_SIZE;
hsize = entries / 4;
for (i = 4; (1 << i) < hsize && i < 16; i++);
hsize = 1 << i;
hshift = 32 - i;
*hash_shift = hshift;

top = buf + bufsize;
data = buf + (bufsize / BLK_SIZE) * BLK_SIZE;
if (data == top)
/* allocate lookup index */
mem = malloc(hsize * sizeof(*hash) + entries * sizeof(*entry));
if (!mem)
return NULL;
hash = mem;
entry = mem + hsize * sizeof(*hash);
memset(hash, 0, hsize * sizeof(*hash));

/* then populate it */
data = buf + entries * BLK_SIZE - BLK_SIZE;
blksize = bufsize - (data - buf);
while (data >= buf) {
unsigned int val = adler32(0, data, blksize);
i = HASH(val, hshift);
entry->ptr = data;
entry->val = val;
entry->next = hash[i];
hash[i] = entry++;
blksize = BLK_SIZE;
data -= BLK_SIZE;
}

for ( ; data >= buf; data -= BLK_SIZE) {
brec = cha_alloc(&bdf->cha);
if (!brec) {
cha_free(&bdf->cha);
free(fphash);
return -1;
}
brec->fp = adler32(0, data, MIN(BLK_SIZE, top - data));
brec->ptr = data;
i = HASH(brec->fp, fphbits);
brec->next = fphash[i];
fphash[i] = brec;
}

bdf->fphbits = fphbits;
bdf->fphash = fphash;

return 0;
}

static void delta_cleanup(bdfile_t *bdf)
{
free(bdf->fphash);
cha_free(&bdf->cha);
return hash;
}

/* provide the size of the copy opcode given the block offset and size */
#define COPYOP_SIZE(o, s) \
(!!(o & 0xff) + !!(o & 0xff00) + !!(o & 0xff0000) + !!(o & 0xff000000) + \
!!(s & 0xff) + !!(s & 0xff00) + 1)

/* the maximum size for any opcode */
#define MAX_OP_SIZE COPYOP_SIZE(0xffffffff, 0xffffffff)

void *diff_delta(void *from_buf, unsigned long from_size,
void *to_buf, unsigned long to_size,
unsigned long *delta_size,
unsigned long max_size)
{
int i, outpos, outsize, inscnt, csize, msize, moff;
unsigned int fp;
const unsigned char *ref_data, *ref_top, *data, *top, *ptr1, *ptr2;
unsigned char *out, *orig;
bdrecord_t *brec;
bdfile_t bdf;
unsigned int i, outpos, outsize, inscnt, hash_shift;
const unsigned char *ref_data, *ref_top, *data, *top;
unsigned char *out;
struct index *entry, **hash;

if (!from_size || !to_size || delta_prepare(from_buf, from_size, &bdf))
if (!from_size || !to_size)
return NULL;
hash = delta_index(from_buf, from_size, &hash_shift);
if (!hash)
return NULL;

outpos = 0;
outsize = 8192;
if (max_size && outsize >= max_size)
outsize = max_size + MAX_OP_SIZE + 1;
out = malloc(outsize);
if (!out) {
delta_cleanup(&bdf);
free(hash);
return NULL;
}

@ -199,28 +138,32 @@ void *diff_delta(void *from_buf, unsigned long from_size,
}

inscnt = 0;
moff = 0;
while (data < top) {
msize = 0;
fp = adler32(0, data, MIN(top - data, BLK_SIZE));
i = HASH(fp, bdf.fphbits);
for (brec = bdf.fphash[i]; brec; brec = brec->next) {
if (brec->fp == fp) {
csize = ref_top - brec->ptr;
if (csize > top - data)
csize = top - data;
for (ptr1 = brec->ptr, ptr2 = data;
csize && *ptr1 == *ptr2;
csize--, ptr1++, ptr2++);

csize = ptr1 - brec->ptr;
if (csize > msize) {
moff = brec->ptr - ref_data;
msize = csize;
if (msize >= 0x10000) {
msize = 0x10000;
break;
}
while (data < top) {
unsigned int moff = 0, msize = 0;
unsigned int blksize = MIN(top - data, BLK_SIZE);
unsigned int val = adler32(0, data, blksize);
i = HASH(val, hash_shift);
for (entry = hash[i]; entry; entry = entry->next) {
const unsigned char *ref = entry->ptr;
const unsigned char *src = data;
unsigned int ref_size = ref_top - ref;
if (entry->val != val)
continue;
if (ref_size > top - src)
ref_size = top - src;
while (ref_size && *src++ == *ref) {
ref++;
ref_size--;
}
ref_size = ref - entry->ptr;
if (ref_size > msize) {
/* this is our best match so far */
moff = entry->ptr - ref_data;
msize = ref_size;
if (msize >= 0x10000) {
msize = 0x10000;
break;
}
}
}
@ -235,13 +178,15 @@ void *diff_delta(void *from_buf, unsigned long from_size,
inscnt = 0;
}
} else {
unsigned char *op;

if (inscnt) {
out[outpos - inscnt - 1] = inscnt;
inscnt = 0;
}

data += msize;
orig = out + outpos++;
op = out + outpos++;
i = 0x80;

if (moff & 0xff) { out[outpos++] = moff; i |= 0x01; }
@ -256,23 +201,21 @@ void *diff_delta(void *from_buf, unsigned long from_size,
msize >>= 8;
if (msize & 0xff) { out[outpos++] = msize; i |= 0x20; }

*orig = i;
*op = i;
}

if (max_size && outpos > max_size) {
free(out);
delta_cleanup(&bdf);
return NULL;
}

/* next time around the largest possible output is 1 + 4 + 3 */
if (outpos > outsize - 8) {
if (outpos >= outsize - MAX_OP_SIZE) {
void *tmp = out;
outsize = outsize * 3 / 2;
out = realloc(out, outsize);
if (max_size && outsize >= max_size)
outsize = max_size + MAX_OP_SIZE + 1;
if (max_size && outpos > max_size)
out = NULL;
else
out = realloc(out, outsize);
if (!out) {
free(tmp);
delta_cleanup(&bdf);
free(hash);
return NULL;
}
}
@ -281,7 +224,7 @@ void *diff_delta(void *from_buf, unsigned long from_size,
if (inscnt)
out[outpos - inscnt - 1] = inscnt;

delta_cleanup(&bdf);
free(hash);
*delta_size = outpos;
return out;
}

View File

@ -14,6 +14,10 @@ while : ; do
-v)
verbose=--verbose
;;
--)
shift
break
;;
-*)
usage
;;

View File

@ -189,7 +189,7 @@ my @month_names = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
sub show_date {
my ($time, $tz) = @_;
my $minutes = abs($tz);
$minutes = ($minutes / 100) * 60 + ($minutes % 100);
$minutes = int($minutes / 100) * 60 + ($minutes % 100);
if ($tz < 0) {
$minutes = -$minutes;
}

View File

@ -4,24 +4,28 @@
#

USAGE='[--onto <newbase>] <upstream> [<branch>]'
LONG_USAGE='If <branch> is specified, switch to that branch first. Then,
extract commits in the current branch that are not in <upstream>,
and reconstruct the current on top of <upstream>, discarding the original
development history. If --onto <newbase> is specified, the history is
reconstructed on top of <newbase>, instead of <upstream>. For example,
while on "topic" branch:
LONG_USAGE='git-rebase applies to <upstream> (or optionally to <newbase>) commits
from <branch> that do not appear in <upstream>. When <branch> is not
specified it defaults to the current branch (HEAD).

When git-rebase is complete, <branch> will be updated to point to the
newly created line of commit objects, so the previous line will not be
accessible unless there are other references to it already.

Assuming the following history:

A---B---C topic
/
D---E---F---G master

$ '"$0"' --onto master~1 master topic
The result of the following command:

would rewrite the history to look like this:
git-rebase --onto master~1 master topic

would be:

A'\''--B'\''--C'\'' topic
/
A'\''--B'\''--C'\'' topic
/
D---E---F---G master
'

@ -71,7 +75,7 @@ esac
# The upstream head must be given. Make sure it is valid.
upstream_name="$1"
upstream=`git rev-parse --verify "${upstream_name}^0"` ||
die "invalid upsteram $upstream_name"
die "invalid upstream $upstream_name"

# If a hook exists, give it a chance to interrupt
if test -x "$GIT_DIR/hooks/pre-rebase"

82
gitk
View File

@ -1936,7 +1936,7 @@ proc findfiles {} {
global selectedline numcommits lineid ctext
global ffileline finddidsel parents nparents
global findinprogress findstartline findinsertpos
global treediffs fdiffids fdiffsneeded fdiffpos
global treediffs fdiffid fdiffsneeded fdiffpos
global findmergefiles

if {$numcommits == 0} return
@ -1953,11 +1953,9 @@ proc findfiles {} {
while 1 {
set id $lineid($l)
if {$findmergefiles || $nparents($id) == 1} {
foreach p $parents($id) {
if {![info exists treediffs([list $id $p])]} {
append diffsneeded "$id $p\n"
lappend fdiffsneeded [list $id $p]
}
if {![info exists treediffs($id)]} {
append diffsneeded "$id\n"
lappend fdiffsneeded $id
}
}
if {[incr l] >= $numcommits} {
@ -1974,7 +1972,7 @@ proc findfiles {} {
error_popup "Error starting search process: $err"
return
}
catch {unset fdiffids}
catch {unset fdiffid}
set fdiffpos 0
fconfigure $df -blocking 0
fileevent $df readable [list readfilediffs $df]
@ -1983,16 +1981,15 @@ proc findfiles {} {
set finddidsel 0
set findinsertpos end
set id $lineid($l)
set p [lindex $parents($id) 0]
. config -cursor watch
settextcursor watch
set findinprogress 1
findcont [list $id $p]
findcont $id
update
}

proc readfilediffs {df} {
global findids fdiffids fdiffs
global findid fdiffid fdiffs

set n [gets $df line]
if {$n < 0} {
@ -2002,19 +1999,19 @@ proc readfilediffs {df} {
stopfindproc
bell
error_popup "Error in git-diff-tree: $err"
} elseif {[info exists findids]} {
set ids $findids
} elseif {[info exists findid]} {
set id $findid
stopfindproc
bell
error_popup "Couldn't find diffs for {$ids}"
error_popup "Couldn't find diffs for $id"
}
}
return
}
if {[regexp {^([0-9a-f]{40}) \(from ([0-9a-f]{40})\)} $line match id p]} {
if {[regexp {^([0-9a-f]{40})$} $line match id]} {
# start of a new string of diffs
donefilediff
set fdiffids [list $id $p]
set fdiffid $id
set fdiffs {}
} elseif {[string match ":*" $line]} {
lappend fdiffs [lindex $line 5]
@ -2022,53 +2019,50 @@ proc readfilediffs {df} {
}

proc donefilediff {} {
global fdiffids fdiffs treediffs findids
global fdiffid fdiffs treediffs findid
global fdiffsneeded fdiffpos

if {[info exists fdiffids]} {
while {[lindex $fdiffsneeded $fdiffpos] ne $fdiffids
if {[info exists fdiffid]} {
while {[lindex $fdiffsneeded $fdiffpos] ne $fdiffid
&& $fdiffpos < [llength $fdiffsneeded]} {
# git-diff-tree doesn't output anything for a commit
# which doesn't change anything
set nullids [lindex $fdiffsneeded $fdiffpos]
set treediffs($nullids) {}
if {[info exists findids] && $nullids eq $findids} {
unset findids
findcont $nullids
set nullid [lindex $fdiffsneeded $fdiffpos]
set treediffs($nullid) {}
if {[info exists findid] && $nullid eq $findid} {
unset findid
findcont $nullid
}
incr fdiffpos
}
incr fdiffpos

if {![info exists treediffs($fdiffids)]} {
set treediffs($fdiffids) $fdiffs
if {![info exists treediffs($fdiffid)]} {
set treediffs($fdiffid) $fdiffs
}
if {[info exists findids] && $fdiffids eq $findids} {
unset findids
findcont $fdiffids
if {[info exists findid] && $fdiffid eq $findid} {
unset findid
findcont $fdiffid
}
}
}

proc findcont {ids} {
global findids treediffs parents nparents
proc findcont {id} {
global findid treediffs parents nparents
global ffileline findstartline finddidsel
global lineid numcommits matchinglines findinprogress
global findmergefiles

set id [lindex $ids 0]
set p [lindex $ids 1]
set pi [lsearch -exact $parents($id) $p]
set l $ffileline
while 1 {
if {$findmergefiles || $nparents($id) == 1} {
if {![info exists treediffs($ids)]} {
set findids $ids
if {![info exists treediffs($id)]} {
set findid $id
set ffileline $l
return
}
set doesmatch 0
foreach f $treediffs($ids) {
foreach f $treediffs($id) {
set x [findmatches $f]
if {$x != {}} {
set doesmatch 1
@ -2077,21 +2071,13 @@ proc findcont {ids} {
}
if {$doesmatch} {
insertmatch $l $id
set pi $nparents($id)
}
} else {
set pi $nparents($id)
}
if {[incr pi] >= $nparents($id)} {
set pi 0
if {[incr l] >= $numcommits} {
set l 0
}
if {$l == $findstartline} break
set id $lineid($l)
if {[incr l] >= $numcommits} {
set l 0
}
set p [lindex $parents($id) $pi]
set ids [list $id $p]
if {$l == $findstartline} break
set id $lineid($l)
}
stopfindproc
if {!$finddidsel} {

View File

@ -778,6 +778,7 @@ int main(int argc, const char **argv)
continue;
error("pathspec '%s' did not match any.",
pathspec[num] + prefix_offset);
errors++;
}
return errors ? 1 : 0;
}

View File

@ -748,11 +748,10 @@ static int try_delta(struct unpacked *cur, struct unpacked *old, unsigned max_de
}

size = cur_entry->size;
if (size < 50)
return -1;
oldsize = old_entry->size;
sizediff = oldsize > size ? oldsize - size : size - oldsize;
if (sizediff > size / 8)

if (size < 50)
return -1;
if (old_entry->depth >= max_depth)
return 0;

View File

@ -0,0 +1,27 @@
#!/bin/sh
#
# Copyright (c) 2006 Carl D. Worth
#

test_description='git-ls-files test for --error-unmatch option

This test runs git-ls-files --error-unmatch to ensure it correctly
returns an error when a non-existent path is provided on the command
line.
'
. ./test-lib.sh

touch foo bar
git-update-index --add foo bar
git-commit -m "add foo bar"

test_expect_failure \
'git-ls-files --error-unmatch should fail with unmatched path.' \
'git-ls-files --error-unmatch foo bar-does-not-match'

test_expect_success \
'git-ls-files --error-unmatch should succeed eith matched paths.' \
'git-ls-files --error-unmatch foo bar'

test_done
1

22
t/t3700-add.sh Executable file
View File

@ -0,0 +1,22 @@
#!/bin/sh
#
# Copyright (c) 2006 Carl D. Worth
#

test_description='Test of git-add, including the -- option.'

. ./test-lib.sh

test_expect_success \
'Test of git-add' \
'touch foo && git-add foo'

test_expect_success \
'Post-check that foo is in the index' \
'git-ls-files foo | grep foo'

test_expect_success \
'Test that "git-add -- -q" works' \
'touch -- -q && git-add -- -q'

test_done

36
t/t5600-clone-fail-cleanup.sh Executable file
View File

@ -0,0 +1,36 @@
#!/bin/sh
#
# Copyright (C) 2006 Carl D. Worth <cworth@cworth.org>
#

test_description='test git-clone to cleanup after failure

This test covers the fact that if git-clone fails, it should remove
the directory it created, to avoid the user having to manually
remove the directory before attempting a clone again.'

. ./test-lib.sh

test_expect_failure \
'clone of non-existent source should fail' \
'git-clone foo bar'

test_expect_failure \
'failed clone should not leave a directory' \
'cd bar'

# Need a repo to clone
test_create_repo foo

# clone doesn't like it if there is no HEAD. Is that a bug?
(cd foo && touch file && git add file && git commit -m 'add file' >/dev/null 2>&1)

test_expect_success \
'clone should work now that source exists' \
'git-clone foo bar'

test_expect_success \
'successfull clone must leave the directory' \
'cd bar'

test_done