~ubuntu-branches/debian/sid/git/sid

« back to all changes in this revision

Viewing changes to wt-status.c

  • Committer: Package Import Robot
  • Author(s): Jonathan Nieder
  • Date: 2013-06-12 07:50:53 UTC
  • mfrom: (1.2.19) (2.1.31 experimental)
  • Revision ID: package-import@ubuntu.com-20130612075053-uue9xe0dq0rvm44y
Tags: 1:1.8.3.1-1
* merge branch debian-experimental
* new upstream point release (see RelNotes/1.8.3.1.txt).
* debian/watch: use xz-compressed tarballs from kernel.org.

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
#include "remote.h"
12
12
#include "refs.h"
13
13
#include "submodule.h"
 
14
#include "column.h"
 
15
#include "strbuf.h"
14
16
 
15
17
static char default_wt_status_colors[][COLOR_MAXLEN] = {
16
18
        GIT_COLOR_NORMAL, /* WT_STATUS_HEADER */
43
45
 
44
46
        strbuf_vaddf(&sb, fmt, ap);
45
47
        if (!sb.len) {
46
 
                strbuf_addch(&sb, '#');
 
48
                strbuf_addch(&sb, comment_line_char);
47
49
                if (!trail)
48
50
                        strbuf_addch(&sb, ' ');
49
51
                color_print_strbuf(s->fp, color, &sb);
57
59
 
58
60
                strbuf_reset(&linebuf);
59
61
                if (at_bol) {
60
 
                        strbuf_addch(&linebuf, '#');
 
62
                        strbuf_addch(&linebuf, comment_line_char);
61
63
                        if (*line != '\n' && *line != '\t')
62
64
                                strbuf_addch(&linebuf, ' ');
63
65
                }
98
100
        va_end(ap);
99
101
}
100
102
 
101
 
void status_printf_more(struct wt_status *s, const char *color,
102
 
                        const char *fmt, ...)
 
103
static void status_printf_more(struct wt_status *s, const char *color,
 
104
                               const char *fmt, ...)
103
105
{
104
106
        va_list ap;
105
107
 
129
131
 
130
132
static void wt_status_print_unmerged_header(struct wt_status *s)
131
133
{
 
134
        int i;
 
135
        int del_mod_conflict = 0;
 
136
        int both_deleted = 0;
 
137
        int not_deleted = 0;
132
138
        const char *c = color(WT_STATUS_HEADER, s);
133
139
 
134
140
        status_printf_ln(s, c, _("Unmerged paths:"));
 
141
 
 
142
        for (i = 0; i < s->change.nr; i++) {
 
143
                struct string_list_item *it = &(s->change.items[i]);
 
144
                struct wt_status_change_data *d = it->util;
 
145
 
 
146
                switch (d->stagemask) {
 
147
                case 0:
 
148
                        break;
 
149
                case 1:
 
150
                        both_deleted = 1;
 
151
                        break;
 
152
                case 3:
 
153
                case 5:
 
154
                        del_mod_conflict = 1;
 
155
                        break;
 
156
                default:
 
157
                        not_deleted = 1;
 
158
                        break;
 
159
                }
 
160
        }
 
161
 
135
162
        if (!advice_status_hints)
136
163
                return;
137
164
        if (s->whence != FROM_COMMIT)
140
167
                status_printf_ln(s, c, _("  (use \"git reset %s <file>...\" to unstage)"), s->reference);
141
168
        else
142
169
                status_printf_ln(s, c, _("  (use \"git rm --cached <file>...\" to unstage)"));
143
 
        status_printf_ln(s, c, _("  (use \"git add/rm <file>...\" as appropriate to mark resolution)"));
 
170
 
 
171
        if (!both_deleted) {
 
172
                if (!del_mod_conflict)
 
173
                        status_printf_ln(s, c, _("  (use \"git add <file>...\" to mark resolution)"));
 
174
                else
 
175
                        status_printf_ln(s, c, _("  (use \"git add/rm <file>...\" as appropriate to mark resolution)"));
 
176
        } else if (!del_mod_conflict && !not_deleted) {
 
177
                status_printf_ln(s, c, _("  (use \"git rm <file>...\" to mark resolution)"));
 
178
        } else {
 
179
                status_printf_ln(s, c, _("  (use \"git add/rm <file>...\" as appropriate to mark resolution)"));
 
180
        }
144
181
        status_printf_ln(s, c, "");
145
182
}
146
183
 
184
221
                                         const char *how)
185
222
{
186
223
        const char *c = color(WT_STATUS_HEADER, s);
187
 
        status_printf_ln(s, c, _("%s files:"), what);
 
224
        status_printf_ln(s, c, "%s:", what);
188
225
        if (!advice_status_hints)
189
226
                return;
190
227
        status_printf_ln(s, c, _("  (use \"git %s <file>...\" to include in what will be committed)"), how);
227
264
{
228
265
        struct wt_status_change_data *d = it->util;
229
266
        const char *c = color(change_type, s);
230
 
        int status = status;
 
267
        int status;
231
268
        char *one_name;
232
269
        char *two_name;
233
270
        const char *one, *two;
255
292
                }
256
293
                status = d->worktree_status;
257
294
                break;
 
295
        default:
 
296
                die("BUG: unhandled change_type %d in wt_status_print_change_data",
 
297
                    change_type);
258
298
        }
259
299
 
260
300
        one = quote_path(one_name, -1, &onebuf, s->prefix);
459
499
{
460
500
        int i;
461
501
        struct dir_struct dir;
 
502
        struct timeval t_begin;
462
503
 
463
504
        if (!s->show_untracked_files)
464
505
                return;
 
506
 
 
507
        if (advice_status_u_option)
 
508
                gettimeofday(&t_begin, NULL);
 
509
 
465
510
        memset(&dir, 0, sizeof(dir));
466
511
        if (s->show_untracked_files != SHOW_ALL_UNTRACKED_FILES)
467
512
                dir.flags |=
468
513
                        DIR_SHOW_OTHER_DIRECTORIES | DIR_HIDE_EMPTY_DIRECTORIES;
 
514
        if (s->show_ignored_files)
 
515
                dir.flags |= DIR_SHOW_IGNORED_TOO;
469
516
        setup_standard_excludes(&dir);
470
517
 
471
518
        fill_directory(&dir, s->pathspec);
 
519
 
472
520
        for (i = 0; i < dir.nr; i++) {
473
521
                struct dir_entry *ent = dir.entries[i];
474
522
                if (cache_name_is_other(ent->name, ent->len) &&
477
525
                free(ent);
478
526
        }
479
527
 
480
 
        if (s->show_ignored_files) {
481
 
                dir.nr = 0;
482
 
                dir.flags = DIR_SHOW_IGNORED | DIR_SHOW_OTHER_DIRECTORIES;
483
 
                fill_directory(&dir, s->pathspec);
484
 
                for (i = 0; i < dir.nr; i++) {
485
 
                        struct dir_entry *ent = dir.entries[i];
486
 
                        if (cache_name_is_other(ent->name, ent->len) &&
487
 
                            match_pathspec(s->pathspec, ent->name, ent->len, 0, NULL))
488
 
                                string_list_insert(&s->ignored, ent->name);
489
 
                        free(ent);
490
 
                }
 
528
        for (i = 0; i < dir.ignored_nr; i++) {
 
529
                struct dir_entry *ent = dir.ignored[i];
 
530
                if (cache_name_is_other(ent->name, ent->len) &&
 
531
                    match_pathspec(s->pathspec, ent->name, ent->len, 0, NULL))
 
532
                        string_list_insert(&s->ignored, ent->name);
 
533
                free(ent);
491
534
        }
492
535
 
493
536
        free(dir.entries);
 
537
        free(dir.ignored);
 
538
        clear_directory(&dir);
 
539
 
 
540
        if (advice_status_u_option) {
 
541
                struct timeval t_end;
 
542
                gettimeofday(&t_end, NULL);
 
543
                s->untracked_in_ms =
 
544
                        (uint64_t)t_end.tv_sec * 1000 + t_end.tv_usec / 1000 -
 
545
                        ((uint64_t)t_begin.tv_sec * 1000 + t_begin.tv_usec / 1000);
 
546
        }
494
547
}
495
548
 
496
549
void wt_status_collect(struct wt_status *s)
641
694
{
642
695
        int i;
643
696
        struct strbuf buf = STRBUF_INIT;
 
697
        static struct string_list output = STRING_LIST_INIT_DUP;
 
698
        struct column_options copts;
644
699
 
645
700
        if (!l->nr)
646
701
                return;
649
704
 
650
705
        for (i = 0; i < l->nr; i++) {
651
706
                struct string_list_item *it;
 
707
                const char *path;
652
708
                it = &(l->items[i]);
 
709
                path = quote_path(it->string, strlen(it->string),
 
710
                                  &buf, s->prefix);
 
711
                if (column_active(s->colopts)) {
 
712
                        string_list_append(&output, path);
 
713
                        continue;
 
714
                }
653
715
                status_printf(s, color(WT_STATUS_HEADER, s), "\t");
654
716
                status_printf_more(s, color(WT_STATUS_UNTRACKED, s),
655
 
                        "%s\n", quote_path(it->string, strlen(it->string),
656
 
                                            &buf, s->prefix));
 
717
                                   "%s\n", path);
657
718
        }
 
719
 
 
720
        strbuf_release(&buf);
 
721
        if (!column_active(s->colopts))
 
722
                return;
 
723
 
 
724
        strbuf_addf(&buf, "%s#\t%s",
 
725
                    color(WT_STATUS_HEADER, s),
 
726
                    color(WT_STATUS_UNTRACKED, s));
 
727
        memset(&copts, 0, sizeof(copts));
 
728
        copts.padding = 1;
 
729
        copts.indent = buf.buf;
 
730
        if (want_color(s->use_color))
 
731
                copts.nl = GIT_COLOR_RESET "\n";
 
732
        print_columns(&output, s->colopts, &copts);
 
733
        string_list_clear(&output, 0);
658
734
        strbuf_release(&buf);
659
735
}
660
736
 
700
776
 
701
777
        for (cp = sb.buf; (ep = strchr(cp, '\n')) != NULL; cp = ep + 1)
702
778
                color_fprintf_ln(s->fp, color(WT_STATUS_HEADER, s),
703
 
                                 "# %.*s", (int)(ep - cp), cp);
704
 
        color_fprintf_ln(s->fp, color(WT_STATUS_HEADER, s), "#");
 
779
                                 "%c %.*s", comment_line_char,
 
780
                                 (int)(ep - cp), cp);
 
781
        color_fprintf_ln(s->fp, color(WT_STATUS_HEADER, s), "%c",
 
782
                         comment_line_char);
 
783
}
 
