583
clear_ref_exclusion(&ref_excludes);
584
}
585
586
+enum format_type {
587
+ /* We would like a relative path. */
588
+ FORMAT_RELATIVE,
589
+ /* We would like a canonical absolute path. */
590
+ FORMAT_CANONICAL,
591
+ /* We would like the default behavior. */
592
+ FORMAT_DEFAULT,
593
+};
594
+
595
+enum default_type {
596
+ /* Our default is a relative path. */
597
+ DEFAULT_RELATIVE,
598
+ /* Our default is a relative path if there's a shared root. */
599
+ DEFAULT_RELATIVE_IF_SHARED,
600
+ /* Our default is a canonical absolute path. */
601
+ DEFAULT_CANONICAL,
602
+ /* Our default is not to modify the item. */
603
+ DEFAULT_UNMODIFIED,
604
+};
605
+
606
+static void print_path(const char *path, const char *prefix, enum format_type format, enum default_type def)
607
+{
608
+ char *cwd = NULL;
609
+ /*
610
+ * We don't ever produce a relative path if prefix is NULL, so set the
611
+ * prefix to the current directory so that we can produce a relative
612
+ * path whenever possible. If we're using RELATIVE_IF_SHARED mode, then
613
+ * we want an absolute path unless the two share a common prefix, so don't
614
+ * set it in that case, since doing so causes a relative path to always
615
+ * be produced if possible.
616
+ */
617
+ if (!prefix && (format != FORMAT_DEFAULT || def != DEFAULT_RELATIVE_IF_SHARED))
618
+ prefix = cwd = xgetcwd();
619
+ if (format == FORMAT_DEFAULT && def == DEFAULT_UNMODIFIED) {
620
+ puts(path);
621
+ } else if (format == FORMAT_RELATIVE ||
622
+ (format == FORMAT_DEFAULT && def == DEFAULT_RELATIVE)) {
623
+ /*
624
+ * In order for relative_path to work as expected, we need to
625
+ * make sure that both paths are absolute paths. If we don't,
626
+ * we can end up with an unexpected absolute path that the user
627
+ * didn't want.
628
+ */
629
+ struct strbuf buf = STRBUF_INIT, realbuf = STRBUF_INIT, prefixbuf = STRBUF_INIT;
630
+ if (!is_absolute_path(path)) {
631
+ strbuf_realpath_forgiving(&realbuf, path, 1);
632
+ path = realbuf.buf;
633
+ }
634
+ if (!is_absolute_path(prefix)) {
635
+ strbuf_realpath_forgiving(&prefixbuf, prefix, 1);
636
+ prefix = prefixbuf.buf;
637
+ }
638
+ puts(relative_path(path, prefix, &buf));
639
+ strbuf_release(&buf);
640
+ strbuf_release(&realbuf);
641
+ strbuf_release(&prefixbuf);
642
+ } else if (format == FORMAT_DEFAULT && def == DEFAULT_RELATIVE_IF_SHARED) {
643
+ struct strbuf buf = STRBUF_INIT;
644
+ puts(relative_path(path, prefix, &buf));
645
+ strbuf_release(&buf);
646
+ } else {
647
+ struct strbuf buf = STRBUF_INIT;
648
+ strbuf_realpath_forgiving(&buf, path, 1);
649
+ puts(buf.buf);
650
+ strbuf_release(&buf);
651
+ }
652
+ free(cwd);
653
+}
654
+
655
int cmd_rev_parse(int argc, const char **argv, const char *prefix)
656
{
657
int i, as_is = 0, verify = 0, quiet = 0, revs_count = 0, type = 0;
665
struct strbuf buf = STRBUF_INIT;
666
const int hexsz = the_hash_algo->hexsz;
667
int seen_end_of_options = 0;
668
+ enum format_type format = FORMAT_DEFAULT;
669
670
if (argc > 1 && !strcmp("--parseopt", argv[1]))
671
return cmd_parseopt(argc - 1, argv + 1, prefix);
738
if (!argv[i + 1])
739
die("--git-path requires an argument");
740
strbuf_reset(&buf);
671
- puts(relative_path(git_path("%s", argv[i + 1]),
672
- prefix, &buf));
741
+ print_path(git_path("%s", argv[i + 1]), prefix,
742
+ format,
743
+ DEFAULT_RELATIVE_IF_SHARED);
744
i++;
745
continue;
746
}
758
show(arg);
759
continue;
760
}
761
+ if (opt_with_value(arg, "--path-format", &arg)) {
762
+ if (!strcmp(arg, "absolute")) {
763
+ format = FORMAT_CANONICAL;
764
+ } else if (!strcmp(arg, "relative")) {
765
+ format = FORMAT_RELATIVE;
766
+ } else {
767
+ die("unknown argument to --path-format: %s", arg);
768
+ }
769
+ continue;
770
+ }
771
if (!strcmp(arg, "--default")) {
772
def = argv[++i];
773
if (!def)
888
if (!strcmp(arg, "--show-toplevel")) {
889
const char *work_tree = get_git_work_tree();
890
if (work_tree)
810
- puts(work_tree);
891
+ print_path(work_tree, prefix, format, DEFAULT_UNMODIFIED);
892
else
893
die("this operation must be run in a work tree");
894
continue;
896
if (!strcmp(arg, "--show-superproject-working-tree")) {
897
struct strbuf superproject = STRBUF_INIT;
898
if (get_superproject_working_tree(&superproject))
818
- puts(superproject.buf);
899
+ print_path(superproject.buf, prefix, format, DEFAULT_UNMODIFIED);
900
strbuf_release(&superproject);
901
continue;
902
}
931
const char *gitdir = getenv(GIT_DIR_ENVIRONMENT);
932
char *cwd;
933
int len;
934
+ enum format_type wanted = format;
935
if (arg[2] == 'g') { /* --git-dir */
936
if (gitdir) {
855
- puts(gitdir);
937
+ print_path(gitdir, prefix, format, DEFAULT_UNMODIFIED);
938
continue;
939
}
940
if (!prefix) {
859
- puts(".git");
941
+ print_path(".git", prefix, format, DEFAULT_UNMODIFIED);
942
continue;
943
}
944
} else { /* --absolute-git-dir */
945
+ wanted = FORMAT_CANONICAL;
946
if (!gitdir && !prefix)
947
gitdir = ".git";
948
if (gitdir) {
955
}
956
cwd = xgetcwd();
957
len = strlen(cwd);
875
- printf("%s%s.git\n", cwd, len && cwd[len-1] != '/' ? "/" : "");
958
+ strbuf_reset(&buf);
959
+ strbuf_addf(&buf, "%s%s.git", cwd, len && cwd[len-1] != '/' ? "/" : "");
960
free(cwd);
961
+ print_path(buf.buf, prefix, wanted, DEFAULT_CANONICAL);
962
continue;
963
}
964
if (!strcmp(arg, "--git-common-dir")) {
880
- strbuf_reset(&buf);
881
- puts(relative_path(get_git_common_dir(),
882
- prefix, &buf));
965
+ print_path(get_git_common_dir(), prefix, format, DEFAULT_RELATIVE_IF_SHARED);
966
continue;
967
}
968
if (!strcmp(arg, "--is-inside-git-dir")) {
992
if (the_index.split_index) {
993
const struct object_id *oid = &the_index.split_index->base_oid;
994
const char *path = git_path("sharedindex.%s", oid_to_hex(oid));
912
- strbuf_reset(&buf);
913
- puts(relative_path(path, prefix, &buf));
995
+ print_path(path, prefix, format, DEFAULT_RELATIVE);
996
}
997
continue;
998
}