git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH 2/2] Teach receive-pack how to keep pack files based on object count.

From
Nicolas Pitre <nico@cam.org>
Date
Oct 31, 2006, 21:08 UTC
Message-ID
<Pine.LNX.4.64.0610311559150.11384@xanadu.home>
In-Reply-To
<20061031201148.GD23671@spearce.org>
On Tue, 31 Oct 2006, Shawn Pearce wrote:
Show 15 quoted lines
> Nicolas Pitre <nico@cam.org> wrote:
> > I think this should be solved before rx packs are actually stored as 
> > packs though.  Otherwise people will end up with unwanted .keep files 
> > left around.  Maybe having a much bigger default for object number 
> > treshold for the time being?  (unless this patch is applied to "next" at 
> > the same time as another one that actually deals with those .keep 
> > files).
> 
> Its next on my list of things to do.  Hopefully I'll be able to
> implement it today.
> 
> I'm thinking of just brute forcing it: put enough identifying data
> into the .keep file to make it unique, then go through every local
> pack and look at their .keep file; if the content matches what
> receive-pack asked index-pack to put there then remove it.

Ouch. What about the patch below? It covers only the pull/fetch case, but covering the push case shouldn't be that hard either (simply use a pipe to read index-pack's stdout and capture the pack name).

I used "pack" <tab> <sha1> so it is easy to pick out of the list of refs that usually comes over the stream in the fetch case (if I understood that part right).

diff --git a/fetch-clone.c b/fetch-clone.c
index f629d8d..579307d 100644
--- a/fetch-clone.c
+++ b/fetch-clone.c
@@ -81,7 +81,18 @@ int receive_unpack_pack(int xd[2], const
 
 int receive_keep_pack(int xd[2], const char *me, int quiet, int sideband)
 {
-	const char *argv[5] = { "index-pack", "--stdin", "--fix-thin",
-				quiet ? NULL : "-v", NULL };
+	const char *argv[6];
+	char my_host[255], keep_arg[128 + 255];
+
+	if (gethostname(my_host, sizeof(my_host)))
+		strcpy(my_host, "localhost");
+	snprintf(keep_arg, sizeof(keep_arg), "--keep=fetch-pack %i on %s",
+		 getpid(), my_host);
+	argv[0] = "index-pack";
+	argv[1] = "--stdin";
+	argv[2] = "--fix-thin";
+	argv[3] = keep_arg;
+	argv[4] = quiet ? NULL : "-v";
+	argv[5] = NULL;
 	return get_pack(xd, me, sideband, argv);
 }
diff --git a/git-fetch.sh b/git-fetch.sh
index 539dff6..366014d 100755
--- a/git-fetch.sh
+++ b/git-fetch.sh
@@ -368,6 +368,7 @@ fetch_main () {
       ;; # we are already done.
   *)
     ( : subshell because we muck with IFS
+      pack_lockfile=
       IFS=" 	$LF"
       (
 	  git-fetch-pack $exec $keep "$remote" $rref || echo failed "$remote"
@@ -378,6 +379,10 @@ fetch_main () {
 	  failed)
 		  echo >&2 "Fetch failure: $remote"
 		  exit 1 ;;
+	  pack)
+		  # special line coming from index-pack with the pack name
+		  pack_lockfile="$GIT_OBJECT_DIRECTORY/pack/pack-$remote_name.keep"
+		  continue ;;
 	  esac
 	  found=
 	  single_force=
@@ -408,6 +413,7 @@ fetch_main () {
 	  append_fetch_head "$sha1" "$remote" \
 		  "$remote_name" "$remote_nick" "$local_name" "$not_for_merge"
       done
+      [ "$pack_lockfile" ] && rm -f "$pack_lockfile"
     ) || exit ;;
   esac
 
diff --git a/index-pack.c b/index-pack.c
index a3b55f9..c8f66da 100644
--- a/index-pack.c
+++ b/index-pack.c
@@ -767,18 +767,6 @@ static void final(const char *final_pack
 		if (err)
 			die("error while closing pack file: %s", strerror(errno));
 		chmod(curr_pack_name, 0444);
-
-		/*
-		 * Let's just mimic git-unpack-objects here and write
-		 * the last part of the buffer to stdout.
-		 */
-		while (input_len) {
-			err = xwrite(1, input_buffer + input_offset, input_len);
-			if (err <= 0)
-				break;
-			input_len -= err;
-			input_offset += err;
-		}
 	}
 
 	if (keep_msg) {
@@ -818,6 +806,27 @@ static void final(const char *final_pack
 		if (move_temp_to_file(curr_index_name, final_index_name))
 			die("cannot store index file");
 	}
+
+	if (!from_stdin) {
+		printf("%s\n", sha1_to_hex(sha1));
+	} else {
+		char buf[48];
+		int len = snprintf(buf, sizeof(buf), "pack\t%s\n",
+				   sha1_to_hex(sha1));
+		xwrite(1, buf, len);
+
+		/*
+		 * Let's just mimic git-unpack-objects here and write
+		 * the last part of the input buffer to stdout.
+		 */
+		while (input_len) {
+			err = xwrite(1, input_buffer + input_offset, input_len);
+			if (err <= 0)
+				break;
+			input_len -= err;
+			input_offset += err;
+		}
+	}
 }
 
 int main(int argc, char **argv)
@@ -934,8 +943,5 @@ int main(int argc, char **argv)
 	free(index_name_buf);
 	free(keep_name_buf);
 
-	if (!from_stdin)
-		printf("%s\n", sha1_to_hex(sha1));
-
 	return 0;
Previous: Shawn PearceNext: Shawn Pearce
Message 4 of 7 in “Teach receive-pack how to keep pack files based on object count.”
  1. 2/2 Teach receive-pack how to keep pack files based on object count.Shawn Pearce, Oct 31, 2006
  2. Nicolas PitreOct 31, 2006
  3. Shawn PearceOct 31, 2006
  4. Nicolas PitreOct 31, 2006
  5. Shawn PearceOct 31, 2006
  6. Nicolas PitreOct 31, 2006
  7. Junio C HamanoOct 31, 2006

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.