784
 
 
785
static int has_unmerged(struct wt_status *s)
 
786
{
 
787
        int i;
 
788
 
 
789
        for (i = 0; i < s->change.nr; i++) {
 
790
                struct wt_status_change_data *d;
 
791
                d = s->change.items[i].util;
 
792
                if (d->stagemask)
 
793
                        return 1;
 
794
        }
 
795
        return 0;
 
796
}
 
797
 
 
798
static void show_merge_in_progress(struct wt_status *s,
 
799
                                struct wt_status_state *state,
 
800
                                const char *color)
 
801
{
 
802
        if (has_unmerged(s)) {
 
803
                status_printf_ln(s, color, _("You have unmerged paths."));
 
804
                if (advice_status_hints)
 
805
                        status_printf_ln(s, color,
 
806
                                _("  (fix conflicts and run \"git commit\")"));
 
807
        } else {
 
808
                status_printf_ln(s, color,
 
809
                        _("All conflicts fixed but you are still merging."));
 
810
                if (advice_status_hints)
 
811
                        status_printf_ln(s, color,
 
812
                                _("  (use \"git commit\" to conclude merge)"));
 
813
        }
 
814
        wt_status_print_trailer(s);
 
815
}
 
816
 
 
817
static void show_am_in_progress(struct wt_status *s,
 
818
                                struct wt_status_state *state,
 
819
                                const char *color)
 
