diff --git a/Documentation/Makefile b/Documentation/Makefile index c2baad0bd8..2aae4c9cbb 100644 --- a/Documentation/Makefile +++ b/Documentation/Makefile @@ -2,6 +2,8 @@ MAN1_TXT = MAN5_TXT = MAN7_TXT = +HOWTO_TXT = +DOC_DEP_TXT = TECH_DOCS = ARTICLES = SP_ARTICLES = @@ -42,6 +44,11 @@ MAN7_TXT += gittutorial-2.txt MAN7_TXT += gittutorial.txt MAN7_TXT += gitworkflows.txt +HOWTO_TXT += $(wildcard howto/*.txt) + +DOC_DEP_TXT += $(wildcard *.txt) +DOC_DEP_TXT += $(wildcard config/*.txt) + ifdef MAN_FILTER MAN_TXT = $(filter $(MAN_FILTER),$(MAN1_TXT) $(MAN5_TXT) $(MAN7_TXT)) else @@ -286,7 +293,7 @@ docdep_prereqs = \ mergetools-list.made $(mergetools_txt) \ cmd-list.made $(cmds_txt) -doc.dep : $(docdep_prereqs) $(wildcard *.txt) $(wildcard config/*.txt) build-docdep.perl +doc.dep : $(docdep_prereqs) $(DOC_DEP_TXT) build-docdep.perl $(QUIET_GEN)$(RM) $@+ $@ && \ $(PERL_PATH) ./build-docdep.perl >$@+ $(QUIET_STDERR) && \ mv $@+ $@ @@ -429,9 +436,9 @@ $(patsubst %.txt,%.texi,$(MAN_TXT)): %.texi : %.xml $(DOCBOOK2X_TEXI) --to-stdout $*.xml >$@+ && \ mv $@+ $@ -howto-index.txt: howto-index.sh $(wildcard howto/*.txt) +howto-index.txt: howto-index.sh $(HOWTO_TXT) $(QUIET_GEN)$(RM) $@+ $@ && \ - '$(SHELL_PATH_SQ)' ./howto-index.sh $(sort $(wildcard howto/*.txt)) >$@+ && \ + '$(SHELL_PATH_SQ)' ./howto-index.sh $(sort $(HOWTO_TXT)) >$@+ && \ mv $@+ $@ $(patsubst %,%.html,$(ARTICLES)) : %.html : %.txt @@ -440,7 +447,7 @@ $(patsubst %,%.html,$(ARTICLES)) : %.html : %.txt WEBDOC_DEST = /pub/software/scm/git/docs howto/%.html: ASCIIDOC_EXTRA += -a git-relative-html-prefix=../ -$(patsubst %.txt,%.html,$(wildcard howto/*.txt)): %.html : %.txt GIT-ASCIIDOCFLAGS +$(patsubst %.txt,%.html,$(HOWTO_TXT)): %.html : %.txt GIT-ASCIIDOCFLAGS $(QUIET_ASCIIDOC)$(RM) $@+ $@ && \ sed -e '1,/^$$/d' $< | \ $(TXT_TO_HTML) - >$@+ && \ @@ -472,7 +479,13 @@ print-man1: @for i in $(MAN1_TXT); do echo $$i; done lint-docs:: - $(QUIET_LINT)$(PERL_PATH) lint-gitlink.perl + $(QUIET_LINT)$(PERL_PATH) lint-gitlink.perl \ + $(HOWTO_TXT) $(DOC_DEP_TXT) \ + --section=1 $(MAN1_TXT) \ + --section=5 $(MAN5_TXT) \ + --section=7 $(MAN7_TXT); \ + $(PERL_PATH) lint-man-end-blurb.perl $(MAN_TXT); \ + $(PERL_PATH) lint-man-section-order.perl $(MAN_TXT); ifeq ($(wildcard po/Makefile),po/Makefile) doc-l10n install-l10n:: diff --git a/Documentation/git-credential.txt b/Documentation/git-credential.txt index 31c81c4c02..206e3c5f40 100644 --- a/Documentation/git-credential.txt +++ b/Documentation/git-credential.txt @@ -159,3 +159,7 @@ empty string. + Components which are missing from the URL (e.g., there is no username in the example above) will be left unset. + +GIT +--- +Part of the linkgit:git[1] suite diff --git a/Documentation/git-cvsserver.txt b/Documentation/git-cvsserver.txt index 1b1c71ad9d..f2e4a47ebe 100644 --- a/Documentation/git-cvsserver.txt +++ b/Documentation/git-cvsserver.txt @@ -24,6 +24,18 @@ Usage: [verse] 'git-cvsserver' [] [pserver|server] [ ...] +DESCRIPTION +----------- + +This application is a CVS emulation layer for Git. + +It is highly functional. However, not all methods are implemented, +and for those methods that are implemented, +not all switches are implemented. + +Testing has been done using both the CLI CVS client, and the Eclipse CVS +plugin. Most functionality works fine with both of these clients. + OPTIONS ------- @@ -57,18 +69,6 @@ access still needs to be enabled by the `gitcvs.enabled` config option unless `--export-all` was given, too. -DESCRIPTION ------------ - -This application is a CVS emulation layer for Git. - -It is highly functional. However, not all methods are implemented, -and for those methods that are implemented, -not all switches are implemented. - -Testing has been done using both the CLI CVS client, and the Eclipse CVS -plugin. Most functionality works fine with both of these clients. - LIMITATIONS ----------- diff --git a/Documentation/git-grep.txt b/Documentation/git-grep.txt index 4e0ba8234a..3d393fbac1 100644 --- a/Documentation/git-grep.txt +++ b/Documentation/git-grep.txt @@ -38,38 +38,6 @@ are lists of one or more search expressions separated by newline characters. An empty string as search expression matches all lines. -CONFIGURATION -------------- - -grep.lineNumber:: - If set to true, enable `-n` option by default. - -grep.column:: - If set to true, enable the `--column` option by default. - -grep.patternType:: - Set the default matching behavior. Using a value of 'basic', 'extended', - 'fixed', or 'perl' will enable the `--basic-regexp`, `--extended-regexp`, - `--fixed-strings`, or `--perl-regexp` option accordingly, while the - value 'default' will return to the default matching behavior. - -grep.extendedRegexp:: - If set to true, enable `--extended-regexp` option by default. This - option is ignored when the `grep.patternType` option is set to a value - other than 'default'. - -grep.threads:: - Number of grep worker threads to use. If unset (or set to 0), Git will - use as many threads as the number of logical cores available. - -grep.fullName:: - If set to true, enable `--full-name` option by default. - -grep.fallbackToNoIndex:: - If set to true, fall back to git grep --no-index if git grep - is executed outside of a git repository. Defaults to false. - - OPTIONS ------- --cached:: @@ -363,6 +331,38 @@ with multiple threads might perform slower than single threaded if `--textconv` is given and there're too many text conversions. So if you experience low performance in this case, it might be desirable to use `--threads=1`. +CONFIGURATION +------------- + +grep.lineNumber:: + If set to true, enable `-n` option by default. + +grep.column:: + If set to true, enable the `--column` option by default. + +grep.patternType:: + Set the default matching behavior. Using a value of 'basic', 'extended', + 'fixed', or 'perl' will enable the `--basic-regexp`, `--extended-regexp`, + `--fixed-strings`, or `--perl-regexp` option accordingly, while the + value 'default' will return to the default matching behavior. + +grep.extendedRegexp:: + If set to true, enable `--extended-regexp` option by default. This + option is ignored when the `grep.patternType` option is set to a value + other than 'default'. + +grep.threads:: + Number of grep worker threads to use. If unset (or set to 0), Git will + use as many threads as the number of logical cores available. + +grep.fullName:: + If set to true, enable `--full-name` option by default. + +grep.fallbackToNoIndex:: + If set to true, fall back to git grep --no-index if git grep + is executed outside of a git repository. Defaults to false. + + GIT --- Part of the linkgit:git[1] suite diff --git a/Documentation/git-mktag.txt b/Documentation/git-mktag.txt index 17a2603a60..466a697519 100644 --- a/Documentation/git-mktag.txt +++ b/Documentation/git-mktag.txt @@ -11,14 +11,6 @@ SYNOPSIS [verse] 'git mktag' -OPTIONS -------- - ---strict:: - By default mktag turns on the equivalent of - linkgit:git-fsck[1] `--strict` mode. Use `--no-strict` to - disable it. - DESCRIPTION ----------- @@ -45,6 +37,14 @@ the appropriate `fsck.` varible: git -c fsck.extraHeaderEntry=ignore mktag :: @@ -1266,6 +1260,12 @@ merge tlsv1.3 merge cmake ------------ +CONFIGURATION +------------- + +include::config/rebase.txt[] +include::config/sequencer.txt[] + BUGS ---- The todo list presented by the deprecated `--preserve-merges --interactive` diff --git a/Documentation/git-svn.txt b/Documentation/git-svn.txt index 67b143cc81..d5776ffcfd 100644 --- a/Documentation/git-svn.txt +++ b/Documentation/git-svn.txt @@ -1061,25 +1061,6 @@ with different name spaces. For example: branches = stable/*:refs/remotes/svn/stable/* branches = debug/*:refs/remotes/svn/debug/* -BUGS ----- - -We ignore all SVN properties except svn:executable. Any unhandled -properties are logged to $GIT_DIR/svn//unhandled.log - -Renamed and copied directories are not detected by Git and hence not -tracked when committing to SVN. I do not plan on adding support for -this as it's quite difficult and time-consuming to get working for all -the possible corner cases (Git doesn't do it, either). Committing -renamed and copied files is fully supported if they're similar enough -for Git to detect them. - -In SVN, it is possible (though discouraged) to commit changes to a tag -(because a tag is just a directory copy, thus technically the same as a -branch). When cloning an SVN repository, 'git svn' cannot know if such a -commit to a tag will happen in the future. Thus it acts conservatively -and imports all SVN tags as branches, prefixing the tag name with 'tags/'. - CONFIGURATION ------------- @@ -1166,6 +1147,25 @@ $GIT_DIR/svn/\**/.rev_map.*:: if it is missing or not up to date. 'git svn reset' automatically rewinds it. +BUGS +---- + +We ignore all SVN properties except svn:executable. Any unhandled +properties are logged to $GIT_DIR/svn//unhandled.log + +Renamed and copied directories are not detected by Git and hence not +tracked when committing to SVN. I do not plan on adding support for +this as it's quite difficult and time-consuming to get working for all +the possible corner cases (Git doesn't do it, either). Committing +renamed and copied files is fully supported if they're similar enough +for Git to detect them. + +In SVN, it is possible (though discouraged) to commit changes to a tag +(because a tag is just a directory copy, thus technically the same as a +branch). When cloning an SVN repository, 'git svn' cannot know if such a +commit to a tag will happen in the future. Thus it acts conservatively +and imports all SVN tags as branches, prefixing the tag name with 'tags/'. + SEE ALSO -------- linkgit:git-rebase[1] diff --git a/Documentation/gitnamespaces.txt b/Documentation/gitnamespaces.txt index b614969ad2..1c8d2ecc35 100644 --- a/Documentation/gitnamespaces.txt +++ b/Documentation/gitnamespaces.txt @@ -62,3 +62,7 @@ git clone ext::'git --namespace=foo %s /tmp/prefixed.git' ---------- include::transfer-data-leaks.txt[] + +GIT +--- +Part of the linkgit:git[1] suite diff --git a/Documentation/lint-gitlink.perl b/Documentation/lint-gitlink.perl index 476cc30b83..b22a367844 100755 --- a/Documentation/lint-gitlink.perl +++ b/Documentation/lint-gitlink.perl @@ -1,71 +1,67 @@ #!/usr/bin/perl -use File::Find; -use Getopt::Long; +use strict; +use warnings; -my $basedir = "."; -GetOptions("basedir=s" => \$basedir) - or die("Cannot parse command line arguments\n"); +# Parse arguments, a simple state machine for input like: +# +# howto/*.txt config/*.txt --section=1 git.txt git-add.txt [...] --to-lint git-add.txt a-file.txt [...] +my %TXT; +my %SECTION; +my $section; +my $lint_these = 0; +for my $arg (@ARGV) { + if (my ($sec) = $arg =~ /^--section=(\d+)$/s) { + $section = $sec; + next; + } -my $found_errors = 0; + my ($name) = $arg =~ /^(.*?)\.txt$/s; + unless (defined $section) { + $TXT{$name} = $arg; + next; + } + $SECTION{$name} = $section; +} + +my $exit_code = 0; sub report { - my ($where, $what, $error) = @_; - print "$where: $error: $what\n"; - $found_errors = 1; + my ($pos, $line, $target, $msg) = @_; + substr($line, $pos) = "' <-- HERE"; + $line =~ s/^\s+//; + print "$ARGV:$.: error: $target: $msg, shown with 'HERE' below:\n"; + print "$ARGV:$.:\t'$line\n"; + $exit_code = 1; } -sub grab_section { - my ($page) = @_; - open my $fh, "<", "$basedir/$page.txt"; - my $firstline = <$fh>; - chomp $firstline; - close $fh; - my ($section) = ($firstline =~ /.*\((\d)\)$/); - return $section; -} +@ARGV = sort values %TXT; +die "BUG: Nothing to process!" unless @ARGV; +while (<>) { + my $line = $_; + while ($line =~ m/linkgit:((.*?)\[(\d)\])/g) { + my $pos = pos $line; + my ($target, $page, $section) = ($1, $2, $3); -sub lint { - my ($file) = @_; - open my $fh, "<", $file - or return; - while (<$fh>) { - my $where = "$file:$."; - while (s/linkgit:((.*?)\[(\d)\])//) { - my ($target, $page, $section) = ($1, $2, $3); + # De-AsciiDoc + $page =~ s/{litdd}/--/g; - # De-AsciiDoc - $page =~ s/{litdd}/--/g; - - if ($page !~ /^git/) { - report($where, $target, "nongit link"); - next; - } - if (! -f "$basedir/$page.txt") { - report($where, $target, "no such source"); - next; - } - $real_section = grab_section($page); - if ($real_section != $section) { - report($where, $target, - "wrong section (should be $real_section)"); - next; - } + if (!exists $TXT{$page}) { + report($pos, $line, $target, "link outside of our own docs"); + next; + } + if (!exists $SECTION{$page}) { + report($pos, $line, $target, "link outside of our sectioned docs"); + next; + } + my $real_section = $SECTION{$page}; + if ($section != $SECTION{$page}) { + report($pos, $line, $target, "wrong section (should be $real_section)"); + next; } } - close $fh; + # this resets our $. for each file + close ARGV if eof; } -sub lint_it { - lint($File::Find::name) if -f && /\.txt$/; -} - -if (!@ARGV) { - find({ wanted => \&lint_it, no_chdir => 1 }, $basedir); -} else { - for (@ARGV) { - lint($_); - } -} - -exit $found_errors; +exit $exit_code; diff --git a/Documentation/lint-man-end-blurb.perl b/Documentation/lint-man-end-blurb.perl new file mode 100755 index 0000000000..d69312e5db --- /dev/null +++ b/Documentation/lint-man-end-blurb.perl @@ -0,0 +1,24 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +my $exit_code = 0; +sub report { + my ($target, $msg) = @_; + print "error: $target: $msg\n"; + $exit_code = 1; +} + +local $/; +while (my $slurp = <>) { + report($ARGV, "has no 'Part of the linkgit:git[1] suite' end blurb") + unless $slurp =~ m[ + ^GIT\n + ---\n + \QPart of the linkgit:git[1] suite\E \n + \z + ]mx; +} + +exit $exit_code; diff --git a/Documentation/lint-man-section-order.perl b/Documentation/lint-man-section-order.perl new file mode 100755 index 0000000000..b05f9156dd --- /dev/null +++ b/Documentation/lint-man-section-order.perl @@ -0,0 +1,105 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +my %SECTIONS; +{ + my $order = 0; + %SECTIONS = ( + 'NAME' => { + required => 1, + order => $order++, + }, + 'SYNOPSIS' => { + required => 1, + order => $order++, + }, + 'DESCRIPTION' => { + required => 1, + order => $order++, + }, + 'OPTIONS' => { + order => $order++, + required => 0, + }, + 'CONFIGURATION' => { + order => $order++, + }, + 'BUGS' => { + order => $order++, + }, + 'SEE ALSO' => { + order => $order++, + }, + 'GIT' => { + required => 1, + order => $order++, + }, + ); +} +my $SECTION_RX = do { + my ($names) = join "|", keys %SECTIONS; + qr/^($names)$/s; +}; + +my $exit_code = 0; +sub report { + my ($msg) = @_; + print "$ARGV:$.: $msg\n"; + $exit_code = 1; +} + +my $last_was_section; +my @actual_order; +while (my $line = <>) { + chomp $line; + if ($line =~ $SECTION_RX) { + push @actual_order => $line; + $last_was_section = 1; + # Have no "last" section yet, processing NAME + next if @actual_order == 1; + + my @expected_order = sort { + $SECTIONS{$a}->{order} <=> $SECTIONS{$b}->{order} + } @actual_order; + + my $expected_last = $expected_order[-2]; + my $actual_last = $actual_order[-2]; + if ($actual_last ne $expected_last) { + report("section '$line' incorrectly ordered, comes after '$actual_last'"); + } + next; + } + if ($last_was_section) { + my $last_section = $actual_order[-1]; + if (length $last_section ne length $line) { + report("dashes under '$last_section' should match its length!"); + } + if ($line !~ /^-+$/) { + report("dashes under '$last_section' should be '-' dashes!"); + } + $last_was_section = 0; + } + + if (eof) { + # We have both a hash and an array to consider, for + # convenience + my %actual_sections; + @actual_sections{@actual_order} = (); + + for my $section (sort keys %SECTIONS) { + next if !$SECTIONS{$section}->{required} or exists $actual_sections{$section}; + report("has no required '$section' section!"); + } + + # Reset per-file state + { + @actual_order = (); + # this resets our $. for each file + close ARGV; + } + } +} + +exit $exit_code;