Git development
 help / color / mirror / Atom feed
* [PATCH] http-push: disable http-push without USE_CURL_MULTI
From: Grégoire Barbier @ 2008-01-13 19:02 UTC (permalink / raw)
  To: git; +Cc: gitster, Grégoire Barbier
In-Reply-To: <1200250979-19604-2-git-send-email-gb@gbarbier.org>

Make http-push always fail when not compiled with USE_CURL_MULTI, since
otherwise it corrupts the remote repository (and then fails anyway).

Signed-off-by: Grégoire Barbier <gb@gbarbier.org>
---
 http-push.c |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/http-push.c b/http-push.c
index cbbf432..96c8e75 100644
--- a/http-push.c
+++ b/http-push.c
@@ -2212,6 +2212,10 @@ int main(int argc, char **argv)
 		break;
 	}
 
+#ifndef USE_CURL_MULTI
+	die("git-push is not available for http/https repository when not compiled with USE_CURL_MULTI");
+#endif
+
 	if (!remote->url)
 		usage(http_push_usage);
 
-- 
1.5.3.6

^ permalink raw reply related

* Re: Adding Git to Better SCM Initiative : Comparison
From: linux @ 2008-01-13 18:42 UTC (permalink / raw)
  To: Matthieu.Moy, linux; +Cc: jnareb, git
In-Reply-To: <vpqd4s5ycvv.fsf@bauges.imag.fr>

Matthieu Moy <Matthieu.Moy@imag.fr> wrote:
> linux@horizon.com writes:
>> "Rename support" is a kludge to make a fundamentally broken model
>> less painful.
>
> It's not.
>
> Git _has_ rename support. Look into the code, you'll find some code
> whose purpose is to manage renames. And _no_, rename support is not
> just a direct consequence of commits being atomic.
>
> Atomic commit help, but if you do nothing else, moving a file and then
> trying to merge will fail for example. So, in addition to atomic
> commits, you have at least 3 options : explicit file ID (bzr),
> recording renames (hg), or detecting renames after-the-fact (git).

Please forgive me for not mentioning that part.  Yes, there are
interesting things to do with renames, and git is doing them, but I
skipped over them because they don't have much to do with the better-scm
definition of the feature:

"Does the system support moving a file or directory to a different
location while still retaining the history of the file?"

You can try to interpret it so it makes sense, but the question is
basically assuming that the history is attached to the file rather than
that the file is attached to the history.

With the latter model, the question is almost silly.  Even with the very
primitive version of git that Linus used to make v2.6.12-rc2 with none
of that fancy code, you can rename a file and git retains the history.
Period.  The qualification "of the file" doesn't even make sense.

As Linus has observed in the past, git does lots of fancy stuff to follow
the history of the code that's *in* the file, but the idea is that a file,
per se, doesn't have a history or even an identity.

You can ask about the history of a file *name*, or of a file's *contents*,
but if not that, what exactly is this "file" thing you want the history of?

Once you've answered that, you can then figure out if the answer to
the question based on whether the file has a history to retain in the
first place.


There are interesting questions about renames that you could ask, but
better-scm isn't asking questions like "can you resolve merges properly
after renaming a file on one branch?"  Maybe I'm being uncharitable, but I
can't help but read the question as asking if the system has a workaround
for a well-known CVS problem.  And one honest answer is "no, there's no
workaround; git doesn't suffer from the problem in the first place."

^ permalink raw reply

* [PATCH 1/2] parse_commit_buffer: don't parse invalid commits
From: Martin Koegler @ 2008-01-13 18:11 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Martin Koegler

Signed-off-by: Martin Koegler <mkoegler@auto.tuwien.ac.at>
---

commit.c |   35 ++++++++++++++++++++++++-----------
 1 files changed, 24 insertions(+), 11 deletions(-)

diff --git a/commit.c b/commit.c
index f074811..5b52daa 100644
--- a/commit.c
+++ b/commit.c
@@ -48,22 +48,34 @@ struct commit *lookup_commit(const unsigned char *sha1)
 	return check_commit(obj, sha1, 0);
 }
 
-static unsigned long parse_commit_date(const char *buf)
+static int parse_commit_date(const char *buf, const char *tail, unsigned long *date)
 {
-	unsigned long date;
+	const char *dateptr;
 
+	if (buf + 6 >= tail)
+		return 0;
 	if (memcmp(buf, "author", 6))
 		return 0;
-	while (*buf++ != '\n')
+	while (buf < tail && *buf++ != '\n')
 		/* nada */;
+	if (buf + 9 >= tail)
+		return 0;
 	if (memcmp(buf, "committer", 9))
 		return 0;
-	while (*buf++ != '>')
+	while (buf < tail && *buf++ != '>')
 		/* nada */;
-	date = strtoul(buf, NULL, 10);
-	if (date == ULONG_MAX)
-		date = 0;
-	return date;
+	if (buf >= tail)
+		return 0;
+	dateptr = buf;
+	while (buf < tail && *buf++ != '\n')
+		/* nada */;
+	if (buf >= tail)
+		return 0;
+	/* dateptr < buf && buf[-1] == '\n', so strtoul will stop at buf-1 */
+	*date = strtoul(dateptr, NULL, 10);
+	if (*date == ULONG_MAX)
+		*date = 0;
+	return 1;
 }
 
 static struct commit_graft **commit_graft;
@@ -236,9 +248,9 @@ int parse_commit_buffer(struct commit *item, void *buffer, unsigned long size)
 		return 0;
 	item->object.parsed = 1;
 	tail += size;
-	if (tail <= bufptr + 5 || memcmp(bufptr, "tree ", 5))
+	if (tail <= bufptr + 46 || memcmp(bufptr, "tree ", 5) || bufptr[45] != '\n')
 		return error("bogus commit object %s", sha1_to_hex(item->object.sha1));
-	if (tail <= bufptr + 45 || get_sha1_hex(bufptr + 5, parent) < 0)
+	if (get_sha1_hex(bufptr + 5, parent) < 0)
 		return error("bad tree pointer in commit %s",
 			     sha1_to_hex(item->object.sha1));
 	item->tree = lookup_tree(parent);
@@ -275,7 +287,8 @@ int parse_commit_buffer(struct commit *item, void *buffer, unsigned long size)
 			n_refs++;
 		}
 	}