820
{
 
821
        status_printf_ln(s, color,
 
822
                _("You are in the middle of an am session."));
 
823
        if (state->am_empty_patch)
 
824
                status_printf_ln(s, color,
 
825
                        _("The current patch is empty."));
 
826
        if (advice_status_hints) {
 
827
                if (!state->am_empty_patch)
 
828
                        status_printf_ln(s, color,
 
829
                                _("  (fix conflicts and then run \"git am --resolved\")"));
 
830
                status_printf_ln(s, color,
 
831
                        _("  (use \"git am --skip\" to skip this patch)"));
 
832
                status_printf_ln(s, color,
 
833
                        _("  (use \"git am --abort\" to restore the original branch)"));
 
834
        }
 
835
        wt_status_print_trailer(s);
 
836
}
 
837
 
 
838
static char *read_line_from_git_path(const char *filename)
 
839
{
 
840
        struct strbuf buf = STRBUF_INIT;
 
841
        FILE *fp = fopen(git_path("%s", filename), "r");
 
842
        if (!fp) {
 
843
                strbuf_release(&buf);
 
844
                return NULL;
 
845
        }
 
846
        strbuf_getline(&buf, fp, '\n');
 
847
        if (!fclose(fp)) {
 
848
                return strbuf_detach(&buf, NULL);
 
849
        } else {
 
850
                strbuf_release(&buf);
 
851
                return NULL;
 
852
        }
 
853
}
 
