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

Re: [PATCH 3/3] - Convert git-checkout-cache to argp

From
Sean <seanlkml@sympatico.ca>
Date
May 21, 2005, 21:39 UTC
Message-ID
<2669.10.10.10.24.1116711571.squirrel@linux1>
In-Reply-To
<7v7jhsgtlg.fsf@assigned-by-dhcp.cox.net>
On Sat, May 21, 2005 5:24 pm, Junio C Hamano said:
Show 17 quoted lines
>>>>>> "JG" == Jeff Garzik <jgarzik@pobox.com> writes:
>
> JG> Sean wrote:
>>> Use argp to process command line arguments for git-checkout-cache.
>>> Also,
>>> fix things up so that the order of options on the command line no
>>> longer
>>> matters.  To this end, the "-f" (--force) switch only applies to the
>>> individual files given on the command line.   A new forcing version of
>>> the
>>> "-a" (--all) switch is added as "-A" (--forceall).
>
> JG> I agree with Junio -- this patch breaks stuff.
>
> Yes, and that is exactly why I wanted to see the documentation
> changes first before the code.
>

Okay. Attached no longer tries to maintain the feature of unforced -a in combination with forced file list. So:

Use argp to process command line arguments for git-checkout-cache. Also, fix things up so that the order of options on the command line no longer matters. To this end, the "-f" (--force) option always affects the -a (--all) option no matter where it appears on the command line.

Signed-off-by: Sean Estabrooks <seanlkml@sympatico.ca>
 Documentation/git-checkout-cache.txt |   16 ++--
 checkout-cache.c                     |  120
++++++++++++++++-------------------
 2 files changed, 64 insertions(+), 72 deletions(-)
Index: Documentation/git-checkout-cache.txt
===================================================================
--- 3abc6a8ee0f27eaba8d0a7d091413eb390447386/Documentation/git-checkout-cache.txt  (mode:100644)
+++ uncommitted/Documentation/git-checkout-cache.txt  (mode:100644)
@@ -24,7 +24,7 @@
 	the cache file.
 
 -q::
-	be quiet if files exist or are not in the cache
+	be quiet if files exist or are not in the cache.
 
 -f::
 	forces overwrite of existing files
@@ -44,17 +44,15 @@
 --::
 	Do not interpret any more arguments as options.
 
-Note that the order of the flags matters:
+Example:
 
-     git-checkout-cache -a -f file.c
+     git-checkout-cache -a
 
-will first check out all files listed in the cache (but not overwrite
-any old ones), and then force-checkout `file.c` a second time (ie that
-one *will* overwrite any old contents with the same filename).
+Will check out all files listed in the cache.
 
-Also, just doing "git-checkout-cache" does nothing. You probably meant
+Just doing "git-checkout-cache" does nothing. You probably meant
 "git-checkout-cache -a". And if you want to force it, you want
-"git-checkout-cache -f -a".
+"git-checkout-cache -a -f".
 
 Intuitiveness is not the goal here. Repeatability is. The reason for
 the "no arguments means no work" thing is that from scripts you are
@@ -68,7 +66,7 @@
 
 To update and refresh only the files already checked out:
 
-        git-checkout-cache -n -f -a && git-update-cache --ignore-missing --refresh
+        git-checkout-cache -n -a -f && git-update-cache --ignore-missing --refresh
 
 Oh, and the "--" is just a good idea when you know the rest will be
 filenames. Just so that you wouldn't have a filename of "-a" causing
Index: checkout-cache.c
===================================================================
--- 3abc6a8ee0f27eaba8d0a7d091413eb390447386/checkout-cache.c  (mode:100644)
+++ uncommitted/checkout-cache.c  (mode:100644)
@@ -3,18 +3,14 @@
  *
  * Copyright (C) 2005 Linus Torvalds
  *
- * Careful: order of argument flags does matter. For example,
+ *	git-checkout-cache -a
  *
- *	git-checkout-cache -a -f file.c
+ * Will check out all files listed in the cache, but not
+ * overwrite any existing files. 
  *
- * Will first check out all files listed in the cache (but not
- * overwrite any old ones), and then force-checkout "file.c" a
- * second time (ie that one _will_ overwrite any old contents
- * with the same filename).
- *
- * Also, just doing "git-checkout-cache" does nothing. You probably
- * meant "git-checkout-cache -a". And if you want to force it, you
- * want "git-checkout-cache -f -a".
+ * Just doing "git-checkout-cache" does nothing. You probably
+ * meant "git-checkout-cache -a". And if you want to force it,
+ * you want "git-checkout-cache -f -a".
  *
  * Intuitiveness is not the goal here. Repeatability is. The
  * reason for the "no arguments means no work" thing is that
