diff --git a/gtags/gtags.c b/gtags/gtags.c
index c25ae77..924324b 100644
--- a/gtags/gtags.c
+++ b/gtags/gtags.c
@@ -69,29 +69,30 @@ void updatetags(const char *, const char *, IDSET *, STRBUF *);
 void createtags(const char *, const char *);
 int printconf(const char *);
 
-int cflag;					/**< compact format */
-int iflag;					/**< incremental update */
-int Iflag;					/**< make  idutils index */
-int Oflag;					/**< use objdir */
-int qflag;					/**< quiet mode */
-int wflag;					/**< warning message */
-int vflag;					/**< verbose mode */
-int show_version;
-int show_help;
-int show_config;
-char *gtagsconf;
-char *gtagslabel;
-int debug;
-const char *config_name;
-const char *file_list;
-const char *dump_target;
-char *single_update;
+int cflag = 0;					/**< compact format */
+int iflag = 0;					/**< incremental update */
+int Iflag = 0;					/**< make  idutils index */
+int Oflag = 0;					/**< use objdir */
+int qflag = 0;					/**< quiet mode */
+int wflag = 0;					/**< warning message */
+int vflag = 0;					/**< verbose mode */
+int Dflag = 0;					/**< Delta update */
+int show_version = 0;
+int show_help = 0;
+int show_config = 0;
+char *gtagsconf = NULL;
+char *gtagslabel = NULL;
+int debug = 0;
+const char *config_name = NULL;
+const char *file_list = NULL;
+const char *dump_target = NULL;
+char *single_update = NULL;
 int statistics = STATISTICS_STYLE_NONE;
 
 #define GTAGSFILES "gtags.files"
 
-int extractmethod;
-int total;
+int extractmethod = 0;
+int total = 0;
 
 static void
 usage(void)
@@ -121,6 +122,7 @@ static struct option const long_options[] = {
 	{"file", required_argument, NULL, 'f'},
 	{"idutils", no_argument, NULL, 'I'},
 	{"incremental", no_argument, NULL, 'i'},
+	{"delta", no_argument, NULL, 'D'},
 	{"max-args", required_argument, NULL, 'n'},
 	{"omit-gsyms", no_argument, NULL, 'o'},		/* removed */
 	{"objdir", no_argument, NULL, 'O'},
@@ -206,7 +208,7 @@ main(int argc, char **argv)
 			argv = prepend_options(&argc, argv, env);
 	}
 	logging_arguments(argc, argv);