854
 
 
855
static int split_commit_in_progress(struct wt_status *s)
 
856
{
 
857
        int split_in_progress = 0;
 
858
        char *head = read_line_from_git_path("HEAD");
 
859
        char *orig_head = read_line_from_git_path("ORIG_HEAD");
 
860
        char *rebase_amend = read_line_from_git_path("rebase-merge/amend");
 
861
        char *rebase_orig_head = read_line_from_git_path("rebase-merge/orig-head");
 
862
 
 
863
        if (!head || !orig_head || !rebase_amend || !rebase_orig_head ||
 
864
            !s->branch || strcmp(s->branch, "HEAD"))
 
865
                return split_in_progress;
 
866
 
 
867
        if (!strcmp(rebase_amend, rebase_orig_head)) {
 
868
                if (strcmp(head, rebase_amend))
 
869
                        split_in_progress = 1;
 
870
        } else if (strcmp(orig_head, rebase_orig_head)) {
 
871
                split_in_progress = 1;
 
872
        }
 
873
 
 
874
        if (!s->amend && !s->nowarn && !s->workdir_dirty)
 
875
                split_in_progress = 0;
 
876
 
 
877
        free(head);
 
878
        free(orig_head);
 
879
        free(rebase_amend);
 
880
        free(rebase_orig_head);
 
881
        return split_in_progress;
 
882
}
 
883
 
 
884
static void show_rebase_in_progress(struct wt_status *s,
 
885
                                struct wt_status_state *state,
 
886
                                const char *color)
 
887
{
 
888
        struct stat st;
 
889
 
 
890
        if (has_unmerged(s)) {
 
891
                if (state->branch)
 
892
                        status_printf_ln(s, color,
 
893
                                         _("You are currently rebasing branch '%s' on '%s'."),
 
894
                                         state->branch,
 
895
                                         state->onto);
 
896
                else
 
897
                        status_printf_ln(s, color,
 
898
                                         _("You are currently rebasing."));
 
899
                if (advice_status_hints) {
 
900
                        status_printf_ln(s, color,
 
901
                                _("  (fix conflicts and then run \"git rebase --continue\")"));
 
902
                        status_printf_ln(s, color,
 
903
                                _("  (use \"git rebase --skip\" to skip this patch)"));
 
904
                        status_printf_ln(s, color,
 
905
                                _("  (use \"git rebase --abort\" to check out the original branch)"));
 
906
                }
 
907
        } else if (state->rebase_in_progress || !stat(git_path("MERGE_MSG"), &st)) {
 
908
                if (state->branch)
 
909
                        status_printf_ln(s, color,
 
910
                                         _("You are currently rebasing branch '%s' on '%s'."),
 
911
                                         state->branch,
 
912
                                         state->onto);
 
913
                else
 
914
                        status_printf_ln(s, color,
 
915
                                         _("You are currently rebasing."));
 
916
                if (advice_status_hints)
 
917
                        status_printf_ln(s, color,
 
918
                                _("  (all conflicts fixed: run \"git rebase --continue\")"));
 
919
        } else if (split_commit_in_progress(s)) {
 
920
                if (state->branch)
 
921
                        status_printf_ln(s, color,
 
922
                                         _("You are currently splitting a commit while rebasing branch '%s' on '%s'."),
 
923
                                         state->branch,
 
924
                                         state->onto);
 
925
                else
 
926
                        status_printf_ln(s, color,
 
927
                                         _("You are currently splitting a commit during a rebase."));
 
928
                if (advice_status_hints)
 
929
                        status_printf_ln(s, color,
 
930
                                _("  (Once your working directory is clean, run \"git rebase --continue\")"));
 
931
        } else {
 
932
                if (state->branch)
 
933
                        status_printf_ln(s, color,
 
934
                                         _("You are currently editing a commit while rebasing branch '%s' on '%s'."),
 
935
                                         state->branch,
 
936
                                         state->onto);
 
937
                else
 
938
                        status_printf_ln(s, color,
 
939
                                         _("You are currently editing a commit during a rebase."));
 
940
                if (advice_status_hints && !s->amend) {
 
941
                        status_printf_ln(s, color,
 
942
                                _("  (use \"git commit --amend\" to amend the current commit)"));
 
943
                        status_printf_ln(s, color,
 
944
                                _("  (use \"git rebase --continue\" once you are satisfied with your changes)"));
 
945
                }
 
946
        }
 
947
        wt_status_print_trailer(s);
 
948
}
 