-	item->date = parse_commit_date(bufptr);
+	if (!parse_commit_date(bufptr, tail, &item->date))
+		return error("bogus commit date in object %s", sha1_to_hex(item->object.sha1));
 
 	if (track_object_refs) {
 		unsigned i = 0;
-- 
1.4.4.4

^ permalink raw reply related

* [PATCH 2/2] git-fsck: remove commit test already done by parse_commit_buffer
From: Martin Koegler @ 2008-01-13 18:11 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Martin Koegler
In-Reply-To: <12002478702664-git-send-email-mkoegler@auto.tuwien.ac.at>

Signed-off-by: Martin Koegler <mkoegler@auto.tuwien.ac.at>
---
 builtin-fsck.c |   12 ------------
 1 files changed, 0 insertions(+), 12 deletions(-)

diff --git a/builtin-fsck.c b/builtin-fsck.c
index e4874f6..a77d8c0 100644
--- a/builtin-fsck.c
+++ b/builtin-fsck.c
@@ -360,18 +360,6 @@ static int fsck_commit(struct commit *commit)
 		fprintf(stderr, "Checking commit %s\n",
 			sha1_to_hex(commit->object.sha1));
 
-	if (memcmp(buffer, "tree ", 5))
-		return objerror(&commit->object, "invalid format - expected 'tree' line");
-	if (get_sha1_hex(buffer+5, tree_sha1) || buffer[45] != '\n')
-		return objerror(&commit->object, "invalid 'tree' line format - bad sha1");
-	buffer += 46;
-	while (!memcmp(buffer, "parent ", 7)) {
-		if (get_sha1_hex(buffer+7, sha1) || buffer[47] != '\n')
-			return objerror(&commit->object, "invalid 'parent' line format - bad sha1");
-		buffer += 48;
-	}
-	if (memcmp(buffer, "author ", 7))
-		return objerror(&commit->object, "invalid format - expected 'author' line");
 	free(commit->buffer);
 	commit->buffer = NULL;
 	if (!commit->tree)
-- 
1.4.4.4

^ permalink raw reply related

* Re: Digging through old vendor code
From: Jon Smirl @ 2008-01-13 17:31 UTC (permalink / raw)
  To: linux@horizon.com; +Cc: git, torvalds
In-Reply-To: <20080113162806.13991.qmail@science.horizon.com>

[-- Attachment #1: Type: text/plain, Size: 2020 bytes --]

On 13 Jan 2008 11:28:06 -0500, linux@horizon.com <linux@horizon.com> wrote:
> > Heh. Maybe you could just use the rename logic?
> >
> > [How-to snipped]
>
> Clever idea, but I think the real problem was to figure out what VERSION
> of the file was the base; i.e. to look through history.
>
> Still, it should be possible to adapt the technique...
>
> #!/bin/sh
>
> # List of files we are looking to copy from
> SRC="drivers/serial/"
> # Temporary work directory
> DST=/tmp/work
> git-clone -l -n -s . $DST
> { cd $DST; git-symbolic-ref HEAD refs/heads/DELETEME; }
> for i in `git-rev-list v2.6.20..v2.6.24-rc6 -- $SRC`; do
>         j=`git-describe $i`
>         git-archive --prefix="$j/" $i -- $SRC | tar xf - -C $DST
>         # This is abusing the index, but it saves space...
>         { cd $DST; git add $j; rm -rf $j; }
> done
>
> # And  now proceed as per Linus's idea...
> # Except we have it all in the index; no need
> # to actually make a commit...
>
> cd $DST
> cp $target_file $DST
> { cd $DST; git-diff-files -M...; }

I tried this using -M1%, it returned 53,575 files. Same thing for 10%.

The files don't seem to be in order by similarity, the first match
returned is not a good one.

I attached the file if anyone wants to play with it. I'm 90% certain
it was copied from amba-pl010.c in 2.6.15.


>
>
> Maybe a real git wizard will show me how to insert the index entries
> directly without ever doing anything as pedestrian as extracting, hashing,
> and then deleting the files, but it's still not that bad.
>
> And it's kind of a neat example of using the index as a staging area
> for a commit.
>
> (Exercise for the reader: the above gets a complete copy of every file in
> the directory for every commit in qhich ANY file in the directory changed.
> Better would be to do the git-rev-list per-file, so you only add unique
> file versions.  This requires an outer loop over file names and a more
> careful pathname specification to git add in the inner loop.)
>


-- 
Jon Smirl
jonsmirl@gmail.com

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: ep93xx_uart.c --]
[-- Type: text/x-csrc; name=ep93xx_uart.c, Size: 23091 bytes --]

/*
 *  linux/drivers/serial/cs93xx.c
 *
 *  Driver for EP93xx serial ports
 *
 *  Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o,
 *  Deep Blue Solutions Ltd.
 *
 *  Copyright 1999 ARM Limited
 *  Copyright (C) 2000 Deep Blue Solutions Ltd.
 *  Copyright (c) 2003 Cirrus Logic, Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 *  $Id: linux-2.6.21.5-ep9x.patch,v 1.8 2008/01/04 13:28:07 baustin Exp $
 *
 * The EP93xx serial ports are AMBA, but at different addresses from the
 * integrator.
 * This is a generic driver for ARM AMBA-type serial ports.  They
 * have a lot of 16550-like features, but are not register compatable.
 * Note that although they do have CTS, DCD and DSR inputs, they do
 * not have an RI input, nor do they have DTR or RTS outputs.  If
 * required, these have to be supplied via some other means (eg, GPIO)
 * and hooked into this driver.
 */
#include <linux/module.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/serial.h>
#include <linux/console.h>
#include <linux/sysrq.h>
#include <linux/spinlock.h>
//#include <linux/device.h>
#include <linux/platform_device.h>

#include <asm/hardware.h>
#include <asm/io.h>
//#include <asm/irqs.h>

#if defined(CONFIG_SERIAL_EP93XX_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
#define SUPPORT_SYSRQ
#endif


#include <linux/serial_core.h>
#include <linux/amba/bus.h>
#include <linux/amba/serial.h>



#if defined(CONFIG_ARCH_EP9301) || defined(CONFIG_ARCH_EP9302)
#ifdef CONFIG_EP93XX_IRDA
#define UART_NR		1
#else
#define UART_NR		2
#endif
#else
#ifdef CONFIG_EP93XX_IRDA
#define UART_NR		2
#else
#define UART_NR		3
#endif
#endif

#define SERIAL_EP93XX_MAJOR	204
#define SERIAL_EP93XX_MINOR	16
#define SERIAL_EP93XX_NR	UART_NR

#define EP93XX_ISR_PASS_LIMIT	256

/*
 * Access macros for the AMBA UARTs
 */
#define UART_GET_INT_STATUS(p)	((readl((p)->membase + UARTIIR)) & 0xff)
#define UART_PUT_ICR(p, c)	writel((c), (p)->membase + UARTICR)
#define UART_GET_FR(p)		((readl((p)->membase + UARTFR)) & 0xff)
#define UART_GET_CHAR(p)	((readl((p)->membase + UARTDR)) & 0xff)
#define UART_PUT_CHAR(p, c)	writel((c), (p)->membase + UARTDR)
#define UART_GET_RSR(p)		((readl((p)->membase + UARTRSR)) & 0xff)
#define UART_PUT_RSR(p, c)	writel((c), (p)->membase + UARTRSR)
#define UART_GET_CR(p)		((readl((p)->membase + UARTCR)) & 0xff)
#define UART_PUT_CR(p,c)	writel((c), (p)->membase + UARTCR)
#define UART_GET_LCRL(p)	((readl((p)->membase + UARTCR_L)) & 0xff)
#define UART_PUT_LCRL(p,c)	writel((c), (p)->membase + UARTCR_L)
#define UART_GET_LCRM(p)	((readl((p)->membase + UARTCR_M)) & 0xff)
#define UART_PUT_LCRM(p,c)	writel((c), (p)->membase + UARTCR_M)
#define UART_GET_LCRH(p)	((readl((p)->membase + UARTCR_H)) & 0xff)
#define UART_PUT_LCRH(p,c)	writel((c), (p)->membase + UARTCR_H)
#define UART_RX_DATA(s)		(((s) & UARTFR_RXFE) == 0)
#define UART_TX_READY(s)	(((s) & UARTFR_TXFF) == 0)
#define UART_TX_EMPTY(p)	((UART_GET_FR(p) & UARTFR_TMSK) == 0)

#define UART_GET_MCR(p)		readl((p)->membase + UARTMCR)
#define UART_PUT_MCR(c, p)	writel((c), (p)->membase + UARTMCR)
#define UART_CLEAR_ECR(p)	writel( 0, (p)->membase + UARTECR)

#define UART_DUMMY_RSR_RX	256
#define UART_PORT_SIZE		65536

/*
 * We wrap our port structure around the generic uart_port.
 */
struct uart_ep93xx_port {
	struct uart_port	port;
	unsigned int		old_status;
};


static void
ep93xxuart_enable_clocks(struct uart_port *port)
{
	unsigned int uiSysDevCfg;

	/*
	 * Enable the clocks to this UART in CSC_syscon
	 * - Read DEVCFG
	 * - OR in the correct uart enable bit
	 * - Set the lock register
	 * - Write back to DEVCFG
	 */
	uiSysDevCfg = inl(SYSCON_DEVCFG);

	switch ((unsigned long)port->membase) {
	case UART1_BASE:
		uiSysDevCfg |= SYSCON_DEVCFG_U1EN;
		break;

	case UART2_BASE:
		uiSysDevCfg |= SYSCON_DEVCFG_U2EN;
		break;

	case UART3_BASE:
		uiSysDevCfg |= SYSCON_DEVCFG_U3EN;
		break;
	}

	SysconSetLocked( SYSCON_DEVCFG, uiSysDevCfg );
}

static void
ep93xxuart_disable_clocks(struct uart_port *port)
{
	unsigned int uiSysDevCfg;

	/*
	 * Disable the clocks to this UART in CSC_syscon
	 * - Read DEVCFG
	 * - AND to clear the correct uart enable bit
	 * - Set the lock register
	 * - Write back to DEVCFG
	 */
	uiSysDevCfg = inl(SYSCON_DEVCFG);

	switch ((unsigned long)port->membase) {
	case UART1_BASE:
		uiSysDevCfg &= ~((unsigned int)SYSCON_DEVCFG_U1EN);
		break;

	case UART2_BASE:
		uiSysDevCfg &= ~((unsigned int)SYSCON_DEVCFG_U2EN);
		break;

	case UART3_BASE:
		uiSysDevCfg &= ~((unsigned int)SYSCON_DEVCFG_U3EN);
		break;
	}

	SysconSetLocked( SYSCON_DEVCFG, uiSysDevCfg );
}

#if 1
static int
ep93xxuart_is_port_enabled(struct uart_port *port)
{
	unsigned int uiSysDevCfg;

	uiSysDevCfg = inl(SYSCON_DEVCFG);

	switch ((unsigned long)port->membase) {
	case UART1_BASE:
		uiSysDevCfg &= (unsigned int)SYSCON_DEVCFG_U1EN;
		break;

	case UART2_BASE:
		uiSysDevCfg &= (unsigned int)SYSCON_DEVCFG_U2EN;
		break;

	case UART3_BASE:
		uiSysDevCfg &= (unsigned int)SYSCON_DEVCFG_U3EN;
		break;
	}

	return( uiSysDevCfg != 0 );
}
#endif

static void
ep93xxuart_stop_tx(struct uart_port *port)
{
	unsigned int cr;

	cr = UART_GET_CR(port);
	cr &= ~UARTCR_TIE;
	UART_PUT_CR(port, cr);
}

static void
ep93xxuart_start_tx(struct uart_port *port)
{
	unsigned int cr;

	cr = UART_GET_CR(port);
	cr |= UARTCR_TIE;
	UART_PUT_CR(port, cr);
}

static void
ep93xxuart_stop_rx(struct uart_port *port)
{
	unsigned int cr;

	cr = UART_GET_CR(port);
	cr &= ~(UARTCR_RIE | UARTCR_RTIE);
	UART_PUT_CR(port, cr);
}

static void
ep93xxuart_enable_ms(struct uart_port *port)
{
	unsigned int cr;

	cr = UART_GET_CR(port);
	cr |= UARTCR_MSIE;
	UART_PUT_CR(port, cr);
}

static void
#ifdef SUPPORT_SYSRQ
ep93xxuart_rx_chars(struct uart_port *port, struct pt_regs *regs)
#else
ep93xxuart_rx_chars(struct uart_port *port)
#endif
{
	struct tty_struct *tty = port->info->tty;
	unsigned int status, ch, flag, rsr, max_count = 256;

if(((unsigned long)port->membase)==UART2_BASE)
{
printk("ep93 UART2 ep93xxuart_rx_chars\n");
}

	flag = 0;
	status = UART_GET_FR(port);
	while (UART_RX_DATA(status) && max_count--) {
		//if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
		//	tty->flip.work.func((void *)tty);
		//	if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
		//		printk(KERN_WARNING "TTY_DONT_FLIP set\n");
		//		return;
		//	}
		//}
		
		ch = UART_GET_CHAR(port);

		//*tty->flip.char_buf_ptr = ch;
		//*tty->flip.flag_buf_ptr = TTY_NORMAL;
		port->icount.rx++;

		/*
		 * Note that the error handling code is
		 * out of the main execution path
		 */
		rsr = UART_GET_RSR(port) | UART_DUMMY_RSR_RX;
		UART_PUT_RSR(port, 0);
		if (rsr & UARTRSR_ANY) {
			if (rsr & UARTRSR_BE) {
				rsr &= ~(UARTRSR_FE | UARTRSR_PE);
				port->icount.brk++;
				if (uart_handle_break(port))
					goto ignore_char;
			} else if (rsr & UARTRSR_PE)
				port->icount.parity++;
			else if (rsr & UARTRSR_FE)
				port->icount.frame++;
			if (rsr & UARTRSR_OE)
				port->icount.overrun++;

			rsr &= port->read_status_mask;

			if (rsr & UARTRSR_BE)
				//*tty->flip.flag_buf_ptr = TTY_BREAK;
				flag = TTY_BREAK;
			else if (rsr & UARTRSR_PE)
				//*tty->flip.flag_buf_ptr = TTY_PARITY;
				flag = TTY_PARITY;
			else if (rsr & UARTRSR_FE)
				//*tty->flip.flag_buf_ptr = TTY_FRAME;
				flag = TTY_FRAME;
		}

		if (uart_handle_sysrq_char(port, ch))
			goto ignore_char;

		//if ((rsr & port->ignore_status_mask) == 0) {
		//	tty->flip.flag_buf_ptr++;
		//	tty->flip.char_buf_ptr++;
		//	tty->flip.count++;
		//}
		//if ((rsr & UARTRSR_OE) &&
		//   tty->flip.count < TTY_FLIPBUF_SIZE) {
			/*
			 * Overrun is special, since it's reported
			 * immediately, and doesn't affect the current
			 * character
			 */
		//	*tty->flip.char_buf_ptr++ = 0;
		//	*tty->flip.flag_buf_ptr++ = TTY_OVERRUN;
		//	tty->flip.count++;
		//}

		uart_insert_char(port, rsr, UART01x_RSR_OE, ch, flag);

	ignore_char:
		status = UART_GET_FR(port);
	}
	tty_flip_buffer_push(tty);
	return;
}

static void
ep93xxuart_tx_chars(struct uart_port *port)
{
	struct circ_buf *xmit = &port->info->xmit;
	int count;

	if (port->x_char) {
		UART_PUT_CHAR(port, port->x_char);
		port->icount.tx++;
		port->x_char = 0;
		return;
	}
	if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
		ep93xxuart_stop_tx(port);
		return;
	}

	count = port->fifosize >> 1;
	do {
		UART_PUT_CHAR(port, xmit->buf[xmit->tail]);
		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
		port->icount.tx++;
		if (uart_circ_empty(xmit))
			break;
	} while (--count > 0);

	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
		uart_write_wakeup(port);

	if (uart_circ_empty(xmit))
		ep93xxuart_stop_tx(port);
}

static void
ep93xxuart_modem_status(struct uart_port *port)
{
	struct uart_ep93xx_port *uap = (struct uart_ep93xx_port *)port;
	unsigned int status, delta;

	UART_PUT_ICR(port, 0);

	status = UART_GET_FR(port) & UARTFR_MODEM_ANY;

	delta = status ^ uap->old_status;
	uap->old_status = status;

	if (!delta)
		return;

	if (delta & UARTFR_DCD)
		uart_handle_dcd_change(port, status & UARTFR_DCD);

	if (delta & UARTFR_DSR)
		port->icount.dsr++;

	if (delta & UARTFR_CTS)
		uart_handle_cts_change(port, status & UARTFR_CTS);

	wake_up_interruptible(&port->info->delta_msr_wait);
}

static irqreturn_t
ep93xxuart_int(int irq, void *dev_id)
{
	struct uart_port *port = dev_id;
	unsigned int status, pass_counter = EP93XX_ISR_PASS_LIMIT;


if(((unsigned long)port->membase)==UART2_BASE)
{
printk("ep93 UART2 ep93xxuart_int\n");
}


	spin_lock(&port->lock);

	status = UART_GET_INT_STATUS(port);
if(((unsigned long)port->membase)==UART2_BASE)
{
printk("status=%x\n",status);
}
	do {
		if (status & (UARTIIR_RTIS | UARTIIR_RIS))
#ifdef SUPPORT_SYSRQ
			ep93xxuart_rx_chars(port, regs);
#else
			ep93xxuart_rx_chars(port);
#endif
		if (status & UARTIIR_TIS)
			ep93xxuart_tx_chars(port);
		if (status & UARTIIR_MIS)
			ep93xxuart_modem_status(port);

		if (pass_counter-- == 0)
			break;

		status = UART_GET_INT_STATUS(port);
	} while (status & (UARTIIR_RTIS | UARTIIR_RIS | UARTIIR_TIS));

	spin_unlock(&port->lock);

	return IRQ_HANDLED;
}

static unsigned int
ep93xxuart_tx_empty(struct uart_port *port)
{
	return UART_GET_FR(port) & UARTFR_BUSY ? 0 : TIOCSER_TEMT;
}

static unsigned int
ep93xxuart_get_mctrl(struct uart_port *port)
{
	unsigned int result = 0;
	unsigned int status;

	status = UART_GET_FR(port);
	if (status & UARTFR_DCD)
		result |= TIOCM_CAR;
	if (status & UARTFR_DSR)
		result |= TIOCM_DSR;
	if (status & UARTFR_CTS)
		result |= TIOCM_CTS;

	return result;
}

static void
ep93xxuart_set_mctrl(struct uart_port *port, unsigned int mctrl)
{
	unsigned int ctrl = 0;

	ctrl = UART_GET_MCR(port);

#define BIT93(tiocmbit, uartbit)		\
	if (mctrl & tiocmbit)		\
		ctrl |= uartbit;	\
	else				\
		ctrl &= ~uartbit

	BIT93(TIOCM_RTS, UARTMCR_RTS);
	BIT93(TIOCM_DTR, UARTMCR_DTR);
	BIT93(TIOCM_OUT1, UARTMCR_OUT1);
	BIT93(TIOCM_OUT2, UARTMCR_OUT2);
	BIT93(TIOCM_LOOP, UARTMCR_LOOP);
#undef BIT93

	UART_PUT_MCR(ctrl, port);
}

