#include "tree-walk.h"
#include "cache-tree.h"
#include "unpack-trees.h"
+#include "progress.h"
#define DBRT_DEBUG 1
* directories, in case this unlink is the removal of the
* last entry in the directory -- empty directories are removed.
*/
-static void unlink_entry(char *name)
+static void unlink_entry(char *name, char *last_symlink)
{
char *cp, *prev;
+ if (has_symlink_leading_path(name, last_symlink))
+ return;
if (unlink(name))
return;
prev = NULL;
}
}
-static volatile sig_atomic_t progress_update;
-
-static void progress_interval(int signum)
-{
- progress_update = 1;
-}
-
-static void setup_progress_signal(void)
-{
- struct sigaction sa;
- struct itimerval v;
-
- memset(&sa, 0, sizeof(sa));
- sa.sa_handler = progress_interval;
- sigemptyset(&sa.sa_mask);
- sa.sa_flags = SA_RESTART;
- sigaction(SIGALRM, &sa, NULL);
-
- v.it_interval.tv_sec = 1;
- v.it_interval.tv_usec = 0;
- v.it_value = v.it_interval;
- setitimer(ITIMER_REAL, &v, NULL);
-}
-
static struct checkout state;
static void check_updates(struct cache_entry **src, int nr,
- struct unpack_trees_options *o)
+ struct unpack_trees_options *o)
{
unsigned short mask = htons(CE_UPDATE);
- unsigned last_percent = 200, cnt = 0, total = 0;
+ unsigned cnt = 0, total = 0;
+ struct progress progress;
+ char last_symlink[PATH_MAX];
if (o->update && o->verbose_update) {
for (total = cnt = 0; cnt < nr; cnt++) {
total++;
}
- /* Don't bother doing this for very small updates */
- if (total < 250)
- total = 0;
-
- if (total) {
- fprintf(stderr, "Checking files out...\n");
- setup_progress_signal();
- progress_update = 1;
- }
+ start_progress_delay(&progress, "Checking %u files out...",
+ "", total, 50, 2);
cnt = 0;
}
+ *last_symlink = '\0';
while (nr--) {
struct cache_entry *ce = *src++;
- if (total) {
- if (!ce->ce_mode || ce->ce_flags & mask) {
- unsigned percent;
- cnt++;
- percent = (cnt * 100) / total;
- if (percent != last_percent ||
- progress_update) {
- fprintf(stderr, "%4u%% (%u/%u) done\r",
- percent, cnt, total);
- last_percent = percent;
- progress_update = 0;
- }
- }
- }
+ if (total)
+ if (!ce->ce_mode || ce->ce_flags & mask)
+ display_progress(&progress, ++cnt);
if (!ce->ce_mode) {
if (o->update)
- unlink_entry(ce->name);
+ unlink_entry(ce->name, last_symlink);
continue;
}
if (ce->ce_flags & mask) {
ce->ce_flags &= ~mask;
- if (o->update)
+ if (o->update) {
checkout_entry(ce, &state, NULL);
+ *last_symlink = '\0';
+ }
}
}
- if (total) {
- signal(SIGALRM, SIG_IGN);
- fputc('\n', stderr);
- }
+ if (total)
+ stop_progress(&progress);;
}
int unpack_trees(struct object_list *trees, struct unpack_trees_options *o)