949
 
 
950
static void show_cherry_pick_in_progress(struct wt_status *s,
 
951
                                        struct wt_status_state *state,
 
952
                                        const char *color)
 
953
{
 
954
        status_printf_ln(s, color, _("You are currently cherry-picking."));
 
955
        if (advice_status_hints) {
 
956
                if (has_unmerged(s))
 
957
                        status_printf_ln(s, color,
 
958
                                _("  (fix conflicts and run \"git commit\")"));
 
959
                else
 
960
                        status_printf_ln(s, color,
 
961
                                _("  (all conflicts fixed: run \"git commit\")"));
 
962
        }
 
963
        wt_status_print_trailer(s);
 
964
}
 
965
 
 
966
static void show_revert_in_progress(struct wt_status *s,
 
967
                                        struct wt_status_state *state,
 
968
                                        const char *color)
 
969
{
 
970
        status_printf_ln(s, color, _("You are currently reverting commit %s."),
 
971
                         find_unique_abbrev(state->revert_head_sha1, DEFAULT_ABBREV));
 
972
        if (advice_status_hints) {
 
973
                if (has_unmerged(s))
 
974
                        status_printf_ln(s, color,
 
975
                                _("  (fix conflicts and run \"git revert --continue\")"));
 
976
                else
 
977
                        status_printf_ln(s, color,
 
978
                                _("  (all conflicts fixed: run \"git revert --continue\")"));
 
979
                status_printf_ln(s, color,
 
980
                        _("  (use \"git revert --abort\" to cancel the revert operation)"));
 
981
        }
 
982
        wt_status_print_trailer(s);
 
983
}
 
984
 
 
985
static void show_bisect_in_progress(struct wt_status *s,
 
986
                                struct wt_status_state *state,
 
987
                                const char *color)
 
988
{
 
989
        if (state->branch)
 
990
                status_printf_ln(s, color,
 
991
                                 _("You are currently bisecting, started from branch '%s'."),
 
992
                                 state->branch);
 
993
        else
 
994
                status_printf_ln(s, color,
 
995
                                 _("You are currently bisecting."));
 
996
        if (advice_status_hints)
 
997
                status_printf_ln(s, color,
 
998
                        _("  (use \"git bisect reset\" to get back to the original branch)"));
 
999
        wt_status_print_trailer(s);
 
1000
}
 
1001
 
 
1002
/*
 
1003
 * Extract branch information from rebase/bisect
 
1004
 */
 
1005
static char *read_and_strip_branch(const char *path)
 
1006
{
 
1007
        struct strbuf sb = STRBUF_INIT;
 
1008
        unsigned char sha1[20];
 
1009
 
 
1010
        if (strbuf_read_file(&sb, git_path("%s", path), 0) <= 0)
 
1011
                goto got_nothing;
 
1012
 
 
1013
        while (&sb.len && sb.buf[sb.len - 1] == '\n')
 
1014
                strbuf_setlen(&sb, sb.len - 1);
 
1015
        if (!sb.len)
 
1016
                goto got_nothing;
 
1017
        if (!prefixcmp(sb.buf, "refs/heads/"))
 
1018
                strbuf_remove(&sb,0, strlen("refs/heads/"));
 
1019
        else if (!prefixcmp(sb.buf, "refs/"))
 
1020
                ;
 
1021
        else if (!get_sha1_hex(sb.buf, sha1)) {
 
1022
                const char *abbrev;
 
1023
                abbrev = find_unique_abbrev(sha1, DEFAULT_ABBREV);
 
1024
                strbuf_reset(&sb);
 
1025
                strbuf_addstr(&sb, abbrev);
 
1026
        } else if (!strcmp(sb.buf, "detached HEAD")) /* rebase */
 
1027
                goto got_nothing;
 
1028
        else                    /* bisect */
 
1029
                ;
 
1030
        return strbuf_detach(&sb, NULL);
 
1031
 
 
1032
got_nothing:
 
1033
        strbuf_release(&sb);
 
1034
        return NULL;
 
1035
}
 