static void
ep93xxuart_break_ctl(struct uart_port *port, int break_state)
{
	unsigned long flags;
	unsigned int lcr_h;

	spin_lock_irqsave(&port->lock, flags);
	lcr_h = UART_GET_LCRH(port);
	if (break_state == -1)
		lcr_h |= UARTLCR_H_BRK;
	else
		lcr_h &= ~UARTLCR_H_BRK;
	UART_PUT_LCRH(port, lcr_h);
	spin_unlock_irqrestore(&port->lock, flags);
}

static int
ep93xxuart_startup(struct uart_port *port)
{
	struct uart_ep93xx_port *uap = (struct uart_ep93xx_port *)port;
	int retval = -EINVAL;
	char *name = 0;

	/*
	 * Enable the clocks for this port.
	 */
	ep93xxuart_enable_clocks(port);

	/*
	 * Get the name of this port (used only for resource allocations).
	 */
	switch ((unsigned long)port->membase) {
	case UART1_BASE:
		name = "ttyAM0";
		break;
	case UART2_BASE:
		name = "ttyAM1";
		break;
	case UART3_BASE:
		name = "ttyAM2";
		break;
	}
printk("EP93XX UART--%s irq=%d\n",name,port->irq);
	/*
	 * Allocate the IRQ
	 */
	retval = request_irq(port->irq, ep93xxuart_int, 0 , name, port);
printk("irq is ok %d\n",retval);
	if (retval) {
		ep93xxuart_disable_clocks(port);
		return retval;
	}

	/*
	 * Allocate the memory region.
	 */
	if(request_mem_region(port->mapbase, UART_PORT_SIZE, name) == NULL) {
		printk("mem region fail\n");
		free_irq(port->irq, port);
		ep93xxuart_disable_clocks(port);
		return 1;
	}

	/*
	 * initialise the old status of the modem signals
	 */
	uap->old_status = UART_GET_FR(port) & UARTFR_MODEM_ANY;

printk("old status %x\n",uap->old_status);
	/*
	 * Finally, enable interrupts
	 */
	spin_lock_irq(&port->lock);
	UART_PUT_CR(port, UARTCR_UARTEN | UARTCR_RIE | UARTCR_RTIE|0x2);
	spin_unlock_irq(&port->lock);
	
	{
	unsigned int cr;

	cr = UART_GET_CR(port);
	printk("cr=%x\n",cr);
	}
	/*
	 * Success.
	 */
	return 0;
}

static void
ep93xxuart_shutdown(struct uart_port *port)
{
	/*
	 * disable all interrupts, disable the port
	 */
	UART_PUT_CR(port, 0);

	/*
	 * disable break condition and fifos
	 */
	UART_PUT_LCRH(port, UART_GET_LCRH(port) &
		      ~(UARTLCR_H_BRK | UARTLCR_H_FEN));

	/*
	 * Free the interrupt
	 */
	free_irq(port->irq, port);

	/*
	 * Release the memory region.
	 */
	release_mem_region(port->mapbase, UART_PORT_SIZE);

	/*
	 * Disable the clock.
	 */
	ep93xxuart_disable_clocks( port );
}

static void
ep93xxuart_set_termios(struct uart_port *port, struct ktermios *termios,
		       struct ktermios *old)
{
	unsigned int lcr_h, baud, quot;
	unsigned long flags;

	/*
	 * Ask the core to calculate the divisor for us.
	 */
	baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
	quot = uart_get_divisor(port, baud) - 1;
	
	/* byte size and parity */
	switch (termios->c_cflag & CSIZE) {
	case CS5:
		lcr_h = UARTLCR_H_WLEN_5;
		break;
	case CS6:
		lcr_h = UARTLCR_H_WLEN_6;
		break;
	case CS7:
		lcr_h = UARTLCR_H_WLEN_7;
		break;
	default: // CS8
		lcr_h = UARTLCR_H_WLEN_8;
		break;
	}
	if (termios->c_cflag & CSTOPB)
		lcr_h |= UARTLCR_H_STP2;
	if (termios->c_cflag & PARENB) {
		lcr_h |= UARTLCR_H_PEN;
		if (!(termios->c_cflag & PARODD))
			lcr_h |= UARTLCR_H_EPS;
	}
	if (port->fifosize > 1)
		lcr_h |= UARTLCR_H_FEN;

	spin_lock_irqsave(&port->lock, flags);

	/*
	 * Update the per-port timeout.
	 */
	uart_update_timeout(port, termios->c_cflag, baud);

	port->read_status_mask = UARTRSR_OE;
	if (termios->c_iflag & INPCK)
		port->read_status_mask |= UARTRSR_FE | UARTRSR_PE;
	if (termios->c_iflag & (BRKINT | PARMRK))
		port->read_status_mask |= UARTRSR_BE;

	/*
	 * Characters to ignore
	 */
	port->ignore_status_mask = 0;
	if (termios->c_iflag & IGNPAR)
		port->ignore_status_mask |= UARTRSR_FE | UARTRSR_PE;
	if (termios->c_iflag & IGNBRK) {
		port->ignore_status_mask |= UARTRSR_BE;
		/*
		 * If we're ignoring parity and break indicators,
		 * ignore overruns too (for real raw support).
		 */
		if (termios->c_iflag & IGNPAR)
			port->ignore_status_mask |= UARTRSR_OE;
	}

	/*
	 * Ignore all characters if CREAD is not set.
	 */
	if ((termios->c_cflag & CREAD) == 0)
		port->ignore_status_mask |= UART_DUMMY_RSR_RX;

	if (UART_ENABLE_MS(port, termios->c_cflag))
		ep93xxuart_enable_ms(port);

	UART_PUT_LCRL(port, quot & 0xff);
	UART_PUT_LCRM(port, (quot >> 8) & 0xff);
	UART_PUT_LCRH(port, lcr_h);

	spin_unlock_irqrestore(&port->lock, flags);
}

static const char *
ep93xxuart_type(struct uart_port *port)
{
	return port->type == PORT_AMBA ? "EP93XX" : NULL;
}

/*
 * Release the memory region(s) being used by 'port'
 */
static void
ep93xxuart_release_port(struct uart_port *port)
{
}

/*
 * Request the memory region(s) being used by 'port'
 */
static int
ep93xxuart_request_port(struct uart_port *port)
{
	return 0;
}

/*
 * Configure/autoconfigure the port.
 */
static void
ep93xxuart_config_port(struct uart_port *port, int flags)
{
	if (flags & UART_CONFIG_TYPE)
		port->type = PORT_AMBA;
}

/*
 * verify the new serial_struct (for TIOCSSERIAL).
 */
static int
ep93xxuart_verify_port(struct uart_port *port, struct serial_struct *ser)
{
	int ret = 0;
	if (ser->type != PORT_UNKNOWN && ser->type != PORT_AMBA)
		ret = -EINVAL;
	if (ser->irq < 0 || ser->irq >= NR_IRQS)
		ret = -EINVAL;
	if (ser->baud_base < 9600)
		ret = -EINVAL;
	return ret;
}

static struct uart_ops ep93xx_pops = {
	.tx_empty	= ep93xxuart_tx_empty,
	.set_mctrl	= ep93xxuart_set_mctrl,
	.get_mctrl	= ep93xxuart_get_mctrl,
	.stop_tx	= ep93xxuart_stop_tx,
	.start_tx	= ep93xxuart_start_tx,
	.stop_rx	= ep93xxuart_stop_rx,
	.enable_ms	= ep93xxuart_enable_ms,
	.break_ctl	= ep93xxuart_break_ctl,
	.startup	= ep93xxuart_startup,
	.shutdown	= ep93xxuart_shutdown,
	.set_termios	= ep93xxuart_set_termios,
	.type		= ep93xxuart_type,
	.release_port	= ep93xxuart_release_port,
	.request_port	= ep93xxuart_request_port,
	.config_port	= ep93xxuart_config_port,
	.verify_port	= ep93xxuart_verify_port,
};

static struct uart_ep93xx_port ep93xx_ports[UART_NR] = {
	{
		.port	= {
			.membase	= (void *)UART1_BASE,
			.mapbase	= /*HwRegToPhys(UART1_BASE)*/UART1_BASE_VIRT,
			.iotype		= UPIO_MEM,
			.irq		= IRQ_EP93XX_UART1,
			.uartclk	= 14745600,
			.fifosize	= 16,
			.ops		= &ep93xx_pops,
			.flags		= UPF_BOOT_AUTOCONF,
			.line		= 0,
		},
	},
#if !defined(CONFIG_EP93XX_IRDA)
	{
		.port	= {
			.membase	= (void *)UART2_BASE,
			.mapbase	= /*HwRegToPhys(UART2_BASE)*/UART2_BASE_VIRT,
			.iotype		= UPIO_MEM,
			.irq		= IRQ_EP93XX_UART2,
			.uartclk	= 14745600,
			.fifosize	= 16,
			.ops		= &ep93xx_pops,
			.flags		= UPF_BOOT_AUTOCONF,
			.line		= 1,
		},
	},
#endif
#if !defined(CONFIG_ARCH_EP9301) && !defined(CONFIG_ARCH_EP9302)
	{
		.port	= {
			.membase	= (void *)UART3_BASE,
			.mapbase	= /*HwRegToPhys(UART3_BASE)*/UART3_BASE_VIRT,
			.iotype		= UPIO_MEM,
			.irq		= IRQ_EP93XX_UART3,
			.uartclk	= 14745600,
			.fifosize	= 16,
			.ops		= &ep93xx_pops,
			.flags		= UPF_BOOT_AUTOCONF,
#if !defined(CONFIG_EP93XX_IRDA)
			.line		= 2,
#else
			.line		= 1,
#endif
		},
	}
#endif
};

#ifdef CONFIG_SERIAL_EP93XX_CONSOLE

static void
ep93xxuart_console_write_char(struct uart_port *port, char ch)
{
	unsigned int status;

	do {
		status = UART_GET_FR(port);
	} while (!UART_TX_READY(status));
	UART_PUT_CHAR(port, ch);
}

static void
ep93xxuart_console_write(struct console *co, const char *s, unsigned int count)
{
	struct uart_port *port = &ep93xx_ports[co->index].port;
	unsigned int status, old_cr, old_power;
	int i;

	old_power = ep93xxuart_is_port_enabled(port);
	if (!old_power)
		ep93xxuart_enable_clocks(port);

	/*
	 * First save the CR then disable the interrupts
	 */
	old_cr = UART_GET_CR(port);
	UART_PUT_CR(port, UARTCR_UARTEN);

	/*
	 * Now, do each character
	 */
	for (i = 0; i < count; i++) {
		ep93xxuart_console_write_char(port, s[i]);
		if (s[i] == '\n')
			ep93xxuart_console_write_char(port, '\r');
	}

	/*
	 * Finally, wait for transmitter to become empty
	 * and restore the TCR
	 */
	do {
		status = UART_GET_FR(port);
	} while (status & UARTFR_BUSY);
	UART_PUT_CR(port, old_cr);

	if (!old_power)
		ep93xxuart_disable_clocks(port);
}

static void __init
ep93xxuart_console_get_options(struct uart_port *port, int *baud, int *parity,
			       int *bits)
{
	if (UART_GET_CR(port) & UARTCR_UARTEN) {
		unsigned int lcr_h, lcr_m, lcr_l;

		lcr_h = UART_GET_LCRH(port);

		*parity = 'n';
		if (lcr_h & UARTLCR_H_PEN) {
			if (lcr_h & UARTLCR_H_EPS)
				*parity = 'e';
			else
				*parity = 'o';
		}

		if ((lcr_h & 0x60) == UARTLCR_H_WLEN_7)
			*bits = 7;
		else
			*bits = 8;

		lcr_m = UART_GET_LCRM(port);
		lcr_l = UART_GET_LCRL(port);

		*baud = port->uartclk / (16 * ((lcr_m * 256) + lcr_l + 1));
	}
}

static int __init
ep93xxuart_console_setup(struct console *co, char *options)
{
	struct uart_port *port;
	int baud = 57600;
	int bits = 8;
	int parity = 'n';
	int flow = 'n';

	/*
	 * Check whether an invalid uart number has been specified, and
	 * if so, search for the first available port that does have
	 * console support.
	 */
	if (co->index >= UART_NR)
		co->index = 0;
	port = &ep93xx_ports[co->index].port;

	if (options)
		uart_parse_options(options, &baud, &parity, &bits, &flow);
	else
		ep93xxuart_console_get_options(port, &baud, &parity, &bits);

	return uart_set_options(port, co, baud, parity, bits, flow);
}

static struct console ep93xx_console;
#define EP93XX_CONSOLE	&ep93xx_console
#else
#define EP93XX_CONSOLE	NULL
#endif