-	while ((optchar = getopt_long(argc, argv, "cd:f:iIn:oOqvwse", long_options, &option_index)) != EOF) {
+	while ((optchar = getopt_long(argc, argv, "cd:f:iIn:oOqvwseD", long_options, &option_index)) != EOF) {
 		switch (optchar) {
 		case 0:
 			/* already flags set */
@@ -251,6 +253,9 @@ main(int argc, char **argv)
 		case 'O':
 			Oflag++;
 			break;
+		case 'D':
+			Dflag++;
+			break;
 		case 'q':
 			qflag++;
 			setquiet();
@@ -540,6 +545,7 @@ incremental(const char *dbpath, const char *root)
 	int updated = 0;
 	const char *path;
 	unsigned int id, limit;
+	char deleted = 0;
 
 	tim = statistics_time_start("Time of inspecting %s and %s.", dbname(GTAGS), dbname(GRTAGS));
 	if (vflag) {
@@ -600,7 +606,7 @@ incremental(const char *dbpath, const char *root)
 			find_open_filelist(file_list, root);
 		else
 			find_open(NULL);
-		while ((path = find_read()) != NULL) {
+		while ((path = find_read_delta(&deleted)) != NULL) {
 			const char *fid;
 			int n_fid = 0;
 			int other = 0;
@@ -611,13 +617,23 @@ incremental(const char *dbpath, const char *root)
 					continue;
 				other = 1;
 			}
-			if (stat(path, &statp) < 0)
-				die("stat failed '%s'.", path);
+			if (!deleted) {
+				if (stat(path, &statp) < 0)
+					die("stat failed '%s'.", path);
+			}
 			fid = gpath_path2fid(path, NULL);
 			if (fid) { 
 				n_fid = atoi(fid);
-				idset_add(findset, n_fid);
+				if (deleted) {
+					idset_add(deleteset, n_fid);
+					continue;
+				} else {
+					idset_add(findset, n_fid);
+				}
+			} else if (deleted) {
+				continue;
 			}
+
 			if (other) {
 				if (fid == NULL)
 					strbuf_puts0(addlist_other, path);
@@ -633,32 +649,35 @@ incremental(const char *dbpath, const char *root)
 			}
 		}
 		find_close();
+
 		/*
 		 * make delete list.
 		 */
-		limit = gpath_nextkey();
-		for (id = 1; id < limit; id++) {
-			char fid[MAXFIDLEN];
-			int type;
+		if (!Dflag) {
+			limit = gpath_nextkey();
+			for (id = 1; id < limit; id++) {
+				char fid[MAXFIDLEN];
+				int type;
 
-			snprintf(fid, sizeof(fid), "%d", id);
-			/*
-			 * This is a hole of GPATH. The hole increases if the deletion
-			 * and the addition are repeated.
-			 */
-			if ((path = gpath_fid2path(fid, &type)) == NULL)
-				continue;
-			/*
-			 * The file which does not exist in the findset is treated
-			 * assuming that it does not exist in the file system.
-			 */
-			if (type == GPATH_OTHER) {
-				if (!idset_contains(findset, id) || !test("f", path) || test("b", path))
-					strbuf_puts0(deletelist, path);
-			} else {
-				if (!idset_contains(findset, id) || !test("f", path)) {
-					strbuf_puts0(deletelist, path);
-					idset_add(deleteset, id);
+				snprintf(fid, sizeof(fid), "%d", id);
+				/*
+				 * This is a hole of GPATH. The hole increases if the deletion
+				 * and the addition are repeated.
+				 */
+				if ((path = gpath_fid2path(fid, &type)) == NULL)
+					continue;
+				/*
+				 * The file which does not exist in the findset is treated
+				 * assuming that it does not exist in the file system.
+				 */
+				if (type == GPATH_OTHER) {
+					if (!idset_contains(findset, id) || !test("f", path) || test("b", path))
+						strbuf_puts0(deletelist, path);
+				} else {
+					if (!idset_contains(findset, id) || !test("f", path)) {
+						strbuf_puts0(deletelist, path);
+						idset_add(deleteset, id);
+					}
 				}
 			}
 		}
diff --git a/gtags/manual.in b/gtags/manual.in
index 5735108..8863b80 100644
--- a/gtags/manual.in
+++ b/gtags/manual.in
@@ -61,6 +61,9 @@
 		The argument @arg{file} can be set to @val{-} to accept a list of
 		files from the standard input.
 		File names must be separated by newline.
+	@item{@option{-D}, @option{--delta}}
+		Batch update tag files incrementally for files specified in option '-f'.
+		Use in conjunction with incremental update.
 	@item{@option{--gtagsconf} @arg{file}}
 		Set environment variable @var{GTAGSCONF} to @arg{file}.
 	@item{@option{--gtagslabel} @arg{label}}
diff --git a/libutil/find.c b/libutil/find.c
index 54f24eb..8b9c109 100644
--- a/libutil/find.c
+++ b/libutil/find.c
@@ -106,7 +106,8 @@ static int find_eof;
 
 static void trim(char *);
 static char *find_read_traverse(void);
-static char *find_read_filelist(void);
+static char *find_read_filelist(char *deleted);
+static char *find_read_internal(char *deleted);
 
 extern int qflag;
 extern int debug;
@@ -654,6 +655,7 @@ find_open_filelist(const char *filename, const char *root)
 		snprintf(rootdir, sizeof(rootdir), "%s/", root);
 	strlimcpy(cwddir, root, sizeof(cwddir));
 }
+
 /**
  * find_read: read path without @VAR{GPATH}.
  *
@@ -662,19 +664,32 @@ find_open_filelist(const char *filename, const char *root)
 char *
 find_read(void)
 {
+    return find_read_internal(0);
+}
+
+char *
+find_read_delta(char *deleted)
+{
+    return find_read_internal(deleted);
+}
+
+static char *
+find_read_internal(char *deleted)
+{
 	static char *path;
 
 	assert(find_mode != 0);
 	if (find_eof)
 		path = NULL;
 	else if (find_mode == FILELIST_OPEN)
-		path = find_read_filelist();
+		path = find_read_filelist(deleted);
 	else if (find_mode == FIND_OPEN)
 		path = find_read_traverse();
 	else
 		die("find_read: internal error.");
 	return path;
 }
+
 /**
  * find_read_traverse: read path without @VAR{GPATH}.
  *
@@ -781,12 +796,15 @@ find_read_traverse(void)
  *	@return		path
  */
 static char *
-find_read_filelist(void)
+find_read_filelist(char *deleted)
 {
 	STATIC_STRBUF(ib);
 	static char buf[MAXPATHLEN + 1];
 	static char *path;
 
+	if (deleted)
+		*deleted = 0;
+
 	strbuf_clear(ib);
 	for (;;) {
 		path = strbuf_fgets(ib, ip, STRBUF_NOCRLF);
@@ -814,9 +832,14 @@ find_read_filelist(void)
 			if (test("d", path))
 				warning("'%s' is a directory. ignored.", trimpath(path));
 			else
-				warning("'%s' not found. ignored.", trimpath(path));
-			continue;
+			    if (deleted) {
+				    *deleted = 1;
+			    } else {
+				    warning("'%s' not found. ignored.", trimpath(path));
+				    continue;
+			    }
 		}
+
 		/*
 		 * normalize path name.
 		 *
diff --git a/libutil/find.h b/libutil/find.h
index 778ba5f..dade074 100644
--- a/libutil/find.h
+++ b/libutil/find.h
@@ -27,6 +27,7 @@ int issourcefile(const char *);
 void find_open(const char *);
 void find_open_filelist(const char *, const char *);
 char *find_read(void);
+char *find_read_delta(char *deleted);
 void find_close(void);
 
 #endif /* ! _FIND_H_ */