1036
 
 
1037
struct grab_1st_switch_cbdata {
 
1038
        int found;
 
1039
        struct strbuf buf;
 
1040
        unsigned char nsha1[20];
 
1041
};
 
1042
 
 
1043
static int grab_1st_switch(unsigned char *osha1, unsigned char *nsha1,
 
1044
                           const char *email, unsigned long timestamp, int tz,
 
1045
                           const char *message, void *cb_data)
 
1046
{
 
1047
        struct grab_1st_switch_cbdata *cb = cb_data;
 
1048
        const char *target = NULL, *end;
 
1049
 
 
1050
        if (prefixcmp(message, "checkout: moving from "))
 
1051
                return 0;
 
1052
        message += strlen("checkout: moving from ");
 
1053
        target = strstr(message, " to ");
 
1054
        if (!target)
 
1055
                return 0;
 
1056
        target += strlen(" to ");
 
1057
        strbuf_reset(&cb->buf);
 
1058
        hashcpy(cb->nsha1, nsha1);
 
1059
        for (end = target; *end && *end != '\n'; end++)
 
1060
                ;
 
1061
        strbuf_add(&cb->buf, target, end - target);
 
1062
        cb->found = 1;
 
1063
        return 1;
 
1064
}
 
1065
 
 
1066
static void wt_status_get_detached_from(struct wt_status_state *state)
 
1067
{
 
1068
        struct grab_1st_switch_cbdata cb;
 
1069
        struct commit *commit;
 
1070
        unsigned char sha1[20];
 
1071
        char *ref = NULL;
 
1072
 
 
1073
        strbuf_init(&cb.buf, 0);
 
1074
        if (for_each_reflog_ent_reverse("HEAD", grab_1st_switch, &cb) <= 0) {
 
1075
                strbuf_release(&cb.buf);
 
1076
                return;
 
1077
        }
 
1078
 
 
1079
        if (dwim_ref(cb.buf.buf, cb.buf.len, sha1, &ref) == 1 &&
 
1080
            /* sha1 is a commit? match without further lookup */
 
1081
            (!hashcmp(cb.nsha1, sha1) ||
 
1082
             /* perhaps sha1 is a tag, try to dereference to a commit */
 
1083
             ((commit = lookup_commit_reference_gently(sha1, 1)) != NULL &&
 
1084
              !hashcmp(cb.nsha1, commit->object.sha1)))) {
 
1085
                int ofs;
 
1086
                if (!prefixcmp(ref, "refs/tags/"))
 
1087
                        ofs = strlen("refs/tags/");
 
1088
                else if (!prefixcmp(ref, "refs/remotes/"))
 
1089
                        ofs = strlen("refs/remotes/");
 
1090
                else
 
1091
                        ofs = 0;
 
1092
                state->detached_from = xstrdup(ref + ofs);
 
1093
        } else
 
1094
                state->detached_from =
 
1095
                        xstrdup(find_unique_abbrev(cb.nsha1, DEFAULT_ABBREV));
 
1096
        hashcpy(state->detached_sha1, cb.nsha1);
 
1097
 
 
1098
        free(ref);
 
1099
        strbuf_release(&cb.buf);
 
1100
}
 
1101
 
 
1102
void wt_status_get_state(struct wt_status_state *state,
 
1103
                         int get_detached_from)
 