static struct uart_driver ep93xx_reg = {
	.driver_name		= "ttyAM",
	.dev_name		= "ttyAM",
	.major			= SERIAL_EP93XX_MAJOR,
	.minor			= SERIAL_EP93XX_MINOR,
	.nr			= UART_NR,
	.cons			= EP93XX_CONSOLE,
};


/*
 * The 'index' element of this field selects which UART to use for
 * console.  For ep93xx, valid values are 0, 1, and 2.  If you set
 * it to -1, then uart_get_console will search for the first UART
 * which is the same as setting it to 0.
 */
static struct console ep93xx_console = {
	.name		= "ttyAM",
	.write		= ep93xxuart_console_write,
	.device		= uart_console_device,
	.setup		= ep93xxuart_console_setup,
	.flags		= CON_PRINTBUFFER,
	.index		= -1,
	.data		= &ep93xx_reg,
};

static int __init
ep93xxuart_console_init(void)
{
	register_console(&ep93xx_console);
	return 0;
}
console_initcall(ep93xxuart_console_init);

static struct resource uarts[UART_NR] = {
	[0] = {
		.name		= "uart1",
		.start		= /*HwRegToPhys(UART1_BASE)*/UART1_BASE_VIRT,
		.end		= /*HwRegToPhys(UART1_BASE)*/UART1_BASE_VIRT + 0x0000ffff,
	},
#if !defined(CONFIG_EP93XX_IRDA)
	[1] = {
		.name		= "uart2",
		.start		= /*HwRegToPhys(UART2_BASE)*/UART2_BASE_VIRT,
		.end		= /*HwRegToPhys(UART2_BASE)*/UART2_BASE_VIRT + 0x0000ffff,
	},
#endif
#if !defined(CONFIG_ARCH_EP9301) && !defined(CONFIG_ARCH_EP9302)
	[2] = {
		.name		= "uart3",
		.start		= /*HwRegToPhys(UART3_BASE)*/UART3_BASE_VIRT,
		.end		= /*HwRegToPhys(UART3_BASE)*/UART3_BASE_VIRT + 0x0000ffff,
	},
#endif
};

static int __init
ep93xxuart_init(void)
{
	int ret, i;

	ret = uart_register_driver(&ep93xx_reg);
	if (ret == 0) {
		for (i = 0; i < UART_NR; i++) {
			request_resource(&iomem_resource, &uarts[i]);
			uart_add_one_port(&ep93xx_reg, &ep93xx_ports[i].port);
		}
	}
	return ret;
}

static void __exit ep93xxuart_exit(void)
{
	int i;

	for (i = 0; i < UART_NR; i++)
		uart_remove_one_port(&ep93xx_reg, &ep93xx_ports[i].port);
	uart_unregister_driver(&ep93xx_reg);
}

module_init(ep93xxuart_init);
module_exit(ep93xxuart_exit);

MODULE_AUTHOR("ARM Ltd/Deep Blue Solutions Ltd/Cirrus Logic, Inc.");
MODULE_DESCRIPTION("EP93xx ARM serial port driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS_CHARDEV(SERIAL_EP93XX_MAJOR, SERIAL_EP93XX_MINOR);

^ permalink raw reply

* Re: performance problem: "git commit filename"
From: Linus Torvalds @ 2008-01-13 17:24 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Git Mailing List, Kristian H?gsberg
In-Reply-To: <7vd4s6qal0.fsf@gitster.siamese.dyndns.org>



On Sun, 13 Jan 2008, Junio C Hamano wrote:
> 
> The attached is a quick and dirty hack which may or may not
> help.  It all looks sane, this also is some core code, and meant
> only for discussion and not application.

I don't think this will help.

You never set CE_UPTODATE, except in the "fill_stat_cache_info()" 
function, but that one will never be called for an old file that already 
matched the stat.

So at a minimum, you should also make ie_match_stat() set CE_UPTODATE if 
it matches. Or something.

			Linus

^ permalink raw reply

* Re: Digging through old vendor code
From: Jon Smirl @ 2008-01-13 17:04 UTC (permalink / raw)
  To: linux@horizon.com; +Cc: git, torvalds
In-Reply-To: <20080113162806.13991.qmail@science.horizon.com>

The vendor gave me an edited file with support for their device. The
original was copied from the kernel somewhere around 2.6.15 and then
edited. Nobody remembers what the source file was but there are a
couple of fairly close matches.

Diffing against the current kernel mixes the two sets of changes -
what the vendor did and what changed in the core kernel. I'm sorting
this out by hand but it is 3,000 lines of diffs.

It is an interesting problem to use the git history to try and
discover the original source file.

-- 
Jon Smirl
jonsmirl@gmail.com

^ permalink raw reply

* Re: performance problem: "git commit filename"
From: Linus Torvalds @ 2008-01-13 16:57 UTC (permalink / raw)
  To: Daniel Barkalow; +Cc: Junio C Hamano, Git Mailing List, Kristian H?gsberg
In-Reply-To: <alpine.LNX.1.00.0801130028460.13593@iabervon.org>



On Sun, 13 Jan 2008, Daniel Barkalow wrote:
> 
> The only issue I know about with using unpack_trees in C as a replacement 
> for read-tree in shell is that unpack_trees leaves "deletion" index 
> entries in memory which are not written to disk, but may surprise some 
> code (these are used to allow -u to remove the files from the working 
> tree).

I certainly agree that this patch should be double-checked. I'm pretty 
sure the issue you mention wouldn't be an issue, since the end result is 
only used for actually updating the index and writing it out as a tree 
(both of which should handle the magic zero ce_mode case ok), but it would 
certainly be good to walk through all cases.

			Linus

^ permalink raw reply

* [PATCH v3] safecrlf: Add mechanism to warn about irreversible crlf conversions
From: Steffen Prohaska @ 2008-01-13 16:30 UTC (permalink / raw)
  To: gitster; +Cc: dpotapov, torvalds, git, Steffen Prohaska

This one could be applied.

I mentioned earlier that crlf_to_git() would be called twice.  Unfortunately,
I can't reproduce this behaviour and are not even sure if it ever happend.
Maybe it was only an illusion in my terminal?

    Steffen

---- snip snap ---

CRLF conversion bears a slight chance of corrupting data.
autocrlf=true will convert CRLF to LF during commit and LF to
CRLF during checkout.  A file that containes a mixture of LF and
CRLF before the commit cannot be recreated by git.  For text
files this does not really matter because we do not care about
the line endings anyway; but for binary files that are
accidentally classified as text the conversion can result in
corrupted data.

If you recognize such corruption during commit you can easily fix
it by setting the conversion type explicitly in .gitattributes.
Right after committing you still have the original file in your
work tree and this file is not yet corrupted.

However, in mixed Windows/Unix environments text files quite
easily can end up containing a mixture of CRLF and LF line
endings and git should handle such situations gracefully.  For
example a user could copy a CRLF file from Windows to Unix and
mix it with an existing LF file there.  The result would contain
both types of line endings.

Unfortunately, the desired effect of cleaning up text files
with mixed lineendings and undesired effect of corrupting binary
files can not be distinguished.  In both cases CRLF are removed
in an irreversible way.  For text files this is the right thing
to do, while for binary file its corrupting data.

In a sane environment committing and checking out the same file
should not modify the origin file in the work tree.  For
autocrlf=input the original file must not contain CRLF.  For
autocrlf=true the original file must not contain LF without
preceding CR.  Otherwise the conversion is irreversible.  Note,
git might be able to recreate the original file with different
autocrlf settings, but in the current environment checking out
will yield a file that differs from the file before the commit.

This patch adds a mechanism that can either warn the user about
an irreversible conversion or can even refuse to convert.  The
mechanism is controlled by the variable core.safecrlf, with the
following values
 - false: disable safecrlf mechanism
 - warn: warn about irreversible conversions
 - true: refuse irreversible conversions

The default is to warn.

The concept of a safety check was originally proposed in a similar
way by Linus Torvalds.  Thanks to Dimitry Potapov for insisting
on getting the naked LF/autocrlf=true case right.

Signed-off-by: Steffen Prohaska <prohaska@zib.de>
---
 Documentation/config.txt        |   21 ++++++++++++++++++
 Documentation/gitattributes.txt |    5 ++++
 cache.h                         |    8 +++++++
 config.c                        |    9 +++++++
 convert.c                       |   28 +++++++++++++++++++++--
 environment.c                   |    1 +
 t/t0020-crlf.sh                 |   45 +++++++++++++++++++++++++++++++++++++++
 7 files changed, 114 insertions(+), 3 deletions(-)

diff --git a/Documentation/config.txt b/Documentation/config.txt
index df091d1..d2a9fdd 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -139,6 +139,27 @@ core.autocrlf::
 	"text" (i.e. be subjected to the autocrlf mechanism) is
 	decided purely based on the contents.
 
+core.safecrlf::
+	If true, makes git check if converting `CRLF` as controlled by
+	`core.autocrlf` is reversible.  Git will check if committing a
+	file followed by checking out the same file will yield the
+	original file in the work tree.  If this is not the case for
+	the current setting of `core.autocrlf`, git will reject the
+	file.  The variable can be set to "warn", in which case git
+	will only warn about an irreversible conversion but accept the
+	file.
++
+Note, this safety check does not mean that a checkout will generate a
+file identical to the original file for different settings of
+`core.autocrlf`, but only for the current one.  For example, a text
+file with `LF` would be accepted with `core.autocrlf=input` and could
+later be checked out with `core.autocrlf=true`, in which case the
+resulting file would contain `CRLF`, although the original file
+contained `LF`.  However, in both work trees the line endings would be
+consistent, that is either all `LF` or all `CRLF`, but never mixed.  A
+file with mixed line endings would be reported by the `core.safecrlf`
+mechanism.
+
 core.symlinks::
 	If false, symbolic links are checked out as small plain files that
 	contain the link text. linkgit:git-update-index[1] and
diff --git a/Documentation/gitattributes.txt b/Documentation/gitattributes.txt
index 35a29fd..2ffe1fb 100644
--- a/Documentation/gitattributes.txt
+++ b/Documentation/gitattributes.txt
@@ -133,6 +133,11 @@ When `core.autocrlf` is set to "input", line endings are
 converted to LF upon checkin, but there is no conversion done
 upon checkout.
 
+If `core.safecrlf` is set to "true" or "warn", git verifies if
+the conversion is reversible for the current setting of
+`core.autocrlf`.  For "true", git rejects irreversible
+conversions; for "warn", git only prints a warning but accepts
+an irreversible conversion.
 
 `ident`
 ^^^^^^^
diff --git a/cache.h b/cache.h
index 39331c2..4e03e3d 100644
--- a/cache.h
+++ b/cache.h
@@ -330,6 +330,14 @@ extern size_t packed_git_limit;
 extern size_t delta_base_cache_limit;
 extern int auto_crlf;
 
+enum safe_crlf {
+	SAFE_CRLF_FALSE = 0,
+	SAFE_CRLF_FAIL = 1,
+	SAFE_CRLF_WARN = 2,
+};
+
+extern enum safe_crlf safe_crlf;
+
 #define GIT_REPO_VERSION 0
 extern int repository_format_version;
 extern int check_repository_format(void);
diff --git a/config.c b/config.c
index 857deb6..0a46046 100644
--- a/config.c
+++ b/config.c
@@ -407,6 +407,15 @@ int git_default_config(const char *var, const char *value)
 		return 0;
 	}
 
+	if (!strcmp(var, "core.safecrlf")) {
+		if (value && !strcasecmp(value, "warn")) {
+			safe_crlf = SAFE_CRLF_WARN;
+			return 0;
+		}
+		safe_crlf = git_config_bool(var, value);
+		return 0;
+	}
+
 	if (!strcmp(var, "user.name")) {
 		strlcpy(git_default_name, value, sizeof(git_default_name));
 		return 0;
diff --git a/convert.c b/convert.c
index 4df7559..c9678ee 100644
--- a/convert.c
+++ b/convert.c
@@ -90,9 +90,6 @@ static int crlf_to_git(const char *path, const char *src, size_t len,
 		return 0;
 
 	gather_stats(src, len, &stats);
-	/* No CR? Nothing to convert, regardless. */
-	if (!stats.cr)
-		return 0;
 
 	if (action == CRLF_GUESS) {
 		/*
@@ -110,6 +107,20 @@ static int crlf_to_git(const char *path, const char *src, size_t len,
 			return 0;
 	}
 
+	if (safe_crlf && auto_crlf > 0 && action != CRLF_INPUT) {
+		/* CRLFs would be added by checkout: check if we have "naked" LFs */
+		if (stats.lf != stats.crlf) {
+			if (safe_crlf == SAFE_CRLF_WARN)
+				warning("Checkout will replace LFs with CRLF in %s", path);
+			else
+				die("Checkout would replace LFs with CRLF in %s", path);
+		}
+	}
+
+	/* Optimization: No CR? Nothing to convert, regardless. */
+	if (!stats.cr)
+		return 0;
+
 	/* only grow if not in place */
 	if (strbuf_avail(buf) + buf->len < len)
 		strbuf_grow(buf, len - buf->len);
@@ -132,6 +143,17 @@ static int crlf_to_git(const char *path, const char *src, size_t len,
 				*dst++ = c;
 		} while (--len);
 	}
+
+	if (safe_crlf && (action == CRLF_INPUT || auto_crlf <= 0)) {
+		/* CRLFs would not be restored by checkout: check if we removed CRLFs */
+		if (buf->len != dst - buf->buf) {
+			if (safe_crlf == SAFE_CRLF_WARN)
+				warning("Stripped CRLF from %s.", path);
+			else
+				die("Refusing to strip CRLF from %s.", path);
+		}
+	}
+
 	strbuf_setlen(buf, dst - buf->buf);
 	return 1;
 }
