? GPATH
? GRTAGS
? GTAGS
Index: gtags/gtags.c
===================================================================
RCS file: /sources/global/global/gtags/gtags.c,v
retrieving revision 1.267
diff -d -u -r1.267 gtags.c
--- gtags/gtags.c	11 May 2014 23:22:51 -0000	1.267
+++ gtags/gtags.c	25 Jun 2014 03:24:25 -0000
@@ -566,41 +566,28 @@
 	/*
 	 * Make add list and delete list for update.
 	 */
-	if (single_update) {
-		int type;
-		const char *fid;
+	do {
+		char process_single_file = (single_update) ? issourcefile(single_update) : 0;
+		if (process_single_file) {
+			path = single_update;
+		} else {
+			file_list = (single_update) ? single_update : file_list;
+			if (file_list) {
+				find_open_filelist(file_list, root);
+			} else {
+				find_open(NULL);
+			}
 
-		if (skipthisfile(single_update))
-			goto exit;
-		if (test("b", single_update))
-			goto exit;
-		fid = gpath_path2fid(single_update, &type);
-		if (fid == NULL) {
-			/* new file */
-			type = issourcefile(single_update) ? GPATH_SOURCE : GPATH_OTHER;
-			if (type == GPATH_OTHER)
-				strbuf_puts0(addlist_other, single_update);
-			else {
-				strbuf_puts0(addlist, single_update);
-				total++;
+			if ((path = find_read()) == NULL) {
+				break;
 			}
-		} else {
-			/* update file */
-			if (type == GPATH_OTHER)
-				goto exit;
-			idset_add(deleteset, atoi(fid));
-			strbuf_puts0(addlist, single_update);
-			total++;
 		}
-	} else {
-		if (file_list)
-			find_open_filelist(file_list, root);
-		else
-			find_open(NULL);
-		while ((path = find_read()) != NULL) {
+
+		do {
 			const char *fid;
 			int n_fid = 0;
 			int other = 0;
+			char added = 0;
 
 			/* a blank at the head of path means 'NOT SOURCE'. */
 			if (*path == ' ') {
@@ -608,28 +595,73 @@
 					continue;
 				other = 1;
 			}
-			if (stat(path, &statp) < 0)
-				die("stat failed '%s'.", path);
+
+			if (single_update) {
+				/*
+				 * Prefix files to be dropped with
+				 * '-' and '+' to add/update
+				 * */
+				if (*path == '-') {
+				    added = 0;
+				    ++path;
+				} else if (*path == '+') {
+				    added = 1;
+				    ++path;
+				} else if (test("f", path)) {
+				    added = 1;
+				} else {
+				    added = 0;
+				}
+			} else if (0 == stat(path, &statp)) {
+				added = !!(gtags_mtime < statp.st_mtime);
+			} else {
+				if (errno == ENOENT || errno == ESTALE) {
+					added = 0;
+				} else {
+				    die("stat failed with error %d for '%s'.", errno, path);
+				}
+			}
+
 			fid = gpath_path2fid(path, NULL);
 			if (fid) { 
 				n_fid = atoi(fid);
 				idset_add(findset, n_fid);
 			}
+
 			if (other) {
-				if (fid == NULL)
+				if (fid == NULL && added)
 					strbuf_puts0(addlist_other, path);
 			} else {
 				if (fid == NULL) {
-					strbuf_puts0(addlist, path);
-					total++;
-				} else if (gtags_mtime < statp.st_mtime) {
+					if (added) {
+						strbuf_puts0(addlist, path);
+						total++;
+					}
+				} else if (added) {
 					strbuf_puts0(addlist, path);
 					total++;
 					idset_add(deleteset, n_fid);
+				} else {
+					strbuf_puts0(deletelist, path);
+					idset_add(deleteset, n_fid);
+					total++;
 				}
 			}
+		} while (!process_single_file && (path = find_read()) != NULL);
+
+		/* Close the file if we have opened */
+		if (!process_single_file) {
+			find_close();
 		}
-		find_close();
+
+		/*
+		 * If single file update or minimal refresh,
+		 * do not delete remaining tags
+		 */
+		if (process_single_file || single_update) {
+			break;
+		}
+
 		/*
 		 * make delete list.
 		 */
@@ -659,7 +691,7 @@
 				}
 			}
 		}
-	}
+	} while(0);
 	statistics_time_end(tim);
 	/*
 	 * execute updating.
Index: libutil/find.c
===================================================================
RCS file: /sources/global/global/libutil/find.c,v
retrieving revision 1.94
diff -d -u -r1.94 find.c
--- libutil/find.c	11 Mar 2014 02:16:20 -0000	1.94
+++ libutil/find.c	25 Jun 2014 03:24:25 -0000
@@ -789,6 +789,7 @@
 
 	strbuf_clear(ib);
 	for (;;) {
+		char prefix = 0;
 		path = strbuf_fgets(ib, ip, STRBUF_NOCRLF);
 		if (path == NULL) {
 			/* EOF */
@@ -804,6 +805,10 @@
 		 */
 		if (*path == '.' && *(path + 1) == ' ')
 			continue;
+
+		if (*path == '+' || *path == '-')
+			prefix = *(path++);
+
 		/*
 		 * Skip the following:
 		 * o directory
@@ -844,6 +849,10 @@
 		 */
 		if (!issourcefile(path))
 			*--path = ' ';
+
+		if (prefix)
+		    *--path = prefix;
+
 		return path;
 	}
 }
Index: libutil/getdbpath.c
===================================================================
RCS file: /sources/global/global/libutil/getdbpath.c,v
retrieving revision 1.32
diff -d -u -r1.32 getdbpath.c
--- libutil/getdbpath.c	28 Feb 2014 04:08:11 -0000	1.32
+++ libutil/getdbpath.c	25 Jun 2014 03:24:25 -0000
@@ -211,7 +211,10 @@
 	char *p;
 	static char msg[1024];
 
-	if (!getcwd(cwd, MAXPATHLEN)) {
+	/* Prefer shorter paths over long realpath if GTAGSLOGICALPATH is set */
+	if (getenv("GTAGSLOGICALPATH") && (p = getenv("PWD"))) {
+		strncpy(cwd, p, sizeof(cwd) - 1);
+	} else if (!getcwd(cwd, MAXPATHLEN)) {
 		gtags_dbpath_error = "cannot get current directory.";
 		return -1;
 	}