1104
{
 
1105
        struct stat st;
 
1106
        unsigned char sha1[20];
 
1107
 
 
1108
        if (!stat(git_path("MERGE_HEAD"), &st)) {
 
1109
                state->merge_in_progress = 1;
 
1110
        } else if (!stat(git_path("rebase-apply"), &st)) {
 
1111
                if (!stat(git_path("rebase-apply/applying"), &st)) {
 
1112
                        state->am_in_progress = 1;
 
1113
                        if (!stat(git_path("rebase-apply/patch"), &st) && !st.st_size)
 
1114
                                state->am_empty_patch = 1;
 
1115
                } else {
 
1116
                        state->rebase_in_progress = 1;
 
1117
                        state->branch = read_and_strip_branch("rebase-apply/head-name");
 
1118
                        state->onto = read_and_strip_branch("rebase-apply/onto");
 
1119
                }
 
1120
        } else if (!stat(git_path("rebase-merge"), &st)) {
 
1121
                if (!stat(git_path("rebase-merge/interactive"), &st))
 
1122
                        state->rebase_interactive_in_progress = 1;
 
1123
                else
 
1124
                        state->rebase_in_progress = 1;
 
1125
                state->branch = read_and_strip_branch("rebase-merge/head-name");
 
1126
                state->onto = read_and_strip_branch("rebase-merge/onto");
 
1127
        } else if (!stat(git_path("CHERRY_PICK_HEAD"), &st)) {
 
1128
                state->cherry_pick_in_progress = 1;
 
1129
        }
 
1130
        if (!stat(git_path("BISECT_LOG"), &st)) {
 
1131
                state->bisect_in_progress = 1;
 
1132
                state->branch = read_and_strip_branch("BISECT_START");
 
1133
        }
 
1134
        if (!stat(git_path("REVERT_HEAD"), &st) &&
 
1135
            !get_sha1("REVERT_HEAD", sha1)) {
 
1136
                state->revert_in_progress = 1;
 
1137
                hashcpy(state->revert_head_sha1, sha1);
 
1138
        }
 
1139
 
 
1140
        if (get_detached_from)
 
1141
                wt_status_get_detached_from(state);
 
1142
}
 
1143
 
 
1144
static void wt_status_print_state(struct wt_status *s,
 
1145
                                  struct wt_status_state *state)
 
1146
{
 
1147
        const char *state_color = color(WT_STATUS_HEADER, s);
 
1148
        if (state->merge_in_progress)
 
1149
                show_merge_in_progress(s, state, state_color);
 
1150
        else if (state->am_in_progress)
 
1151
                show_am_in_progress(s, state, state_color);
 
1152
        else if (state->rebase_in_progress || state->rebase_interactive_in_progress)
 
1153
                show_rebase_in_progress(s, state, state_color);
 
1154
        else if (state->cherry_pick_in_progress)
 
1155
                show_cherry_pick_in_progress(s, state, state_color);
 
1156
        else if (state->revert_in_progress)
 
1157
                show_revert_in_progress(s, state, state_color);
 
1158
        if (state->bisect_in_progress)
 
1159
                show_bisect_in_progress(s, state, state_color);
705
1160
}
706
1161
 