diff --git a/environment.c b/environment.c
index 18a1c4e..e351e99 100644
--- a/environment.c
+++ b/environment.c
@@ -35,6 +35,7 @@ int pager_use_color = 1;
 char *editor_program;
 char *excludes_file;
 int auto_crlf = 0;	/* 1: both ways, -1: only when adding git objects */
+enum safe_crlf safe_crlf = SAFE_CRLF_WARN;
 unsigned whitespace_rule_cfg = WS_DEFAULT_RULE;
 
 /* This is set by setup_git_dir_gently() and/or git_default_config() */
diff --git a/t/t0020-crlf.sh b/t/t0020-crlf.sh
index 89baebd..e2e0f7b 100755
--- a/t/t0020-crlf.sh
+++ b/t/t0020-crlf.sh
@@ -8,6 +8,10 @@ q_to_nul () {
 	tr Q '\000'
 }
 
+q_to_cr () {
+	tr Q '\015'
+}
+
 append_cr () {
 	sed -e 's/$/Q/' | tr Q '\015'
 }
@@ -42,6 +46,47 @@ test_expect_success setup '
 	echo happy.
 '
 
+test_expect_failure 'safecrlf: autocrlf=input, all CRLF' '
+
+	git repo-config core.autocrlf input &&
+	git repo-config core.safecrlf true &&
+
+	for w in I am all CRLF; do echo $w; done | append_cr >allcrlf &&
+	git add allcrlf
+'
+
+test_expect_failure 'safecrlf: autocrlf=input, mixed LF/CRLF' '
+
+	git repo-config core.autocrlf input &&
+	git repo-config core.safecrlf true &&
+
+	for w in Oh here is CRLFQ in text; do echo $w; done | q_to_cr >mixed &&
+	git add mixed
+'
+
+test_expect_failure 'safecrlf: autocrlf=true, all LF' '
+
+	git repo-config core.autocrlf true &&
+	git repo-config core.safecrlf true &&
+
+	for w in I am all LF; do echo $w; done >alllf &&
+	git add alllf
+'
+
+test_expect_failure 'safecrlf: autocrlf=true mixed LF/CRLF' '
+
+	git repo-config core.autocrlf true &&
+	git repo-config core.safecrlf true &&
+
+	for w in Oh here is CRLFQ in text; do echo $w; done | q_to_cr >mixed &&
+	git add mixed
+'
+
+test_expect_success 'switch off autocrlf, safecrlf' '
+	git repo-config core.autocrlf false &&
+	git repo-config core.safecrlf false
+'
+
 test_expect_success 'update with autocrlf=input' '
 
 	rm -f tmp one dir/two three &&
-- 
1.5.4.rc2.60.g46ee

^ permalink raw reply related

* Re: Digging through old vendor code
From: linux @ 2008-01-13 16:28 UTC (permalink / raw)
  To: git, jonsmirl, torvalds; +Cc: linux

> Heh. Maybe you could just use the rename logic?
>
> [How-to snipped]

Clever idea, but I think the real problem was to figure out what VERSION
of the file was the base; i.e. to look through history.

Still, it should be possible to adapt the technique...

#!/bin/sh

# List of files we are looking to copy from
SRC="drivers/serial/"
# Temporary work directory
DST=/tmp/work
git-clone -l -n -s . $DST
{ cd $DST; git-symbolic-ref HEAD refs/heads/DELETEME; }
for i in `git-rev-list v2.6.20..v2.6.24-rc6 -- $SRC`; do
        j=`git-describe $i`
        git-archive --prefix="$j/" $i -- $SRC | tar xf - -C $DST
        # This is abusing the index, but it saves space...
        { cd $DST; git add $j; rm -rf $j; }
done

# And  now proceed as per Linus's idea...
# Except we have it all in the index; no need
# to actually make a commit...

cd $DST
cp $target_file $DST
{ cd $DST; git-diff-files -M...; }


Maybe a real git wizard will show me how to insert the index entries
directly without ever doing anything as pedestrian as extracting, hashing,
and then deleting the files, but it's still not that bad.

And it's kind of a neat example of using the index as a staging area
for a commit.

(Exercise for the reader: the above gets a complete copy of every file in
the directory for every commit in qhich ANY file in the directory changed.
Better would be to do the git-rev-list per-file, so you only add unique
file versions.  This requires an outer loop over file names and a more
careful pathname specification to git add in the inner loop.)

^ permalink raw reply

* [PATCH] Teach git-submodule to use master's remote when updating subprojects
From: Mark Levedahl @ 2008-01-13 16:27 UTC (permalink / raw)
  To: gitster; +Cc: git, Mark Levedahl
In-Reply-To: <1200241631-3300-4-git-send-email-mlevedahl@gmail.com>

Modules that are defined using relative urls to the master project are
assumed to be completely owned by the project. When running
"submodule update" from the top level, it is reasonable that the entire
project exists at the current master's remote. Using the
branch.$name.remote machinery, this remote can be different for each
branch and can be different than the current defaults in each submodule.

This teaches submodule to:

1) Possibly define the current master's remote in each submodule, using
the same relative url used by submodule init.
2) Fetch each submodule's updates from the master's remote.

Submodules defined using absolute urls (not relative to the parent) are
not touched by this logic. These modules are assumed to be independent
of the master project so submodule can do no better than to fetch from
their currently defined default remotes as already done.


Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
---
 git-submodule.sh |   20 +++++++++++++++++++-
 1 files changed, 19 insertions(+), 1 deletions(-)

diff --git a/git-submodule.sh b/git-submodule.sh
index 42be4b9..5b4b16f 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -209,11 +209,14 @@ modules_init()
 
 #
 # Update each submodule path to correct revision, using clone and checkout as needed