@@ -35,8 +31,11 @@
 #include <sys/types.h>
 #include <dirent.h>
 #include "cache.h"
+#include <argp.h>
+const char *argp_program_version = VERSION;
 
-static int force = 0, quiet = 0, not_new = 0, refresh_cache = 0;
+static int force = 0, quiet = 0, not_new = 0, refresh_cache = 0, all = 0;
+static const char *base_opt = "";
 
 static void create_directories(const char *path)
 {
@@ -226,68 +225,63 @@
 	return 0;
 }
 
+static const char doc[] = "Populate working tree with files from cache";
+
+static struct argp_option options[] = {
+ {"prefix", 1, "base", 0, "Prepend base to each file before checkout"},
+ {"all", 'a', 0, 0, "Checkout entire cache"},
+ {"force", 'f', 0, 0, "Allow checkout to overwrite existing files"},
+ {"quiet", 'q', 0, 0, "Suppress warnings"},
+ {"not-new", 'n', 0, 0, "Checkout existing files only"},
+ {"update", 'u', 0, 0, "Update cache with new stat info"},
+ { }
+};
+
+static error_t parse_opt (int key, char *arg, struct argp_state *state)
+{
+        switch (key) {
+        case 'a':		all = 1; break;
+        case 'q':		quiet = 1; break;
+        case 'n':		not_new = 1; break;
+        case 'f':		force = 1; break;
+        case   1:		base_opt = arg; break;
+        case 'u':		refresh_cache = 1; break;
+        default:		return ARGP_ERR_UNKNOWN;
+        }
+        return 0;
+}
+
+static const struct argp argp = { options, parse_opt, "[FILES...]", doc };
+
 int main(int argc, char **argv)
 {
-	int i, force_filename = 0;
-	const char *base_dir = "";
 	struct cache_file cache_file;
-	int newfd = -1;
+	int i, idx, newfd = -1;
 
 	if (read_cache() < 0) {
 		die("invalid cache");
 	}
 
-	for (i = 1; i < argc; i++) {
-		const char *arg = argv[i];
-		if (!force_filename) {
-			if (!strcmp(arg, "-a")) {
-				checkout_all(base_dir);
-				continue;
-			}
-			if (!strcmp(arg, "--")) {
-				force_filename = 1;
-				continue;
-			}
-			if (!strcmp(arg, "-f")) {
-				force = 1;
-				continue;
-			}
-			if (!strcmp(arg, "-q")) {
-				quiet = 1;
-				continue;
-			}
-			if (!strcmp(arg, "-n")) {
-				not_new = 1;
-				continue;
-			}
-			if (!strcmp(arg, "-u")) {
-				refresh_cache = 1;
-				if (newfd < 0)
-					newfd = hold_index_file_for_update
-						(&cache_file,
-						 get_index_file());
-				if (newfd < 0)
-					die("cannot open index.lock file.");
-				continue;
-			}
-			if (!memcmp(arg, "--prefix=", 9)) {
-				base_dir = arg+9;
-				continue;
-			}
-		}
-		if (base_dir[0]) {
-			/* when --prefix is specified we do not
-			 * want to update cache.
-			 */
-			if (refresh_cache) {
-				close(newfd); newfd = -1;
-				rollback_index_file(&cache_file);
-			}
-			refresh_cache = 0;
-		}
-		checkout_file(arg, base_dir);
+	error_t rc = argp_parse(&argp, argc, argv, 0, &idx, NULL);
+	if (rc) {
+		fprintf(stderr, "argument failed: %s\n", strerror(rc));
+		return 1;
 	}
 
+	if (refresh_cache) {
+		if (base_opt[0])
+			die("cannot update cache when --prefix option is used");
+		newfd = hold_index_file_for_update(&cache_file, get_index_file());
+		if (newfd < 0)
+			die("cannot open index.lock file.");
+	}
+
+	if (all)
+		checkout_all(base_opt); 
+
+	for (i = idx; i < argc; i++) 
+		checkout_file(argv[i], base_opt);
+
 	if (0 <= newfd &&
 	    (write_cache(newfd, active_cache, active_nr) ||
 	     commit_index_file(&cache_file)))
Previous: Junio C Hamano
Message 5 of 5 in “- Convert git-checkout-cache to argp”
  1. 3/3 - Convert git-checkout-cache to argpSean, May 21, 2005
  2. Junio C HamanoMay 21, 2005
  3. Jeff GarzikMay 21, 2005
  4. Junio C HamanoMay 21, 2005
  5. SeanMay 21, 2005

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.