707
1162
void wt_status_print(struct wt_status *s)
708
1163
{
709
1164
        const char *branch_color = color(WT_STATUS_ONBRANCH, s);
710
1165
        const char *branch_status_color = color(WT_STATUS_HEADER, s);
 
1166
        struct wt_status_state state;
 
1167
 
 
1168
        memset(&state, 0, sizeof(state));
 
1169
        wt_status_get_state(&state,
 
1170
                            s->branch && !strcmp(s->branch, "HEAD"));
711
1171
 
712
1172
        if (s->branch) {
713
1173
                const char *on_what = _("On branch ");
715
1175
                if (!prefixcmp(branch_name, "refs/heads/"))
716
1176
                        branch_name += 11;
717
1177
                else if (!strcmp(branch_name, "HEAD")) {
718
 
                        branch_name = "";
719
1178
                        branch_status_color = color(WT_STATUS_NOBRANCH, s);
720
 
                        on_what = _("Not currently on any branch.");
 
1179
                        if (state.detached_from) {
 
1180
                                unsigned char sha1[20];
 
1181
                                branch_name = state.detached_from;
 
1182
                                if (!get_sha1("HEAD", sha1) &&
 
1183
                                    !hashcmp(sha1, state.detached_sha1))
 
1184
                                        on_what = _("HEAD detached at ");
 
1185
                                else
 
1186
                                        on_what = _("HEAD detached from ");
 
1187
                        } else {
 
1188
                                branch_name = "";
 
1189
                                on_what = _("Not currently on any branch.");
 
1190
                        }
721
1191
                }
722
1192
                status_printf(s, color(WT_STATUS_HEADER, s), "");
723
1193
                status_printf_more(s, branch_status_color, "%s", on_what);
726
1196
                        wt_status_print_tracking(s);
727
1197
        }
728
1198
 
 
1199
        wt_status_print_state(s, &state);
 
1200
        free(state.branch);
 
1201
        free(state.onto);
 
1202
        free(state.detached_from);
 
1203
 
729
1204
        if (s->is_initial) {
730
1205
                status_printf_ln(s, color(WT_STATUS_HEADER, s), "");
731
1206
                status_printf_ln(s, color(WT_STATUS_HEADER, s), _("Initial commit"));
742
1217
                wt_status_print_submodule_summary(s, 1);  /* unstaged */
743
1218
        }
744
1219
        if (s->show_untracked_files) {
745
 
                wt_status_print_other(s, &s->untracked, _("Untracked"), "add");
 
1220
                wt_status_print_other(s, &s->untracked, _("Untracked files"), "add");
746
1221
                if (s->show_ignored_files)
747
 
                        wt_status_print_other(s, &s->ignored, _("Ignored"), "add -f");
 
1222
                        wt_status_print_other(s, &s->ignored, _("Ignored files"), "add -f");
 
1223
                if (advice_status_u_option && 2000 < s->untracked_in_ms) {
 
1224
                        status_printf_ln(s, GIT_COLOR_NORMAL, "");
 
1225
                        status_printf_ln(s, GIT_COLOR_NORMAL,
 
1226
                                         _("It took %.2f seconds to enumerate untracked files. 'status -uno'\n"
 
1227
                                           "may speed it up, but you have to be careful not to forget to add\n"
 
1228
                                           "new files yourself (see 'git help status')."),
 
1229
                                         s->untracked_in_ms / 1000.0);
 
1230
                }
748
1231
        } else if (s->commitable)
749
1232
                status_printf_ln(s, GIT_COLOR_NORMAL, _("Untracked files not listed%s"),
750
1233
                        advice_status_hints
757
1240
                        status_printf_ln(s, GIT_COLOR_NORMAL, _("No changes"));
758
1241
                else if (s->nowarn)
759
1242
                        ; /* nothing */
760
 
                else if (s->workdir_dirty)
761
 
                        printf(_("no changes added to commit%s\n"),
762
 
                                advice_status_hints
763
 
                                ? _(" (use \"git add\" and/or \"git commit -a\")") : "");
764
 
                else if (s->untracked.nr)
765
 
                        printf(_("nothing added to commit but untracked files present%s\n"),
766
 
                                advice_status_hints
767
 
                                ? _(" (use \"git add\" to track)") : "");
768
 
                else if (s->is_initial)
769
 
                        printf(_("nothing to commit%s\n"), advice_status_hints
770
 
                                ? _(" (create/copy files and use \"git add\" to track)") : "");
771
 
                else if (!s->show_untracked_files)
772
 
                        printf(_("nothing to commit%s\n"), advice_status_hints
773
 
                                ? _(" (use -u to show untracked files)") : "");
774
 
                else
775
 
                        printf(_("nothing to commit%s\n"), advice_status_hints
776
 
                                ? _(" (working directory clean)") : "");
 
1243
                else if (s->workdir_dirty) {
 
1244
                        if (advice_status_hints)
 
1245
                                printf(_("no changes added to commit "
 
1246
                                         "(use \"git add\" and/or \"git commit -a\")\n"));
 
1247
                        else
 
1248
                                printf(_("no changes added to commit\n"));
 
1249
                } else if (s->untracked.nr) {
 
1250
                        if (advice_status_hints)
 
1251
                                printf(_("nothing added to commit but untracked files "
 
1252
                                         "present (use \"git add\" to track)\n"));
 
1253
                        else
 
1254
                                printf(_("nothing added to commit but untracked files present\n"));
 
1255
                } else if (s->is_initial) {
 
1256
                        if (advice_status_hints)
 
1257
                                printf(_("nothing to commit (create/copy files "
 
1258
                                         "and use \"git add\" to track)\n"));
 
1259
                        else
 
1260
                                printf(_("nothing to commit\n"));
 
1261
                } else if (!s->show_untracked_files) {
 
1262
                        if (advice_status_hints)
 
1263
                                printf(_("nothing to commit (use -u to show untracked files)\n"));
 
1264
                        else
 
1265
                                printf(_("nothing to commit\n"));
 
1266
                } else
 
1267
                        printf(_("nothing to commit, working directory clean\n"));
777
1268
        }
778
1269
}
779
1270