+# For owned submodules (defined using relative url), we use master project's remote
+# and define that in each submodule if not already there
 #
 # $@ = requested paths (default to all)
 #
 modules_update()
 {
+	master_remote=$(get_default_remote)
 	git ls-files --stage -- "$@" | grep -e '^160000 ' |
 	while read mode sha1 stage path
 	do
@@ -240,9 +243,24 @@ modules_update()
 			die "Unable to find current revision in submodule path '$path'"
 		fi
 
+		baseurl="$(GIT_CONFIG=.gitmodules git config submodule."$name".url)"
+		case "$baseurl" in
+		./*|../*)
+			fetch_remote=$master_remote
+			(unset GIT_DIR ; cd "$path" && git config remote."$fetch_remote".url > nul) ||
+			(
+				absurl="$(resolve_relative_url $baseurl)"
+				unset GIT_DIR; cd "$path" && git remote add "$master_remote" "$absurl"
+			) || die "Unable to define remote '$fetch_remote' in submodule path '$path'"
+			;;
+		*)
+			fetch_remote=
+			;;
+		esac
+
 		if test "$subsha1" != "$sha1"
 		then
-			(unset GIT_DIR; cd "$path" && git-fetch &&
+			(unset GIT_DIR; cd "$path" && git-fetch "$fetch_remote" &&
 				git-checkout -q "$sha1") ||
 			die "Unable to checkout '$sha1' in submodule path '$path'"
 
-- 
1.5.4.rc3.14.gc50f

^ permalink raw reply related

* [PATCH] git-submodule - Possibly inherit parent's default remote on init/clone
From: Mark Levedahl @ 2008-01-13 16:27 UTC (permalink / raw)
  To: gitster; +Cc: git, Mark Levedahl
In-Reply-To: <1200241631-3300-3-git-send-email-mlevedahl@gmail.com>

For submodules defined relative to their parent, it is likely that the
parent's defined default remote is correct for the child as well. This
allows use of remote names other than "origin", important as managed
submodules are typically checked out on a detached head and therefore
submodule-update invokes git-fetch using the default remote. Without this
change, submodules effectively had to have a default remote of "origin."

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
---
 Documentation/git-submodule.txt |    8 +++++---
 git-submodule.sh                |   19 +++++++++++++------
 2 files changed, 18 insertions(+), 9 deletions(-)

diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt
index cffc6d4..440e234 100644
--- a/Documentation/git-submodule.txt
+++ b/Documentation/git-submodule.txt
@@ -36,9 +36,11 @@ status::
 
 init::
 	Initialize the submodules, i.e. register in .git/config each submodule
-	name and url found in .gitmodules. The key used in .git/config is
-	`submodule.$name.url`. This command does not alter existing information
-	in .git/config.
+	name and url found in .gitmodules, along with the default remote origin.
+	For submodules using a relative url, the default remote is inherited
+	from the parent project, for absolute urls the default "origin" is used.
+	The key used in .git/config is submodule.$name.url`. This command does
+	not alter existing information in .git/config.
 
 update::
 	Update the registered submodules, i.e. clone missing submodules and
diff --git a/git-submodule.sh b/git-submodule.sh
index ad9fe62..42be4b9 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -7,6 +7,7 @@
 USAGE='[--quiet] [--cached] [add <repo> [-b branch]|status|init|update] [--] [<path>...]'
 OPTIONS_SPEC=
 . git-sh-setup
+. git-parse-remote
 require_work_tree
 
 add=
@@ -43,9 +44,7 @@ get_repo_base() {
 # Resolve relative url by appending to parent's url
 resolve_relative_url ()
 {
-	branch="$(git symbolic-ref HEAD 2>/dev/null)"
-	remote="$(git config branch.${branch#refs/heads/}.remote)"
-	remote="${remote:-origin}"
+	remote="$(get_default_remote)"
 	remoteurl="$(git config remote.$remote.url)" ||
 		die "remote ($remote) does not have a url in .git/config"
 	url="$1"
@@ -95,6 +94,7 @@ module_clone()
 {
 	path=$1
 	url=$2
+	origin=${3:-origin}
 
 	# If there already is a directory at the submodule path,
 	# expect it to be empty (since that is the default checkout
@@ -110,7 +110,7 @@ module_clone()
 	test -e "$path" &&
 	die "A file already exist at path '$path'"
 
-	git-clone -n "$url" "$path" ||
+	git-clone -n -o "$origin" "$url" "$path" ||
 	die "Clone of '$url' into submodule path '$path' failed"
 }
 
@@ -130,9 +130,11 @@ module_add()
 		usage
 	fi
 
+	origin=origin
 	case "$repo" in
 	./*|../*)
 		# dereference source url relative to parent's url
+		origin=$(get_default_remote)
 		realrepo="$(resolve_relative_url $repo)" ;;
 	*)
 		# Turn the source into an absolute path if
@@ -157,7 +159,7 @@ module_add()
 	git ls-files --error-unmatch "$path" > /dev/null 2>&1 &&
 	die "'$path' already exists in the index"
 
-	module_clone "$path" "$realrepo" || exit
+	module_clone "$path" "$realrepo" "$origin" || exit
 	(unset GIT_DIR; cd "$path" && git checkout -q ${branch:+-b "$branch" "origin/$branch"}) ||
 	die "Unable to checkout submodule '$path'"
 	git add "$path" ||
@@ -189,12 +191,15 @@ modules_init()
 		die "No url found for submodule path '$path' in .gitmodules"
 
 		# Possibly a url relative to parent
+		origin=origin
 		case "$url" in
 		./*|../*)
 			url="$(resolve_relative_url "$url")"
+			origin=$(get_default_remote)
 			;;
 		esac
 
+		git config submodule."$name".origin "$origin" &&
 		git config submodule."$name".url "$url" ||
 		die "Failed to register url for submodule path '$path'"
 
@@ -222,10 +227,12 @@ modules_update()
 			say "Submodule path '$path' not initialized"
 			continue
 		fi
+		origin=$(git config submodule."$name".origin)
+		origin=${origin:-origin}
 
 		if ! test -d "$path"/.git
 		then
-			module_clone "$path" "$url" || exit
+			module_clone "$path" "$url" "$origin" || exit
 			subsha1=
 		else
 			subsha1=$(unset GIT_DIR; cd "$path" &&
-- 
1.5.4.rc3.14.gc50f

^ permalink raw reply related

* [PATCH] git-clone - Set remotes.origin config variable
From: Mark Levedahl @ 2008-01-13 16:27 UTC (permalink / raw)
  To: gitster; +Cc: git, Mark Levedahl
In-Reply-To: <1200241631-3300-2-git-send-email-mlevedahl@gmail.com>

This records the users choice of default remote name (by default "origin")
as given by the -o option.

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
---
 Documentation/git-clone.txt |    3 ++-
 git-clone.sh                |    1 +
 2 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt
index fdccbd4..6c15fa4 100644
--- a/Documentation/git-clone.txt
+++ b/Documentation/git-clone.txt
@@ -95,7 +95,8 @@ OPTIONS
 --origin <name>::
 -o <name>::
 	Instead of using the remote name 'origin' to keep track
-	of the upstream repository, use <name> instead.
+	of the upstream repository, use <name> instead. The name
+	is recorded in the core.origin config variable.
 
 --upload-pack <upload-pack>::
 -u <upload-pack>::
diff --git a/git-clone.sh b/git-clone.sh
index b4e858c..7208d68 100755
--- a/git-clone.sh
+++ b/git-clone.sh
@@ -242,6 +242,7 @@ fi &&
 export GIT_DIR &&
 GIT_CONFIG="$GIT_DIR/config" git-init $quiet ${template+"$template"} || usage
 
+git config core.origin $origin
 if test -n "$bare"
 then
 	GIT_CONFIG="$GIT_DIR/config" git config core.bare true
-- 
1.5.4.rc3.14.gc50f

^ permalink raw reply related

* [PATCH] git-remote - Unset core.origin when deleting the default remote
From: Mark Levedahl @ 2008-01-13 16:27 UTC (permalink / raw)
  To: gitster; +Cc: git, Mark Levedahl
In-Reply-To: <1200241631-3300-1-git-send-email-mlevedahl@gmail.com>

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
---
 git-remote.perl |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/git-remote.perl b/git-remote.perl
index d13e4c1..75d2371 100755
--- a/git-remote.perl
+++ b/git-remote.perl
@@ -328,6 +328,11 @@ sub rm_remote {
 
 	$git->command('config', '--remove-section', "remote.$name");
 
+	my $defremote = $git->config("core.origin");
+	if (defined $defremote && $defremote eq $name) {
+	       $git->command("config", "--unset", "core.origin");
+	}
+
 	eval {
 	    my @trackers = $git->command('config', '--get-regexp',
 			'branch.*.remote', $name);
-- 
1.5.4.rc3.14.gc50f

^ permalink raw reply related

* [PATCH] Teach remote machinery about core.origin config variable
From: Mark Levedahl @ 2008-01-13 16:27 UTC (permalink / raw)
  To: gitster; +Cc: git, Mark Levedahl
In-Reply-To: <478A3284.1000102@gmail.com>

This introduces a new configuration variable, core.origin, that
defines the name of the default remote to be used. Traditionally, this
is "origin", and could be overridden for a given branch. This change
introduces a way to redefine the default as desired and have that honored
regardless of the currently checked out head (e.g., core.origin is
used when on a detached head or any other non-tracking branch).

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
---
 Documentation/config.txt |    6 ++++++
 git-parse-remote.sh      |    5 +++--
 remote.c                 |   11 ++++++++++-
 3 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/Documentation/config.txt b/Documentation/config.txt
index df091d1..b7241cf 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -291,6 +291,12 @@ core.editor::
 	`GIT_EDITOR` environment, `core.editor`, `VISUAL` and
 	`EDITOR` environment variables and then finally `vi`.
 
+core.origin::
+	The name of the remote used by default for fetch / pull. If unset,
+	origin is assumed. This value is used whenever the current branch
+	has no corresponding branch.<name>.remote, such as when working on
+	a detached head.
+
 core.pager::
 	The command that git will use to paginate output.  Can be overridden
 	with the `GIT_PAGER` environment variable.
diff --git a/git-parse-remote.sh b/git-parse-remote.sh
index 695a409..c7ac7c7 100755
--- a/git-parse-remote.sh
+++ b/git-parse-remote.sh
@@ -56,8 +56,9 @@ get_remote_url () {
 
 get_default_remote () {
 	curr_branch=$(git symbolic-ref -q HEAD | sed -e 's|^refs/heads/||')
-	origin=$(git config --get "branch.$curr_branch.remote")
-	echo ${origin:-origin}
+	git config --get "branch.$curr_branch.remote" ||
+	git config --get "core.origin" ||
+	echo origin
 }
 
 get_remote_default_refs_for_push () {
diff --git a/remote.c b/remote.c
index 0e00680..302d499 100644
--- a/remote.c
+++ b/remote.c
@@ -10,6 +10,7 @@ static int allocated_branches;
 
 static struct branch *current_branch;
 static const char *default_remote_name;
+static const char *core_origin;
 
 #define BUF_SIZE (2048)
 static char buffer[BUF_SIZE];
@@ -233,6 +234,11 @@ static int handle_config(const char *key, const char *value)
 			add_merge(branch, xstrdup(value));
 		return 0;
 	}
+	if (!strcmp(key, "core.origin")) {
+		if (value)
+			core_origin = xstrdup(value);
+		return 0;
+	}
 	if (prefixcmp(key,  "remote."))
 		return 0;
 	name = key + 7;
@@ -291,7 +297,6 @@ static void read_config(void)
 	int flag;
 	if (default_remote_name) // did this already
 		return;
-	default_remote_name = xstrdup("origin");
 	current_branch = NULL;
 	head_ref = resolve_ref("HEAD", sha1, 0, &flag);
 	if (head_ref && (flag & REF_ISSYMREF) &&
@@ -300,6 +305,10 @@ static void read_config(void)
 			make_branch(head_ref + strlen("refs/heads/"), 0);
 	}
 	git_config(handle_config);
+	if (!default_remote_name) {
+		default_remote_name = core_origin ?
+		core_origin : xstrdup("origin");
+	}
 }
 
 struct refspec *parse_ref_spec(int nr_refspec, const char **refspec)
-- 
1.5.4.rc3.14.gc50f

^ permalink raw reply related

* Re: Adding Git to Better SCM Initiative : Comparison
From: Jakub Narebski @ 2008-01-13 16:25 UTC (permalink / raw)
  To: Matthieu Moy; +Cc: linux, git
In-Reply-To: <vpqd4s5ycvv.fsf@bauges.imag.fr>

On Sun, 13 January 2008, Matthieu Moy wrote:
> linux@horizon.com writes:

Can't you use a name or nick, by the way?
 
> > "Rename support" is a kludge to make a fundamentally broken model
> > less painful.
> 
> It's not.
> 
> Git _has_ rename support. Look into the code, you'll find some code
> whose purpose is to manage renames. And _no_, rename support is not
> just a direct consequence of commits being atomic.
> 
> Atomic commit help, but if you do nothing else, moving a file and then
> trying to merge will fail for example. So, in addition to atomic
> commits, you have at least 3 options : explicit file ID (bzr),
> recording renames (hg), or detecting renames after-the-fact (git).

Rename detection / dealing with renames in SCMs is needed for:
0. Recovering previous state
1. Merging correct files
2. Forensic (log, blame) across renames / code movement

While the fact that Git is snapshot based and has whole-tree atomic
commits (Subversion does too) make it automatically obey 0., some
kind of rename support is needed for merges (Better SCM has it in TODO),
and for examining history, for example if the file was renamed in
one of the branches.

For example "git log --follow=gitweb/gitweb.perl" follows history of
specified file (IIRC this does not work for directory; but then Git
does not per se tracks directories), even if it was called gitweb.cgi
at the very beginning. "git blame -M" assign commit to a line denoting
when line was created, and not when it was moved (perhaps across file
boundaries) in the current place.

-- 
Jakub Narebski
Poland

^ permalink raw reply

* Re: [PATCH] Teach remote machinery about remotes.default config variable
From: Mark Levedahl @ 2008-01-13 15:47 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7v4pdislrf.fsf@gitster.siamese.dyndns.org>

Junio C Hamano wrote:
> Mark Levedahl <mlevedahl@gmail.com> writes:
>
>   
>> Basically, I think an important (but not complete) test of the design
>> is that
>>
>>    git clone -o frotz git://frotz.foo.bar/myproject.git
>>    cd myproject
>>    git submodule init
>>    git submodule update
>>
>> work, with origin = frotz throughout the submodules, and with the
>> whole project correctly checked out even if the entire project was
>> rehosted onto a different server.
>>     
>
> I like that.  This is a very good argument, especially because
> it clarifies very well that the issue is not about "'submodule
> init' misbehaves" but "fetch/pull/merge does not play well with
> clone -o"
Carrying the above forward...  Assume I have a checked out project as 
above, then in top-level master project I do:

git remote add zoo git://zoo.tar.fu hisfork.git
git fetch zoo
git checkout --track -b fork zoo/fork
git submodule update

I claim the submodule machinery *should* now follow master's default 
remote, which is "zoo", for the current branch. In addition, the 
submodule machinery should define remote "zoo" in each submodule  where 
it does not already exist, using the same logic using in the original 
init/update phase. This should only apply to modules defined using 
relative urls.

Basically, this formalizes the notion that:

* submodules defined using relative urls are "owned" by the master 
project and will exist anywhere the master does.
* submodules defined using absolute urls are incorporated into the 
project but are separately managed. (While some improved mechanism to 
automate their management from top-level may be proposed, it is not 
obvious to me nor addressed here.)

The subsequent patch modifies git-submodule to implement this logic, and 
applies on top of my previous series.

(Note: I cannot find my latest series in the git-archives on gmane nor 
on marc.info, both have only part, and I am suspicious that something 
went wrong in my sending via gmail, so I am resending the series here, 
now five patches long. Please excuse if this is redundant).

Mark

^ permalink raw reply

* Re: Adding Git to Better SCM Initiative : Comparison
From: Matthieu Moy @ 2008-01-13 15:16 UTC (permalink / raw)
  To: linux; +Cc: git, jnareb
In-Reply-To: <20080113150541.21883.qmail@science.horizon.com>

linux@horizon.com writes:

> "Rename support" is a kludge to make a fundamentally broken model
> less painful.

It's not.

Git _has_ rename support. Look into the code, you'll find some code
whose purpose is to manage renames. And _no_, rename support is not
just a direct consequence of commits being atomic.

Atomic commit help, but if you do nothing else, moving a file and then
trying to merge will fail for example. So, in addition to atomic
commits, you have at least 3 options : explicit file ID (bzr),
recording renames (hg), or detecting renames after-the-fact (git).

-- 
Matthieu

^ permalink raw reply

* Re: git-checkout question
From: David J. Neu @ 2008-01-13 15:12 UTC (permalink / raw)
  To: Steffen Prohaska; +Cc: git
In-Reply-To: <AF05EA04-C41A-4964-B225-E3A427D32E33@zib.de>


On Sun, Jan 13, 2008 at 03:31:19PM +0100, Steffen Prohaska wrote:
> 
> On Jan 13, 2008, at 3:21 PM, David J. Neu wrote:
> 
> >I was wondering if someone could explain the following behavior.
> >
> >1. create and switch to branch off master
> >2. edit a file in the branch
> >3. checkout master without committing changes in the branch
> >4. the changes in the branch are automatically applied in working tree
> >   in master
> >
> >I wasn't expecting the changes in the branch to be automatically
> >moved to master.  Had I committed while in the branch this doesn't
> >happen.
> 
> This already is the explanation.  You did not commit.  Therefore,
> the changes are not in the branch but still in your work tree.
> They are on neither branch; they are _only_ in your work tree.
> If you switch the branch the changes will stay in the work tree.
> They always stayed in the same place: your work tree.
> 
> 	Steffen
> 

Ahh, got it - thanks!

^ permalink raw reply

* Re: Adding Git to Better SCM Initiative : Comparison
From: linux @ 2008-01-13 15:05 UTC (permalink / raw)
  To: git, jnareb; +Cc: linux

> What does "Renames Support" mean? Does it mean that when browsing history
> we [can] show file / directory renames? Does it mean that log of file or
> directory history [can] follow renames? Does it mean that line-wise file
> history [can] follow renames? Renames support in merges is as TODO, so
> I don't think that this one matters in this question. Because the answer,
> especially in the case of git which is a bit different in that it does
> rename detection and not rename tracking (using inodes / file-ids),
> depends on that...

Let me make a bolder statement: a person asking for "rename support"
has been mentally damaged by using CVS too much.

CVS's fundamental problem is that it's a tree of versioned files.  So a
file has to have a well-defined identity across versions, so CVS uses
the name, and that leads to problems if you rename the file.

And this is fundamentally broken.  Both git and subversion do it right:
a repository is a versioned tree of files.  Files don't have versions, but
rather versions have files.  With this model, the problem Just Goes Away.
It doesn't exist any more.  There's nothing to solve, nothing to do.

"Rename support" is a kludge to make a fundamentally broken model
less painful.  Git doesn't have the problem, and so doesn't need,
doesn't have, and doesn't want the kludge.  Indeed, as your questions
above show, it's hard to even define what it would be if it existed.
It's like asking if an electric light has a thoriated mantle, or inquiring
about the filament supply voltage of my mp3 player.

In all honesty, the correct answer is "no", git doesn't have that feature,
just like my laptop doesn't have a cooling water pressure sensor and
my solar-powered pocket calculator doesn't have a user-serviceable
mains fuse.

What's broken is the feature checklist.  Someone has to go and re-think
the issue in a less CVS-centric way.


Just in case I was not clear enough above:

	The need for a source file to have an identity
	that persists across multiple revisions is an
	artifact of CVS's implementation.  Anyone asking
	if a different version control system can preserve
	that identity across renames needs to learn that
	we now have ways of making light without fire.

^ permalink raw reply

* Re: [ANNOUNCE] GIT 1.5.4-rc3
From: Steffen Prohaska @ 2008-01-13 14:41 UTC (permalink / raw)
  To: Git Mailing List, msysGit; +Cc: Junio C Hamano
In-Reply-To: <7vsl13wmas.fsf-jO8aZxhGsIagbBziECNbOZn29agUkmeCHZ5vskTnxNA@public.gmane.org>



On Jan 12, 2008, at 8:11 AM, Junio C Hamano wrote:

> The third rc for the next feature release GIT 1.5.4 is available
> at the usual places:


The msysgit setup is available at:

   http://code.google.com/p/msysgit/downloads/

	Steffen

^ permalink raw reply

* Re: git-checkout question
From: Steffen Prohaska @ 2008-01-13 14:31 UTC (permalink / raw)
  To: djneu; +Cc: git
In-Reply-To: <20080113142140.GB10426@bach.davidneu.local>


On Jan 13, 2008, at 3:21 PM, David J. Neu wrote:

> I was wondering if someone could explain the following behavior.
>
> 1. create and switch to branch off master
> 2. edit a file in the branch
> 3. checkout master without committing changes in the branch
> 4. the changes in the branch are automatically applied in working tree
>    in master
>
> I wasn't expecting the changes in the branch to be automatically
> moved to master.  Had I committed while in the branch this doesn't
> happen.

This already is the explanation.  You did not commit.  Therefore,
the changes are not in the branch but still in your work tree.
They are on neither branch; they are _only_ in your work tree.
If you switch the branch the changes will stay in the work tree.
They always stayed in the same place: your work tree.

	Steffen

^ permalink raw reply

* git-checkout question
From: David J. Neu @ 2008-01-13 14:21 UTC (permalink / raw)
  To: git

Hi, 

I was wondering if someone could explain the following behavior.

1. create and switch to branch off master
2. edit a file in the branch
3. checkout master without committing changes in the branch
4. the changes in the branch are automatically applied in working tree 
   in master

I wasn't expecting the changes in the branch to be automatically
moved to master.  Had I committed while in the branch this doesn't
happen.  I'm using git version 1.5.3, the details are below.

Many thanks!

Cheers,
David

[/tmp] mkdir git-test
[/tmp] cd git-test
[/tmp/git-test] git-init 
Initialized empty Git repository in .git/
[/tmp/git-test] # create hello.py
[/tmp/git-test] git-add hello.py 
[/tmp/git-test] git-commit   
Created initial commit 58282ee: Initial commit of git-test.
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 hello.py
[/tmp/git-test] cat hello.py 
print "hello from master."
[/tmp/git-test] git-checkout -b test-branch
Switched to a new branch "test-branch"
[/tmp/git-test] # modify hello.py
[/tmp/git-test] cat hello.py 
print "hello from test-branch."
[/tmp/git-test] git-checkout master
M       hello.py
Switched to branch "master"
[/tmp/git-test] cat hello.py 
print "hello from test-branch."
[/tmp/git-test] # hmmm?

^ permalink raw reply

* [PATCH 3/3] Abstract out zlib
From: Marco Costalba @ 2008-01-13 13:24 UTC (permalink / raw)
  To: gitster; +Cc: git, Marco Costalba
In-Reply-To: <1200230678-18188-2-git-send-email-mcostalba@gmail.com>

Finally remove the hardcoded link between
compression helpers and zlib.

Association bewteen a stream and the compression library
is done at stream init time through a set of function
pointers. Library choice is based on compression level
parameter passed to compress_alloc(), this allow us to
stay 100% back compatible with current code.

Patch also adds the the necessary zlib engine plugin,
this turns out to be trivial since we have modeled
everything around zlib.

Signed-off-by: Marco Costalba <mcostalba@gmail.com>
---
 compress.c |   55 ++++++++++++++++++++++++++++++++++++++++++++++---------
 compress.h |    6 ++++++
 2 files changed, 52 insertions(+), 9 deletions(-)

diff --git a/compress.c b/compress.c
index b28c389..09a5df0 100644
--- a/compress.c
+++ b/compress.c
@@ -1,6 +1,41 @@
 #include "cache.h"
 #include "compress.h"
 
+/* Default zlib engine plugin definition
+ *
+ * Because everything is modeled after zlib the
+ * corresponding engine wrappers here are trivial
+ */
+static int zlib_deflateInit(z_stream *s, int l) { return deflateInit(s, l); }
+static int zlib_deflate(z_stream *s, int f) { return deflate(s, f); }
+static int zlib_deflateEnd(z_stream *s) { return deflateEnd(s); }
+static unsigned long zlib_deflateBound(z_stream *s, unsigned long sz) { return deflateBound(s, sz); }
+
+static int zlib_inflateInit(z_stream *s) { return inflateInit(s); }
+static int zlib_inflate(z_stream *s, int f) { return inflate(s, f); }
+static int zlib_inflateEnd(z_stream *s) { return inflateEnd(s); }
+
+
+/* link the stream to the compression library functions */
+static int register_engine(ext_stream *stream, int level)
+{
+	switch (level) {
+	case LZO_COMPRESSION:
+		die ("LZO compression still not implemented");
+		break;
+	default: /* assumed to be zlib */
+		stream->deflateInit_fn  = zlib_deflateInit;
+		stream->deflate_fn      = zlib_deflate;
+		stream->deflateEnd_fn   = zlib_deflateEnd;
+		stream->deflateBound_fn = zlib_deflateBound;
+		stream->inflateInit_fn  = zlib_inflateInit;
+		stream->inflate_fn      = zlib_inflate;
+		stream->inflateEnd_fn   = zlib_inflateEnd;
+		break;
+	};
+	return Z_OK;
+}
+
 /*
  *     Compression helpers
  */
@@ -8,8 +43,9 @@
 unsigned long compress_alloc(ext_stream *stream, int level, unsigned long size)
 {
 	memset(stream, 0, sizeof(*stream));
-	deflateInit(&stream->z, level);
-	return deflateBound(&stream->z, size);
+	register_engine(stream, level);
+	stream->deflateInit_fn(&stream->z, level);
+	return stream->deflateBound_fn(&stream->z, size);
 }
 
 int compress_start(ext_stream *stream,
@@ -28,7 +64,7 @@ int compress_next(ext_stream *stream, int flush)
 	int result;
 
 	do {
-		result = deflate(&stream->z, flush);
+		result = stream->deflate_fn(&stream->z, flush);
 	} while (result == Z_OK);
 
 	return result;
@@ -36,7 +72,7 @@ int compress_next(ext_stream *stream, int flush)
 
 unsigned long compress_free(ext_stream *stream)
 {
-	deflateEnd(&stream->z);
+	stream->deflateEnd_fn(&stream->z);
 	return stream->z.total_out;
 }
 
@@ -68,7 +104,8 @@ unsigned long compress_all(int level, unsigned char *in,
 int decompress_alloc(ext_stream *stream)
 {
 	memset(stream, 0, sizeof(*stream));
-	return inflateInit(&stream->z);
+	register_engine(stream, Z_DEFAULT_COMPRESSION); // FIXME for now zlib assumed
+	return stream->inflateInit_fn(&stream->z);
 }
 
 int decompress_from(ext_stream *stream, unsigned char *in, unsigned long in_size)
@@ -87,24 +124,24 @@ int decompress_into(ext_stream *stream, unsigned char *out, unsigned long out_si
 
 int decompress_next(ext_stream *stream, int flush)
 {
-	return inflate(&stream->z, flush);
+	return stream->inflate_fn(&stream->z, flush);
 }
 
 int decompress_next_from(ext_stream *stream, unsigned char *in, unsigned long in_size, int flush)
 {
 	decompress_from(stream, in, in_size);
-	return inflate(&stream->z, flush);
+	return stream->inflate_fn(&stream->z, flush);
 }
 
 int decompress_next_into(ext_stream *stream, unsigned char *out, unsigned long out_size, int flush)
 {
 	decompress_into(stream, out, out_size);
-	return inflate(&stream->z, flush);
+	return stream->inflate_fn(&stream->z, flush);
 }
 
 unsigned long decompress_free(ext_stream *stream)
 {
-	inflateEnd(&stream->z);
+	stream->inflateEnd_fn(&stream->z);
 	return stream->z.total_out;
 }
 
diff --git a/compress.h b/compress.h
index d1de31f..151234a 100644
--- a/compress.h
+++ b/compress.h
@@ -1,6 +1,12 @@
 #ifndef COMPRESS_H
 #define COMPRESS_H
 
+/* Add here custom compression levels. First 0-9
+ * and -1 are reserved values used by zlib
+ */
+#define LZO_COMPRESSION 99
+
+
 /* Any compress/decompress engine must implement all the
  * below functions that are modeled after the zlib ones.
  */
-- 
1.5.4.rc2.98.g58cd2

^ permalink raw reply related

* [PATCH 2/3] Rename z_stream to ext_stream across the sources
From: Marco Costalba @ 2008-01-13 13:24 UTC (permalink / raw)
  To: gitster; +Cc: git, Marco Costalba
In-Reply-To: <1200230678-18188-1-git-send-email-mcostalba@gmail.com>

Also fix the places where z_stream member access
is open coded.

In the future we could hide direct z_stream handling
behind some helpers, but for now leave it like it is
now to better understand what is going on.

Signed-off-by: Marco Costalba <mcostalba@gmail.com>
---
 builtin-pack-objects.c   |    8 +++---
 builtin-unpack-objects.c |    6 ++--
 http-push.c              |   12 +++++-----
 http-walker.c            |    6 ++--
 index-pack.c             |    6 ++--
 sha1_file.c              |   56 +++++++++++++++++++++++-----------------------
 6 files changed, 47 insertions(+), 47 deletions(-)

diff --git a/builtin-pack-objects.c b/builtin-pack-objects.c
index d2865fe..5165a23 100644
--- a/builtin-pack-objects.c
+++ b/builtin-pack-objects.c
@@ -300,7 +300,7 @@ static int check_pack_inflate(struct packed_git *p,
 		off_t len,
 		unsigned long expect)
 {
-	z_stream stream;
+	ext_stream stream;
 	unsigned char fakebuf[4096], *in;
 	unsigned int in_size = 0;
 	int st;
@@ -310,12 +310,12 @@ static int check_pack_inflate(struct packed_git *p,
 		decompress_into(&stream, fakebuf, sizeof(fakebuf));
 		in = use_pack(p, w_curs, offset, &in_size);
 		st = decompress_next_from(&stream, in, in_size, Z_FINISH);
-		offset += stream.next_in - in;
+		offset += stream.z.next_in - in;
 	} while (st == Z_OK || st == Z_BUF_ERROR);
 	decompress_free(&stream);
 	return (st == Z_STREAM_END &&
-		stream.total_out == expect &&
-		stream.total_in == len) ? 0 : -1;
+		stream.z.total_out == expect &&
+		stream.z.total_in == len) ? 0 : -1;
 }
 
 static int check_pack_crc(struct packed_git *p, struct pack_window **w_curs,
diff --git a/builtin-unpack-objects.c b/builtin-unpack-objects.c
index c996560..066bf06 100644
--- a/builtin-unpack-objects.c
+++ b/builtin-unpack-objects.c
@@ -61,7 +61,7 @@ static void use(int bytes)
 
 static void *get_data(unsigned long size)
 {
-	z_stream stream;
+	ext_stream stream;
 	unsigned char *buf = xmalloc(size);;
 
 	decompress_alloc(&stream);
@@ -71,8 +71,8 @@ static void *get_data(unsigned long size)
 		/* fill() modifies len, so be sure is evaluated as first */
 		void* tmp = fill(1);
 		int ret = decompress_next_from(&stream, tmp, len, Z_NO_FLUSH);
-		use(len - stream.avail_in);
-		if (stream.total_out == size && ret == Z_STREAM_END)
+		use(len - stream.z.avail_in);
+		if (stream.z.total_out == size && ret == Z_STREAM_END)
 			break;
 		if (ret != Z_OK) {
 			error("decompress returned %d\n", ret);
diff --git a/http-push.c b/http-push.c
index ec0568c..c7ea871 100644
--- a/http-push.c
+++ b/http-push.c
@@ -127,7 +127,7 @@ struct transfer_request
 	long http_code;
 	unsigned char real_sha1[20];
 	SHA_CTX c;
-	z_stream stream;
+	ext_stream stream;
 	int zret;
 	int rename;
 	void *userData;
@@ -209,8 +209,8 @@ static size_t fwrite_sha1_file(void *ptr, size_t eltsize, size_t nmemb,
 		request->zret = decompress_next_into(&request->stream, expn,
 		                                     sizeof(expn), Z_SYNC_FLUSH);
 		SHA1_Update(&request->c, expn,
-			    sizeof(expn) - request->stream.avail_out);
-	} while (request->stream.avail_in && request->zret == Z_OK);
+			    sizeof(expn) - request->stream.z.avail_out);
+	} while (request->stream.z.avail_in && request->zret == Z_OK);
 	data_received++;
 	return size;
 }
@@ -483,7 +483,7 @@ static void start_put(struct transfer_request *request)
 	unsigned long len;
 	int hdrlen;
 	ssize_t size;
-	z_stream stream;
+	ext_stream stream;
 
 	unpacked = read_sha1_file(request->obj->sha1, &type, &len);
 	hdrlen = sprintf(hdr, "%s %lu", typename(type), len) + 1;
@@ -501,8 +501,8 @@ static void start_put(struct transfer_request *request)
 	compress_next(&stream, Z_NO_FLUSH);
 
 	/* Then the data itself.. */
-	stream.next_in = unpacked;
-	stream.avail_in = len;
+	stream.z.next_in = unpacked;
+	stream.z.avail_in = len;
 	compress_next(&stream, Z_FINISH);
 
 	request->buffer.buf.len = compress_free(&stream);
diff --git a/http-walker.c b/http-walker.c
index b1d2a28..1581746 100644
--- a/http-walker.c
+++ b/http-walker.c
@@ -38,7 +38,7 @@ struct object_request
 	long http_code;
 	unsigned char real_sha1[20];
 	SHA_CTX c;
-	z_stream stream;
+	ext_stream stream;
 	int zret;
 	int rename;
 	struct active_request_slot *slot;
@@ -83,8 +83,8 @@ static size_t fwrite_sha1_file(void *ptr, size_t eltsize, size_t nmemb,
 		obj_req->zret = decompress_next_into(&obj_req->stream, expn,
                                              sizeof(expn), Z_SYNC_FLUSH);
 		SHA1_Update(&obj_req->c, expn,
-			    sizeof(expn) - obj_req->stream.avail_out);
-	} while (obj_req->stream.avail_in && obj_req->zret == Z_OK);
+			    sizeof(expn) - obj_req->stream.z.avail_out);
+	} while (obj_req->stream.z.avail_in && obj_req->zret == Z_OK);
 	data_received++;
 	return size;
 }
diff --git a/index-pack.c b/index-pack.c
index 929de39..7881a0b 100644
--- a/index-pack.c
+++ b/index-pack.c
@@ -166,7 +166,7 @@ static void bad_object(unsigned long offset, const char *format, ...)
 
 static void *unpack_entry_data(unsigned long offset, unsigned long size)
 {
-	z_stream stream;
+	ext_stream stream;
 	void *buf = xmalloc(size);
 
 	decompress_alloc(&stream);
@@ -176,8 +176,8 @@ static void *unpack_entry_data(unsigned long offset, unsigned long size)
 		/* fill() modifies len, so be sure is evaluated as first */
 		void* tmp = fill(1);
 		int ret = decompress_next_from(&stream, tmp, input_len, Z_NO_FLUSH);
-		use(input_len - stream.avail_in);
-		if (stream.total_out == size && ret == Z_STREAM_END)
+		use(input_len - stream.z.avail_in);
+		if (stream.z.total_out == size && ret == Z_STREAM_END)
 			break;
 		if (ret != Z_OK)
 			bad_object(offset, "decompress returned %d", ret);
diff --git a/sha1_file.c b/sha1_file.c
index 708727a..a978f13 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -1052,7 +1052,7 @@ unsigned long unpack_object_header_gently(const unsigned char *buf, unsigned lon
 	return used;
 }
 
-static int unpack_sha1_header(z_stream *stream, unsigned char *map, unsigned long mapsize, void *buffer, unsigned long bufsiz)
+static int unpack_sha1_header(ext_stream *stream, unsigned char *map, unsigned long mapsize, void *buffer, unsigned long bufsiz)
 {
 	unsigned long size, used;
 	static const char valid_loose_object_type[8] = {
@@ -1087,19 +1087,19 @@ static int unpack_sha1_header(z_stream *stream, unsigned char *map, unsigned lon
 	decompress_from(stream, map, mapsize);
 
 	/* And generate the fake traditional header */
-	stream->total_out = 1 + snprintf(buffer, bufsiz, "%s %lu",
+	stream->z.total_out = 1 + snprintf(buffer, bufsiz, "%s %lu",
 					 typename(type), size);
 	return 0;
 }
 
-static void *unpack_sha1_rest(z_stream *stream, void *buffer, unsigned long size, const unsigned char *sha1)
+static void *unpack_sha1_rest(ext_stream *stream, void *buffer, unsigned long size, const unsigned char *sha1)
 {
 	int bytes = strlen(buffer) + 1;
 	unsigned char *buf = xmalloc(1+size);
 	unsigned long n;
 	int status = Z_OK;
 
-	n = stream->total_out - bytes;
+	n = stream->z.total_out - bytes;
 	if (n > size)
 		n = size;
 	memcpy(buf, (char *) buffer + bytes, n);
@@ -1123,14 +1123,14 @@ static void *unpack_sha1_rest(z_stream *stream, void *buffer, unsigned long size
 			status = decompress_next(stream, Z_FINISH);
 	}
 	buf[size] = 0;
-	if (status == Z_STREAM_END && !stream->avail_in) {
+	if (status == Z_STREAM_END && !stream->z.avail_in) {
 		decompress_free(stream);
 		return buf;
 	}
 
 	if (status < 0)
 		error("corrupt loose object '%s'", sha1_to_hex(sha1));
-	else if (stream->avail_in)
+	else if (stream->z.avail_in)
 		error("garbage at end of loose object '%s'",
 		      sha1_to_hex(sha1));
 	free(buf);
@@ -1191,7 +1191,7 @@ static int parse_sha1_header(const char *hdr, unsigned long *sizep)
 static void *unpack_sha1_file(void *map, unsigned long mapsize, enum object_type *type, unsigned long *size, const unsigned char *sha1)
 {
 	int ret;
-	z_stream stream;
+	ext_stream stream;
 	char hdr[8192];
 
 	ret = unpack_sha1_header(&stream, map, mapsize, hdr, sizeof(hdr));
@@ -1207,7 +1207,7 @@ unsigned long get_size_from_delta(struct packed_git *p,
 {
 	const unsigned char *data;
 	unsigned char delta_head[20], *in;
-	z_stream stream;
+	ext_stream stream;
 	int st;
 	unsigned int in_size = 0;
 
@@ -1217,11 +1217,11 @@ unsigned long get_size_from_delta(struct packed_git *p,
 	do {
 		in = use_pack(p, w_curs, curpos, &in_size);
 		st = decompress_next_from(&stream, in, in_size, Z_FINISH);
-		curpos += stream.next_in - in;
+		curpos += stream.z.next_in - in;
 	} while ((st == Z_OK || st == Z_BUF_ERROR) &&
-		 stream.total_out < sizeof(delta_head));
+		 stream.z.total_out < sizeof(delta_head));
 	decompress_free(&stream);
-	if ((st != Z_STREAM_END) && stream.total_out != sizeof(delta_head))
+	if ((st != Z_STREAM_END) && stream.z.total_out != sizeof(delta_head))
 		die("delta data unpack-initial failed");
 
 	/* Examine the initial part of the delta to figure out
@@ -1416,7 +1416,7 @@ static void *unpack_compressed_entry(struct packed_git *p,
 				    unsigned long size)
 {
 	int st;
-	z_stream stream;
+	ext_stream stream;
 	unsigned char *buffer, *in;
 	unsigned int in_size = 0;
 
@@ -1427,10 +1427,10 @@ static void *unpack_compressed_entry(struct packed_git *p,
 	do {
 		in = use_pack(p, w_curs, curpos, &in_size);
 		st = decompress_next_from(&stream, in, in_size, Z_FINISH);
-		curpos += stream.next_in - in;
+		curpos += stream.z.next_in - in;
 	} while (st == Z_OK || st == Z_BUF_ERROR);
 	decompress_free(&stream);
-	if ((st != Z_STREAM_END) || stream.total_out != size) {
+	if ((st != Z_STREAM_END) || stream.z.total_out != size) {
 		free(buffer);
 		return NULL;
 	}
@@ -1762,7 +1762,7 @@ static int sha1_loose_object_info(const unsigned char *sha1, unsigned long *size
 	int status;
 	unsigned long mapsize, size;
 	void *map;
-	z_stream stream;
+	ext_stream stream;
 	char hdr[32];
 
 	map = map_sha1_file(sha1, &mapsize);
@@ -2033,7 +2033,7 @@ int write_sha1_file(void *buf, unsigned long len, const char *type, unsigned cha
 {
 	int size, ret;
 	unsigned char *compressed;
-	z_stream stream;
+	ext_stream stream;
 	unsigned char sha1[20];
 	char *filename;
 	static char tmpfile[PATH_MAX];
@@ -2084,8 +2084,8 @@ int write_sha1_file(void *buf, unsigned long len, const char *type, unsigned cha
 	compress_next(&stream, Z_NO_FLUSH);
 
 	/* Then the data itself.. */
-	stream.next_in = buf;
-	stream.avail_in = len;
+	stream.z.next_in = buf;
+	stream.z.avail_in = len;
 	ret = compress_next(&stream, Z_FINISH);
 	if (ret != Z_STREAM_END)
 		die("unable to deflate new object %s (%d)", sha1_to_hex(sha1), ret);
@@ -2109,7 +2109,7 @@ int write_sha1_file(void *buf, unsigned long len, const char *type, unsigned cha
 static void *repack_object(const unsigned char *sha1, unsigned long *objsize)
 {
 	size_t size;
-	z_stream stream;
+	ext_stream stream;
 	unsigned char *unpacked;
 	unsigned long len;
 	enum object_type type;
@@ -2135,8 +2135,8 @@ static void *repack_object(const unsigned char *sha1, unsigned long *objsize)
 	compress_next(&stream, Z_NO_FLUSH);
 
 	/* Then the data itself.. */
-	stream.next_in = unpacked;
-	stream.avail_in = len;
+	stream.z.next_in = unpacked;
+	stream.z.avail_in = len;
 	compress_next(&stream, Z_FINISH);
 
 	*objsize = compress_free(&stream);
@@ -2167,7 +2167,7 @@ int write_sha1_from_fd(const unsigned char *sha1, int fd, char *buffer,
 {
 	char tmpfile[PATH_MAX];
 	int local;
-	z_stream stream;
+	ext_stream stream;
 	unsigned char real_sha1[20];
 	unsigned char discard[4096];
 	int ret;
@@ -2193,13 +2193,13 @@ int write_sha1_from_fd(const unsigned char *sha1, int fd, char *buffer,
 			do {
 				ret = decompress_next_into(&stream, discard, sizeof(discard), Z_SYNC_FLUSH);
 				SHA1_Update(&c, discard, sizeof(discard) -
-					    stream.avail_out);
-			} while (stream.avail_in && ret == Z_OK);
-			if (write_buffer(local, buffer, *bufposn - stream.avail_in) < 0)
+					    stream.z.avail_out);
+			} while (stream.z.avail_in && ret == Z_OK);
+			if (write_buffer(local, buffer, *bufposn - stream.z.avail_in) < 0)
 				die("unable to write sha1 file");
-			memmove(buffer, buffer + *bufposn - stream.avail_in,
-				stream.avail_in);
-			*bufposn = stream.avail_in;
+			memmove(buffer, buffer + *bufposn - stream.z.avail_in,
+				stream.z.avail_in);
+			*bufposn = stream.z.avail_in;
 			if (ret != Z_OK)
 				break;
 		}
-- 
1.5.4.rc2.98.g58cd2

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox