* Re: Migration of git-scm.com to a static web site: ready for review/testing
2024-09-11 22:18 ` Johannes Schindelin
@ 2024-09-11 22:20 ` Johannes Schindelin
2024-09-12 7:53 ` Toon Claes
1 sibling, 0 replies; 15+ messages in thread
From: Johannes Schindelin @ 2024-09-11 22:20 UTC (permalink / raw)
To: git
Cc: Matt Burke, Victoria Dye, Matthias Aßhauer, Kaartic Sivaraam,
Todd Zullinger, Johannes Sixt
[-- Attachment #1: Type: text/plain, Size: 135307 bytes --]
Once again, me,
On Thu, 12 Sep 2024, Johannes Schindelin wrote:
> I will try to reply to this mail with a range-diff that is slightly edited
> to leave out the changes made by GitHub workflows (i.e. book and manual
> pages).
Here goes:
1: 3420701f6 < -: --------- Remove a bogus end tag
2: 861766083 < -: --------- docs: fix a bogus <a/>
3: 5af3129c1 < -: --------- Remove obsolete banner
4: 82173f4f1 < -: --------- Revert "book2.rake: drop progit2-ms translation"
5: 32795076e = 1: 987e733c3 Drop the Travis CI configuration
6: 0c6f2b28b = 2: 247a0615a Add a Hugo-aware .gitignore file
7: 5c522f814 ! 3: 593aa9af8 Adjust the Gemfile in preparation for generating a static site
@@ Gemfile
source "https://rubygems.org"
-ruby "3.1.3"
-
--gem "rails", "~> 6.0"
+-
+-gem "rails", "~> 6.1"
-
-# hacks for rails6 + ruby 3.1
-gem 'net-imap', require: false
@@ Gemfile
-gem 'net-smtp', require: false
-
-gem "asciidoctor", "~> 2.0.0"
--gem "elasticsearch", "2.0.2"
+-gem "elasticsearch", "7.13"
-gem "iso8601"
-gem "octokit"
-gem "puma"
8: 46233d1bb ! 4: 5cddbb9a3 Add a Hugo configuration
@@ Commit message
## hugo.yml (new) ##
@@
+---
-+baseURL: https://git-scm.com/
+languageCode: en
+title: Git
+disablePathToLower: true
@@ hugo.yml (new)
+ renderer:
+ unsafe: true
+params:
-+ latest_version: 2.43.0
-+ latest_relnote_url: https://raw.github.com/git/git/master/Documentation/RelNotes/2.43.0.txt
-+ latest_release_date: '2023-11-20'
++ latest_version: 2.46.0
++ latest_relnote_url: https://raw.github.com/git/git/master/Documentation/RelNotes/2.46.0.txt
++ latest_release_date: '2024-07-29'
9: ed4e92165 ! 5: 8de703d8c Drop the Ruby app
@@ Gemfile.lock (deleted)
-GEM
- remote: https://rubygems.org/
- specs:
-- actioncable (6.1.7.3)
-- actionpack (= 6.1.7.3)
-- activesupport (= 6.1.7.3)
+- actioncable (6.1.7.7)
+- actionpack (= 6.1.7.7)
+- activesupport (= 6.1.7.7)
- nio4r (~> 2.0)
- websocket-driver (>= 0.6.1)
-- actionmailbox (6.1.7.3)
-- actionpack (= 6.1.7.3)
-- activejob (= 6.1.7.3)
-- activerecord (= 6.1.7.3)
-- activestorage (= 6.1.7.3)
-- activesupport (= 6.1.7.3)
+- actionmailbox (6.1.7.7)
+- actionpack (= 6.1.7.7)
+- activejob (= 6.1.7.7)
+- activerecord (= 6.1.7.7)
+- activestorage (= 6.1.7.7)
+- activesupport (= 6.1.7.7)
- mail (>= 2.7.1)
-- actionmailer (6.1.7.3)
-- actionpack (= 6.1.7.3)
-- actionview (= 6.1.7.3)
-- activejob (= 6.1.7.3)
-- activesupport (= 6.1.7.3)
+- actionmailer (6.1.7.7)
+- actionpack (= 6.1.7.7)
+- actionview (= 6.1.7.7)
+- activejob (= 6.1.7.7)
+- activesupport (= 6.1.7.7)
- mail (~> 2.5, >= 2.5.4)
- rails-dom-testing (~> 2.0)
-- actionpack (6.1.7.3)
-- actionview (= 6.1.7.3)
-- activesupport (= 6.1.7.3)
+- actionpack (6.1.7.7)
+- actionview (= 6.1.7.7)
+- activesupport (= 6.1.7.7)
- rack (~> 2.0, >= 2.0.9)
- rack-test (>= 0.6.3)
- rails-dom-testing (~> 2.0)
- rails-html-sanitizer (~> 1.0, >= 1.2.0)
-- actiontext (6.1.7.3)
-- actionpack (= 6.1.7.3)
-- activerecord (= 6.1.7.3)
-- activestorage (= 6.1.7.3)
-- activesupport (= 6.1.7.3)
+- actiontext (6.1.7.7)
+- actionpack (= 6.1.7.7)
+- activerecord (= 6.1.7.7)
+- activestorage (= 6.1.7.7)
+- activesupport (= 6.1.7.7)
- nokogiri (>= 1.8.5)
-- actionview (6.1.7.3)
-- activesupport (= 6.1.7.3)
+- actionview (6.1.7.7)
+- activesupport (= 6.1.7.7)
- builder (~> 3.1)
- erubi (~> 1.4)
- rails-dom-testing (~> 2.0)
- rails-html-sanitizer (~> 1.1, >= 1.2.0)
-- activejob (6.1.7.3)
-- activesupport (= 6.1.7.3)
+- activejob (6.1.7.7)
+- activesupport (= 6.1.7.7)
- globalid (>= 0.3.6)
-- activemodel (6.1.7.3)
-- activesupport (= 6.1.7.3)
-- activerecord (6.1.7.3)
-- activemodel (= 6.1.7.3)
-- activesupport (= 6.1.7.3)
-- activestorage (6.1.7.3)
-- actionpack (= 6.1.7.3)
-- activejob (= 6.1.7.3)
-- activerecord (= 6.1.7.3)
-- activesupport (= 6.1.7.3)
+- activemodel (6.1.7.7)
+- activesupport (= 6.1.7.7)
+- activerecord (6.1.7.7)
+- activemodel (= 6.1.7.7)
+- activesupport (= 6.1.7.7)
+- activestorage (6.1.7.7)
+- actionpack (= 6.1.7.7)
+- activejob (= 6.1.7.7)
+- activerecord (= 6.1.7.7)
+- activesupport (= 6.1.7.7)
- marcel (~> 1.0)
- mini_mime (>= 1.1.0)
-- activesupport (6.1.7.3)
+- activesupport (6.1.7.7)
- concurrent-ruby (~> 1.0, >= 1.0.2)
- i18n (>= 1.6, < 2)
- minitest (>= 5.1)
@@ Gemfile.lock (deleted)
- builder (3.2.4)
- byebug (11.1.3)
- coderay (1.1.3)
-- concurrent-ruby (1.2.2)
+- concurrent-ruby (1.2.3)
- crack (0.4.5)
- rexml
- crass (1.0.6)
@@ Gemfile.lock (deleted)
- dotenv-rails (2.7.6)
- dotenv (= 2.7.6)
- railties (>= 3.2)
-- elasticsearch (2.0.2)
-- elasticsearch-api (= 2.0.2)
-- elasticsearch-transport (= 2.0.2)
-- elasticsearch-api (2.0.2)
+- elasticsearch (7.13.0)
+- elasticsearch-api (= 7.13.0)
+- elasticsearch-transport (= 7.13.0)
+- elasticsearch-api (7.13.0)
- multi_json
-- elasticsearch-transport (2.0.2)
-- faraday
+- elasticsearch-transport (7.13.0)
+- faraday (~> 1)
- multi_json
- erubi (1.12.0)
- execjs (2.8.1)
@@ Gemfile.lock (deleted)
- factory_bot_rails (6.2.0)
- factory_bot (~> 6.2.0)
- railties (>= 5.0.0)
-- faraday (1.8.0)
+- faraday (1.10.3)
- faraday-em_http (~> 1.0)
- faraday-em_synchrony (~> 1.0)
- faraday-excon (~> 1.1)
-- faraday-httpclient (~> 1.0.1)
+- faraday-httpclient (~> 1.0)
+- faraday-multipart (~> 1.0)
- faraday-net_http (~> 1.0)
-- faraday-net_http_persistent (~> 1.1)
+- faraday-net_http_persistent (~> 1.0)
- faraday-patron (~> 1.0)
- faraday-rack (~> 1.0)
-- multipart-post (>= 1.2, < 3)
+- faraday-retry (~> 1.0)
- ruby2_keywords (>= 0.0.4)
- faraday-em_http (1.0.0)
- faraday-em_synchrony (1.0.0)
- faraday-excon (1.1.0)
- faraday-httpclient (1.0.1)
-- faraday-net_http (1.0.1)
+- faraday-multipart (1.0.4)
+- multipart-post (~> 2)
+- faraday-net_http (1.0.2)
- faraday-net_http_persistent (1.2.0)
- faraday-patron (1.0.0)
- faraday-rack (1.0.0)
+- faraday-retry (1.0.3)
- ffi (1.15.4)
- foreman (0.87.2)
-- globalid (1.1.0)
-- activesupport (>= 5.0)
+- globalid (1.2.1)
+- activesupport (>= 6.1)
- hashdiff (1.0.1)
-- i18n (1.12.0)
+- i18n (1.14.4)
- concurrent-ruby (~> 1.0)
- iso8601 (0.13.0)
- json (2.6.2)
- listen (3.7.0)
- rb-fsevent (~> 0.10, >= 0.10.3)
- rb-inotify (~> 0.9, >= 0.9.10)
-- loofah (2.19.1)
+- loofah (2.22.0)
- crass (~> 1.0.2)
-- nokogiri (>= 1.5.9)
+- nokogiri (>= 1.12.0)
- mail (2.8.1)
- mini_mime (>= 0.1.1)
- net-imap
- net-pop
- net-smtp
-- marcel (1.0.2)
+- marcel (1.0.4)
- method_source (1.0.0)
-- mini_mime (1.1.2)
-- mini_portile2 (2.8.1)
-- minitest (5.18.0)
+- mini_mime (1.1.5)
+- mini_portile2 (2.8.6)
+- minitest (5.22.3)
- multi_json (1.15.0)
-- multipart-post (2.1.1)
+- multipart-post (2.4.1)
- net-imap (0.3.1)
- net-protocol
- net-pop (0.1.2)
- net-protocol
-- net-protocol (0.1.3)
+- net-protocol (0.2.2)
- timeout
- net-smtp (0.3.2)
- net-protocol
-- nio4r (2.5.9)
-- nokogiri (1.14.3)
-- mini_portile2 (~> 2.8.0)
+- nio4r (2.7.3)
+- nokogiri (1.16.5)
+- mini_portile2 (~> 2.8.2)
- racc (~> 1.4)
- octokit (4.21.0)
- faraday (>= 0.9)
@@ Gemfile.lock (deleted)
- byebug (~> 11.0)
- pry (~> 0.13.0)
- public_suffix (4.0.6)
-- puma (5.6.7)
+- puma (5.6.8)
- nio4r (~> 2.0)
-- racc (1.6.2)
-- rack (2.2.6.4)
+- racc (1.7.3)
+- rack (2.2.8.1)
- rack-test (2.1.0)
- rack (>= 1.3)
- rack-timeout (0.6.0)
-- rails (6.1.7.3)
-- actioncable (= 6.1.7.3)
-- actionmailbox (= 6.1.7.3)
-- actionmailer (= 6.1.7.3)
-- actionpack (= 6.1.7.3)
-- actiontext (= 6.1.7.3)
-- actionview (= 6.1.7.3)
-- activejob (= 6.1.7.3)
-- activemodel (= 6.1.7.3)
-- activerecord (= 6.1.7.3)
-- activestorage (= 6.1.7.3)
-- activesupport (= 6.1.7.3)
+- rails (6.1.7.7)
+- actioncable (= 6.1.7.7)
+- actionmailbox (= 6.1.7.7)
+- actionmailer (= 6.1.7.7)
+- actionpack (= 6.1.7.7)
+- actiontext (= 6.1.7.7)
+- actionview (= 6.1.7.7)
+- activejob (= 6.1.7.7)
+- activemodel (= 6.1.7.7)
+- activerecord (= 6.1.7.7)
+- activestorage (= 6.1.7.7)
+- activesupport (= 6.1.7.7)
- bundler (>= 1.15.0)
-- railties (= 6.1.7.3)
+- railties (= 6.1.7.7)
- sprockets-rails (>= 2.0.0)
- rails-controller-testing (1.0.5)
- actionpack (>= 5.0.1.rc1)
- actionview (>= 5.0.1.rc1)
- activesupport (>= 5.0.1.rc1)
-- rails-dom-testing (2.0.3)
-- activesupport (>= 4.2.0)
+- rails-dom-testing (2.2.0)
+- activesupport (>= 5.0.0)
+- minitest
- nokogiri (>= 1.6)
-- rails-html-sanitizer (1.5.0)
-- loofah (~> 2.19, >= 2.19.1)
+- rails-html-sanitizer (1.6.0)
+- loofah (~> 2.21)
+- nokogiri (~> 1.14)
- rails_12factor (0.0.3)
- rails_serve_static_assets
- rails_stdout_logging
- rails_serve_static_assets (0.0.5)
- rails_stdout_logging (0.0.5)
-- railties (6.1.7.3)
-- actionpack (= 6.1.7.3)
-- activesupport (= 6.1.7.3)
+- railties (6.1.7.7)
+- actionpack (= 6.1.7.7)
+- activesupport (= 6.1.7.7)
- method_source
- rake (>= 12.2)
- thor (~> 1.0)
- rainbow (3.0.0)
-- rake (13.0.6)
+- rake (13.1.0)
- rb-fsevent (0.11.0)
- rb-inotify (0.10.1)
- ffi (~> 1.0)
@@ Gemfile.lock (deleted)
- redis-store (1.9.0)
- redis (>= 4, < 5)
- regexp_parser (2.1.1)
-- rexml (3.2.5)
+- rexml (3.2.8)
+- strscan (>= 3.0.9)
- rspec-core (3.10.1)
- rspec-support (~> 3.10.0)
- rspec-expectations (3.10.1)
@@ Gemfile.lock (deleted)
- shoulda-context (2.0.0)
- shoulda-matchers (4.5.1)
- activesupport (>= 4.2.0)
-- sprockets (4.2.0)
+- sprockets (4.2.1)
- concurrent-ruby (~> 1.0)
- rack (>= 2.2.4, < 4)
- sprockets-rails (3.4.2)
@@ Gemfile.lock (deleted)
- activesupport (>= 5.2)
- sprockets (>= 3.0.0)
- sqlite3 (1.4.2)
-- thor (1.2.1)
+- strscan (3.1.0)
+- thor (1.3.1)
- tilt (2.0.10)
-- timeout (0.3.0)
+- timeout (0.4.1)
- tzinfo (2.0.6)
- concurrent-ruby (~> 1.0)
- uglifier (4.2.0)
@@ Gemfile.lock (deleted)
- addressable (>= 2.8.0)
- crack (>= 0.3.2)
- hashdiff (>= 0.4.0, < 2.0.0)
-- websocket-driver (0.7.5)
+- websocket-driver (0.7.6)
- websocket-extensions (>= 0.1.0)
- websocket-extensions (0.1.5)
-- zeitwerk (2.6.7)
+- zeitwerk (2.6.13)
-
-PLATFORMS
- ruby
@@ Gemfile.lock (deleted)
- database_cleaner
- diffy
- dotenv-rails
-- elasticsearch (= 2.0.2)
+- elasticsearch (= 7.13)
- fabrication
- factory_bot_rails
- foreman
@@ Gemfile.lock (deleted)
- pry-byebug
- puma
- rack-timeout
-- rails (~> 6.0)
+- rails (~> 6.1)
- rails-controller-testing
- rails_12factor
- redis-rails
@@ Rakefile (deleted)
## app.json (deleted) ##
@@
-{
+- "stack": "heroku-24",
- "scripts": {
- },
- "env": {
@@ lib/searchable.rb (deleted)
- "query" => {
- "bool" => {
- "should" => [],
-- "minimum_number_should_match" => 1
+- "minimum_should_match" => 1
- },
- },
- "highlight" => {
10: 7865f2051 = 6: 24844c72e In preparation for using Hugo, move the "blog has moved" page
11: 4effd55ad = 7: 5830b2c27 Hugo-ify the "blog has moved" page
12: 6a09add78 = 8: 34580a126 Move the favicon to the `static/` directory
13: a79b9c844 = 9: 9f96eea1f Drop the robots.txt file
14: 32a4eb168 = 10: 47cbca3c8 Hugo'ify the 404 page
15: 906bb0235 = 11: 7a1f5bdac Drop the custom pages for HTML codes 422 and 500
16: bff32d315 ! 12: 340558bd1 ci: switch to building with Hugo
@@ .github/workflows/ci.yml
name: CI
-on: pull_request
+on: [pull_request]
-+
-+env:
-+ HUGO_VERSION: 0.120.3
jobs:
build:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v2
-+ - uses: actions/checkout@v3
++ - uses: actions/checkout@v4
- - name: ruby setup
- uses: ruby/setup-ruby@v1
- with:
- bundler-cache: true
++ - name: configure Hugo version
++ run: |
++ set -x &&
++ echo "HUGO_VERSION=$(sed -n 's/^ *hugo_version: *//p' <hugo.yml)" >>$GITHUB_ENV
++
+ - name: install Hugo ${{ env.HUGO_VERSION }}
+ run: |
+ set -x &&
@@ .github/workflows/ci.yml
- - name: rubocop
- run: bundle exec rubocop -P
-+ - name: run Pagefind to build the search index
-+ run: npx -y pagefind --site public
++ - name: build tar archive
++ run: cd public && tar czvf ../pages.tar.gz *
- - name: rspec
- run: bundle exec rspec
-+ - name: build tar archive
-+ run: cd public && tar czvf ../pages.tar.gz *
-+
+ - name: Upload build artifact
-+ uses: actions/upload-artifact@v3
++ uses: actions/upload-artifact@v4
+ with:
+ name: pages
+ path: pages.tar.gz
+
+ ## hugo.yml ##
+@@ hugo.yml: markup:
+ renderer:
+ unsafe: true
+ params:
++ hugo_version: 0.134.1
+ latest_version: 2.46.0
+ latest_relnote_url: https://raw.github.com/git/git/master/Documentation/RelNotes/2.46.0.txt
+ latest_release_date: '2024-07-29'
17: f685a732d ! 13: 2b1735089 README: reflect that this is now a Hugo site
@@ README.md
+## Local development setup
-You'll need a Ruby environment to run Rails. First do:
-+You'll need the extended version of [Hugo](https://gohugo.io/). On Windows, we recommend using the Windows Subsystem for Linux (WSL). You can serve the site locally via
++It is highly recommended to clone this repository using [`scalar`](https://git-scm.com/docs/scalar); This allows to work only on the parts of the repository relevant to your interests. You can select which directories are checked out using the [`git sparse-checkout add <directory>...`](https://git-scm.com/docs/git-sparse-checkout) command. The relevant directories are:
- $ rvm use .
- $ bundle install
-+ $ hugo serve -w
++- If you want to test any page rendering using Hugo:
++ - layouts/
++ - content/
++ - static/
++ - assets/
-Then you need to create the database structure:
-+The site should be running on http://127.0.0.1:1313. Note that it may be advisable to do this in a sparse checkout that excludes large parts of `content/`, to speed up the rendering time.
++- To add new GUIs:
++ - data/
- $ rake db:migrate
-+## Update manual pages
++- To work on pre-rendering pages that originate from other repositories (such as the ProGit book):
++ - script/
-Alternatively you can run the script at `script/bootstrap` which will set up Ruby dependencies and the local SQLite database.
--
++- To work on the GitHub workflows that perform the automated, scheduled pre-rendering:
++ - .github/
+
-Now you'll want to populate the man pages. You can do so from a local Git
-source clone like this:
++- The pre-rendered pages (ProGit book, its translated versions, the manual pages, their translated versions):
++ - external/book/
++ - external/docs/
++ You will want to avoid editing these directly, as they contain pages that are pre-rendered via GitHub workflows, sourcing content from other repositories.
++
++To render the site locally, you'll need the extended version of [Hugo](https://gohugo.io/). On Windows, we recommend using the Windows Subsystem for Linux (WSL). You can serve the site locally via
++
++ $ hugo serve -w
++
++The site should be running on http://127.0.0.1:1313. Note that it may be advisable to do this in a sparse checkout that excludes large parts of `content/`, to speed up the rendering time.
++
++## Update manual pages
++
+(TODO!)
+You can do so using a local Git source clone like this:
@@ README.md: Alternatively, you can get the book content from a repository on your
-
## Contributing
- If you wish to contribute to this website, please [fork it on GitHub](https://github.com/git/git-scm.com), push your
-@@ README.md: be accepted. If it involves code, please also write tests for it.
+-If you wish to contribute to this website, please [fork it on GitHub](https://github.com/git/git-scm.com), push your
+-change to a named branch, then send a pull request. If it is a big feature,
+-you might want to [start an issue](https://github.com/git/git-scm.com/issues/new) first to make sure it's something that will
+-be accepted. If it involves code, please also write tests for it.
+-
+-## Adding new GUI
++If you wish to contribute to this website, please [fork it on GitHub](https://github.com/git/git-scm.com).
- The [list of GUI clients](https://git-scm.com/downloads/guis) has been constructed by the community for a long time. If you want to add another tool you'll need to follow a few steps:
+-The [list of GUI clients](https://git-scm.com/downloads/guis) has been constructed by the community for a long time. If you want to add another tool you'll need to follow a few steps:
++Then, clone it using [`scalar`](https://git-scm.com/docs/scalar) (this avoids long clone times) and then use [`git sparse-checkout add <directory>`](https://git-scm.com/docs/git-sparse-checkout) to check out the files relevant to your work.
-1. Add the GUI client details at the YAML file: https://github.com/git/git-scm.com/blob/main/resources/guis.yml
- 1. The fields `name`, `url`, `price`, `license` should be very straightforward to fill.
@@ README.md: be accepted. If it involves code, please also write tests for it.
- 3. `platforms` is a list of at least 1 platform in which the tool is supported. The possibilities are: `Windows`, `Mac`, `Linux`, `Android`, and `iOS`
- 4. `order` can be filled with the biggest number already existing, plus 1 (Adding to the bottom - this will be covered in the following steps)
- 5. `trend_name` is an optional field that can be used for helping sorting the clients (also covered in the next steps)
--
++After making the changes, commit and push to a named branch in your fork, then open a pull request. If it is a big feature, you might want to [start an issue](https://github.com/git/git-scm.com/issues/new) first to make sure it's something that will be accepted.
+
-2. Add the image to `public/images/guis/<GUI_CLIENT_NAME>@2x.png` and `public/images/guis/<GUI_CLIENT_NAME>.png` making sure the aspect ratio matches a 588:332 image.
--
++## Adding a new GUI
+
-3. Sort the tools
- 1. From the root of the repository, run: `$ ./script/sort-gui`
- 2. A list of google trends url's will be displayed at the bottom if everything went well.
@@ README.md: be accepted. If it involves code, please also write tests for it.
- 7. The script makes some basic verifications. If there was some problem, it should be easily visible in the output
- 1. If you have more than 1 tool with the same name, a warning will appear: `======= WARNING: THERE ARE DUPLICATED GUIS =======`
- 2. If you are using the same `order` value for more than 1 tool, a warning will appear: `======= WARNING: THERE ARE DUPLICATED ORDERS (value: <VALUE>) =======`
--
++The [list of GUI clients](https://git-scm.com/downloads/guis) has been constructed by the community for a long time. If you want to add another tool you'll need to follow a few steps:
+
-## FAQ
--
--While setting the repo if you find any error, check if it's a known issue and the corresponding solution bellow.
-+1. Add a new `.md` file with the GUI client details: https://github.com/git/git-scm.com/tree/main/content/data/guis
++1. Add a new `.md` file with the GUI client details: data/guis
+ 1. The fields need to be enclosed within `---` lines
+ 2. The fields `name`, `project_url`, `price`, `license` should be very straightforward to fill.
+ 3. The field `image_tag` corresponds to the path of the image of the tool (should start with `images/guis/`).
+ 4. `platforms` is a list of at least 1 platform in which the tool is supported. The possibilities are: `Windows`, `Mac`, `Linux`, `Android`, and `iOS`
-+ 5. `order` can be filled with the biggest number already existing, plus 1 (Adding to the bottom - this will be covered in the following steps). This is the only field whose value should _not_ be enclosed in double-quote characters.
-+ 6. `trend_name` is an optional field that can be used for helping sorting the clients (also covered in the next steps)
++ 5. `order` can be filled with the biggest number already existing, plus 1 (this number determines the order in which the GUIs are rendered). This is the only field whose value should _not_ be enclosed in double-quote characters.
++ 6. `trend_name` is an optional field that can be used for helping sorting the clients.
--### An error occurred while installing pg (1.2.3), and Bundler cannot continue.
+-While setting the repo if you find any error, check if it's a known issue and the corresponding solution bellow.
+2. Add the image to `static/images/guis/<GUI_CLIENT_NAME>@2x.png` and `static/images/guis/<GUI_CLIENT_NAME>.png` making sure the aspect ratio matches a 588:332 image.
+-### An error occurred while installing pg (1.2.3), and Bundler cannot continue.
++## Useful links
+
-If you got this error when running `bundle install`, then you need to install postgresql on your OS. Check [this stackoverflow topic](https://stackoverflow.com/questions/52339221/rails-gem-error-while-installing-pg-1-1-3-and-bundler-cannot-continue) for more details.
-+## Useful link regarding working with Hugo
++### Hugo (static site generator)
+* https://gohugo.io/
+* https://gohugo.io/content-management/shortcodes/
18: ae9a0d82e = 14: e53e639b5 Move stylesheets to `assets/sass/`
19: faab827f4 ! 15: 11ab6559e Move the images to `static/images/`
@@ public/images/guis/git-glint@2x.png => static/images/guis/git-glint@2x.png
## public/images/guis/git-kraken.png => static/images/guis/git-kraken.png ##
- ## public/images/guis/git-kraken@2x.png => static/images/guis/git-kraken@2x.png ##
-
## public/images/guis/git2go.png => static/images/guis/git2go.png ##
## public/images/guis/git2go@2x.png => static/images/guis/git2go@2x.png ##
@@ public/images/guis/gitklient.png => static/images/guis/gitklient.png
## public/images/guis/gitklient@2x.png => static/images/guis/gitklient@2x.png ##
+ ## public/images/guis/gitkraken-2024@2x.png => static/images/guis/gitkraken-2024@2x.png ##
+
## public/images/guis/gitonic.png => static/images/guis/gitonic.png ##
## public/images/guis/gitonic@2x.png => static/images/guis/gitonic@2x.png ##
@@ public/images/guis/gitx.png => static/images/guis/gitx.png
## public/images/guis/gitx@2x.png => static/images/guis/gitx@2x.png ##
+ ## public/images/guis/gk-cli-keifs@2x.png => static/images/guis/gk-cli-keifs@2x.png ##
+
## public/images/guis/gmaster.png => static/images/guis/gmaster.png ##
## public/images/guis/gmaster@2x.png => static/images/guis/gmaster@2x.png ##
@@ public/images/guis/pragmagit.png => static/images/guis/pragmagit.png
## public/images/guis/pragmagit@2x.png => static/images/guis/pragmagit@2x.png ##
+ ## public/images/guis/relagit.png => static/images/guis/relagit.png ##
+
+ ## public/images/guis/relagit@2x.png => static/images/guis/relagit@2x.png ##
+
## public/images/guis/repoz.png => static/images/guis/repoz.png ##
## public/images/guis/repoz@2x.png => static/images/guis/repoz@2x.png ##
@@ public/images/guis/snailgit.png => static/images/guis/snailgit.png
## public/images/guis/snailgit@2x.png => static/images/guis/snailgit@2x.png ##
+ ## public/images/guis/sourcegit.png => static/images/guis/sourcegit.png ##
+
+ ## public/images/guis/sourcegit@2x.png => static/images/guis/sourcegit@2x.png ##
+
## public/images/guis/sourcetree.png => static/images/guis/sourcetree.png ##
## public/images/guis/sourcetree@2x.png => static/images/guis/sourcetree@2x.png ##
20: 34a9aafae = 16: b379241b1 Move Javascripts to the `static/` directory
21: 1e7d57b39 = 17: add38c971 Remove the layout for the error pages
22: 3775916fa = 18: 0929494dc Migrate the primary layout to the Hugo world
23: 03da9c6ea ! 19: 817c49726 Adjust the layouts
@@ layouts/_default/baseof.html
- <%= stylesheet_link_tag "application" %>
- <%= javascript_include_tag "modernize" %>
-+ {{ $style := resources.Get "sass/application.scss" | resources.ExecuteAsTemplate "application.scss" . | resources.ToCSS | resources.Minify }}
++ {{ $style := resources.Get "sass/application.scss" | resources.ExecuteAsTemplate "application.scss" . | css.Sass | resources.Minify }}
+ <link rel="stylesheet" href="{{ $style.RelPermalink }}">
+ <script src="/js/modernizr.js"></script>
+ <script src="/js/modernize.js"></script>
@@ layouts/_default/baseof.html
+ {{ partial "sidebar.html" . }}
<div id="content">
- <%= yield %>
-+ {{ .Content }}
++ {{ if (eq .Page.Path "/docs") }}
++ {{ partial "ref/index.html" . }}
++ {{ else }}
++ {{ .Content }}
++ {{ end }}
</div>
</div>
- <%= render partial: "shared/footer" %>
24: b721d0a20 = 20: f2546f28f Remove some includable bits that won't be needed in the future
25: 25b0a2330 = 21: e465a5ae6 Move some includable bits to `layouts/`
26: c9fd7e391 = 22: b4a98bee7 Make Javascript imports explicit
27: 3b33bf0de = 23: 68e705c49 Inline the taglines on the top
28: 79ffa61fc = 24: 3558e3570 Move the main index.html to the `content/` directory
29: 1991470d8 = 25: d23fd0543 Migrate the top-level page of the site to Hugo
30: e308db418 = 26: 4d5b58b58 CSS: quote URLs consistently
31: f55cae009 = 27: 37497edb9 Explicitly include 'normalize' in application CSS
32: 61a203caf = 28: 4ac41f786 Use the base URL in partial .scss files
33: c3730b407 ! 29: 6b2d46049 Add a script to update the latest Git version
@@ Commit message
## Gemfile ##
@@
+ # frozen_string_literal: true
source "https://rubygems.org"
-
++
+gem "octokit"
## script/update-git-version.rb (new) ##
34: 79e745184 = 30: 02abe2c42 update-git-version: skip -rc versions
35: 0e8a57fab = 31: 115ebbebf Allow redirecting from `list` pages
36: ac13d76df ! 32: 1118b8eaf Define and use sections in a flexible way
@@ layouts/_default/baseof.html
+{{ $section := "" }}
+{{ if isset .Params "section" }}
+{{ $section = .Params.section }}
-+{{ else if isset .Page "Section" }}
++{{ else if (eq .Page.Path "/docs") }}
++{{ $section = "documentation" }}
++{{ else if (isset .Page "Section") }}
+{{ $section = .Page.Section }}
-+{{ else if or (eq .Page.Type "doc") (eq .Page.Type "docs") (eq .Page.Type "video") }}
++{{ else if (or (eq .Page.Type "doc") (eq .Page.Type "docs") (eq .Page.Type "video")) }}
+{{ $section = "documentation" }}
-+{{ else if isset .Page "Type" }}
++{{ else if (isset .Page "Type") }}
+{{ $section = .Page.Type }}
+{{ else }}
-+{{ warnf "No section found in %s" (.File | jsonify) }}
++{{ warnf "No section found in %s" (.Page.Path | jsonify) }}
+{{ end }}
+{{ .Scratch.Set "section" $section }}
+
37: 894f2cef3 = 33: fffd7a142 Move the "About" pages to `content/about/`
38: 1f7ef75b7 ! 34: 3f3dd9823 Convert 'About' pages to Hugo
@@ content/about/trademark.html
## layouts/_default/baseof.html ##
@@
- <div id="content-wrapper">
- {{ partial "sidebar.html" . }}
<div id="content">
-- {{ .Content }}
-+ {{ if eq $section "about" }}
-+ <div id="main">
+ {{ if (eq .Page.Path "/docs") }}
+ {{ partial "ref/index.html" . }}
++ {{ else if eq $section "about" }}
++ <div id="main">
+ <h1>About</h1>
+
+ <ol id="about-nav">
@@ layouts/_default/baseof.html
+ </ol>
+ {{ .Content }}
+ </div>
-+ {{ else }}
-+ {{ .Content }}
-+ {{ end }}
- </div>
- </div>
- {{ partial "footer.html" . }}
+ {{ else }}
+ {{ .Content }}
+ {{ end }}
## layouts/partials/sidebar.html ##
@@
39: c139f5c1f = 35: e743fb5cc about/trademark: add back old redirect
40: ded625e52 = 36: b68954145 Install redirects for two `About` pages
41: 14843ae22 = 37: a5f2b8be5 Remove dynamic About navigation code
42: 20e420d65 = 38: 100808034 Migrate the community page from the web app to the static site
43: dd4f0b599 ! 39: 7a4f64d25 Adjust the community page
@@ content/community/_index.html
<div id="main">
<h1> Community</h1>
- <h2> Mailing List</h2>
-
- <p>
-- General questions or comments for the Git community can be sent to the mailing list by using the email address <a href="mailto:git@vger.kernel.org">git@vger.kernel.org</a>.
-+ General questions or comments for the Git community can be sent to the mailing list by using the email address <a href="mailto:git@vger.kernel.org">git@vger.kernel.org</a>.
- </p>
--
-+
- <p>
- <strong>If you wish to report any possible bug for Git, please use this mailing list as well.</strong>
- </p>
@@
<p>
The <a href="https://git.github.io/">Git Developer Pages</a> have a <a href="https://git.github.io/Hacking-Git/">Hacking Git page</a> which lists useful development resources. They also have <a href="https://git.github.io/General-Application-Information/">information</a> for people applying to work on Git as part of programs like <a href="https://www.outreachy.org/">Outreachy</a> or the <a href="https://summerofcode.withgoogle.com/">Google Summer of Code</a>.
44: 6625d81dd = 40: 6767a083e Adjust the GUI clients link in the sidebar
45: 293e57ba7 = 41: 4a2f13d4b Move the GUI Clients page into the location expected by Hugo
46: 45c7d59a6 ! 42: df1b23221 Adapt the GUI Clients page to Hugo
@@ Commit message
the JSON containing the list of GUI Clients into individual files inside
`data/`.
+ The files in `data/guis/` were written via:
+
+ git show HEAD:resources/guis.yml |
+ ruby -e '
+ # cannot use YAML.load because that would lose comments
+ $filename = nil
+ $content = ""
+ def write
+ return if $filename.nil?
+ File.open($filename, "w") { |f| f.write("---\n#{$content}---\n") } unless $filename.nil?
+ $filename = nil
+ $content = ""
+ end
+ ARGF.each do |line|
+ if line.start_with?("-") then
+ write
+ line[0] = " "
+ end
+ if line.start_with?(" ") then
+ $filename = "data/guis/#{line[8..].chomp.gsub(/ *\(.*\)$/, "").gsub(/ /, "-").downcase}.yml" if line.start_with?(" name: ")
+ $content += line[2..]
+ .gsub(/^image_tag: /, "\\0images/")
+ .gsub(/^url:/, "project_url:")
+ .gsub(/([-:] )([^"]*[^"0-9][^"]*)\n$/, "\\1\"\\2\"\n")
+ .gsub(/^-/, " -")
+ end
+ end
+ write
+ '
+
Signed-off-by: Victoria Dye <vdye@github.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
@@ data/guis/anchorpoint.yml (new)
## data/guis/aurees.yml (new) ##
@@
+---
-+name: "Aurees"
++name: "Aurees (no longer under active development)"
+project_url: "https://aurees.com/"
+image_tag: "images/guis/aurees@2x.png"
+platforms:
@@ data/guis/gitahead.yml (new)
+ - "Linux"
+price: "Free"
+license: "MIT"
-+order: 13
++order: 17
+---
## data/guis/gitatomic.yml (new) ##
@@ data/guis/gitbreeze.yml (new)
+ - "Linux"
+price: "Free"
+license: "Proprietary"
-+trend_name: "git breeze"
+order: 53
+---
@@ data/guis/gitdrive.yml (new)
+image_tag: "images/guis/gitdrive@2x.png"
+platforms:
+ - "iOS"
-+# No details what the $6.99 in-app purchase does, all it says is 'Unlimited Version'
++# No details what the $6.99 in-app purchase does, all it says is "Unlimited Version"
+price: "Free / $6.99"
+license: "Proprietary"
+order: 37
@@ data/guis/github-desktop.yml (new)
+order: 1
+---
- ## data/guis/gitkraken.yml (new) ##
+ ## data/guis/gitkraken-cli.yml (new) ##
@@
+---
-+name: "GitKraken"
-+project_url: "https://www.gitkraken.com/"
-+image_tag: "images/guis/git-kraken@2x.png"
++name: "GitKraken CLI"
++project_url: "https://www.gitkraken.com/cli"
++image_tag: "images/guis/gk-cli-keifs@2x.png"
++platforms:
++ - "Windows"
++ - "Mac"
++ - "Linux"
++price: "Free / $48.00+/user annually"
++license: "Proprietary"
++order: 55
++---
+
+ ## data/guis/gitkraken-desktop.yml (new) ##
+@@
++---
++name: "GitKraken Desktop"
++project_url: "https://www.gitkraken.com/git-client"
++image_tag: "images/guis/gitkraken-2024@2x.png"
+platforms:
+ - "Windows"
+ - "Mac"
+ - "Linux"
+# Free tier only works with local and public repositories
-+price: "Free / $59+/user annually"
++price: "Free / $48+/user annually"
+license: "Proprietary"
+order: 5
+---
@@ data/guis/gitnuro.yml (new)
@@
+---
+name: "Gitnuro"
-+project_url: "https://gitnuro.jetpackduba.com/"
++project_url: "https://gitnuro.com/"
+image_tag: "images/guis/Gitnuro@2x.png"
+platforms:
+ - "Windows"
@@ data/guis/gitui.yml (new)
@@
+---
+name: "GitUI"
-+project_url: "https://extrawurst.itch.io/gitui"
++project_url: "http://gitui.org"
+image_tag: "images/guis/gitui@2x.png"
+platforms:
+ - "Windows"
@@ data/guis/glint.yml (new)
+ - "Windows"
+ - "Mac"
+ - "Linux"
-+price: "Free (can only open up to two repositories at once)/ $35/user annually"
++# Free tier can only open up to two repositories at once
++price: "Free / $35/user annually"
+license: "Proprietary"
+trend_name: "git glint"
-+order: 52
++order: 13
+---
## data/guis/guitar.yml (new) ##
@@ data/guis/pragma-git.yml (new)
+license: "MIT"
+trend_name: "pragma github"
+order: 54
++---
+
+ ## data/guis/relagit.yml (new) ##
+@@
++---
++name: "RelaGit"
++project_url: "https://rela.dev"
++image_tag: "images/guis/relagit@2x.png"
++platforms:
++ - "Windows"
++ - "Mac"
++ - "Linux"
++price: "Free"
++license: "LGPL-3.0-or-later"
++order: 57
+---
## data/guis/repoz.yml (new) ##
@@ data/guis/snailgit.yml (new)
+price: "Free (limited) / $9.99"
+license: "Proprietary"
+order: 32
++---
+
+ ## data/guis/sourcegit.yml (new) ##
+@@
++---
++name: "SourceGit"
++project_url: "https://sourcegit-scm.github.io"
++image_tag: "images/guis/sourcegit@2x.png"
++platforms:
++ - "Windows"
++ - "Mac"
++ - "Linux"
++price: "Free"
++license: "MIT"
++trend_name: "SourceGit"
++order: 56
+---
## data/guis/sourcetree.yml (new) ##
@@ resources/guis.yml (deleted)
- price: Free
- license: GNU GPL
- order: 4
--- name: GitKraken
-- url: https://www.gitkraken.com/
-- image_tag: guis/git-kraken@2x.png
+-- name: GitKraken Desktop
+- url: https://www.gitkraken.com/git-client
+- image_tag: guis/gitkraken-2024@2x.png
- platforms:
- - Windows
- - Mac
- - Linux
- # Free tier only works with local and public repositories
-- price: Free / $59+/user annually
+- price: Free / $48+/user annually
- license: Proprietary
- order: 5
-- name: Magit
@@ resources/guis.yml (deleted)
- license: GNU GPL
- trend_name: Git giggle
- order: 27
--- name: Aurees
+-- name: Aurees (no longer under active development)
- url: https://aurees.com/
- image_tag: guis/aurees@2x.png
- platforms:
@@ resources/guis.yml (deleted)
- - Linux
- price: Free
- license: MIT
-- order: 13
+- order: 17
-- name: Gittyup
- url: https://murmele.github.io/Gittyup/
- image_tag: guis/gittyup@2x.png
@@ resources/guis.yml (deleted)
- license: Proprietary
- order: 42
-- name: GitUI
-- url: https://extrawurst.itch.io/gitui
+- url: http://gitui.org
- image_tag: guis/gitui@2x.png
- platforms:
- - Windows
@@ resources/guis.yml (deleted)
- trend_name: gitonic
- order: 50
-- name: Gitnuro
-- url: https://gitnuro.jetpackduba.com/
+- url: https://gitnuro.com/
- image_tag: guis/Gitnuro@2x.png
- platforms:
- - Windows
@@ resources/guis.yml (deleted)
- price: Free / $35/user annually
- license: Proprietary
- trend_name: git glint
-- order: 52
+- order: 13
-- name: GitBreeze
- url: https://gitbreeze.dev/
- image_tag: guis/gitbreeze@2x.png
@@ resources/guis.yml (deleted)
- license: MIT
- trend_name: pragma github
- order: 54
--
+-- name: GitKraken CLI
+- url: https://www.gitkraken.com/cli
+- image_tag: guis/gk-cli-keifs@2x.png
+- platforms:
+- - Windows
+- - Mac
+- - Linux
+- price: Free / $48.00+/user annually
+- license: Proprietary
+- order: 55
+-- name: SourceGit
+- url: https://sourcegit-scm.github.io
+- image_tag: guis/sourcegit@2x.png
+- platforms:
+- - Windows
+- - Mac
+- - Linux
+- price: Free
+- license: MIT
+- trend_name: SourceGit
+- order: 56
+-- name: RelaGit
+- url: https://rela.dev
+- image_tag: guis/relagit@2x.png
+- platforms:
+- - Windows
+- - Mac
+- - Linux
+- price: Free
+- license: LGPL-3.0-or-later
+- order: 57
47: 5b1e9a6de = 43: ad17fe7f0 downloads/guis: adjust the Javascript for filtering
48: 579cf46a3 = 44: e6208d5ed Move logos page to the new location
49: 99766e6fd = 45: ea70f19f1 Migrate logos page
50: 1a42a0157 = 46: bc0d9409a Create base Downloads page
51: 07c392bd8 = 47: 3d22dc37c Move the OS-specific Downloads pages into the location needed for Hugo
52: 6d315ee76 = 48: 17c567019 Implement the `site-param` shortcode
53: c2cbcaf82 = 49: 1812362c7 Hugo-ify Linux & Mac download pages
54: d55dfbd55 ! 50: 58a155e45 Add a script to store download data in `hugo.yml`
@@ README.md: Or you can do it from GitHub (much slower) like this:
## hugo.yml ##
@@ hugo.yml: params:
- latest_version: 2.43.0
- latest_relnote_url: https://raw.github.com/git/git/master/Documentation/RelNotes/2.43.0.txt
- latest_release_date: '2023-11-20'
+ latest_version: 2.46.0
+ latest_relnote_url: https://raw.github.com/git/git/master/Documentation/RelNotes/2.46.0.txt
+ latest_release_date: '2024-07-29'
+ macos_installer:
+ url: https://sourceforge.net/projects/git-osx-installer/files/git-2.33.0-intel-universal-mavericks.dmg/download?use_mirror=autoselect
+ version: 2.33.0
@@ hugo.yml: params:
+ filename: git-2.33.0-intel-universal-mavericks.dmg
+ windows_installer:
+ portable32:
-+ filename: PortableGit-2.43.0-32-bit.7z.exe
-+ release_date: '2023-11-20'
-+ version: 2.43.0
-+ url: https://github.com/git-for-windows/git/releases/download/v2.43.0.windows.1/PortableGit-2.43.0-32-bit.7z.exe
++ filename: PortableGit-2.45.2-32-bit.7z.exe
++ release_date: '2024-06-03'
++ version: 2.45.2
++ url: https://github.com/git-for-windows/git/releases/download/v2.45.2.windows.1/PortableGit-2.45.2-32-bit.7z.exe
+ portable64:
-+ filename: PortableGit-2.43.0-64-bit.7z.exe
-+ release_date: '2023-11-20'
-+ version: 2.43.0
-+ url: https://github.com/git-for-windows/git/releases/download/v2.43.0.windows.1/PortableGit-2.43.0-64-bit.7z.exe
++ filename: PortableGit-2.45.2-64-bit.7z.exe
++ release_date: '2024-06-03'
++ version: 2.45.2
++ url: https://github.com/git-for-windows/git/releases/download/v2.45.2.windows.1/PortableGit-2.45.2-64-bit.7z.exe
+ installer32:
-+ filename: Git-2.43.0-32-bit.exe
-+ release_date: '2023-11-20'
-+ version: 2.43.0
-+ url: https://github.com/git-for-windows/git/releases/download/v2.43.0.windows.1/Git-2.43.0-32-bit.exe
++ filename: Git-2.45.2-32-bit.exe
++ release_date: '2024-06-03'
++ version: 2.45.2
++ url: https://github.com/git-for-windows/git/releases/download/v2.45.2.windows.1/Git-2.45.2-32-bit.exe
+ installer64:
-+ filename: Git-2.43.0-64-bit.exe
-+ release_date: '2023-11-20'
-+ version: 2.43.0
-+ url: https://github.com/git-for-windows/git/releases/download/v2.43.0.windows.1/Git-2.43.0-64-bit.exe
++ filename: Git-2.45.2-64-bit.exe
++ release_date: '2024-06-03'
++ version: 2.45.2
++ url: https://github.com/git-for-windows/git/releases/download/v2.45.2.windows.1/Git-2.45.2-64-bit.exe
## app/services/download_service.rb => script/update-download-data.rb ##
@@
55: d58f20885 = 51: cce79c1a0 Downloads (MacOS): show relative date
56: 85d109ff6 = 52: c0340b223 Convert the Windows downloads page to Hugo
57: 5599b85a8 = 53: 5ae935edb download(win): white-space fix
58: 6d1b7c7f3 = 54: 0b69e8c0c Add 'Downloads' page aliases
59: 2f572e985 = 55: 8a9b19d16 Move the documentation landing page in place for Hugo
60: 1a96900f1 = 56: fc28e03d2 Migrate the 'Documentation' landing page to Hugo
61: 2f53db947 < -: --------- Move the "references" landing page to `content/`
-: --------- > 57: 49631dde3 Move the "references" landing page to `layouts/partials/`, in preparation for using it as a Hugo partial template.
62: dd874d4c7 = 58: 59972c75f Move the files defining the documentation categories
63: 60f601394 ! 59: 5ecc96a9a Adjust the "references" page to Hugo
@@ Commit message
Signed-off-by: Victoria Dye <vdye@github.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
- ## content/docs/_index.html ##
-@@
--<%- @section = 'documentation' %>
--<%- @subsection = 'reference' %>
--<%- @page_title = "Git - Reference" %>
-+---
-+section: "documentation"
-+subsection: "reference"
-+title: "Git - Reference"
-+url: /docs.html
-+aliases:
-+- /docs/index.html
-+---
-
- <div id='main'>
- <h1>Reference</h1>
- <div class='callout quickref'>
- <p>
- Quick reference guides:
-- <%= link_to "GitHub Cheat Sheet", "https://github.github.com/training-kit/" %>
-+ <a href="https://github.github.com/training-kit/">GitHub Cheat Sheet</a>
- |
-- <%= link_to "Visual Git Cheat Sheet", "https://ndpsoftware.com/git-cheatsheet.html" %>
-+ <a href="https://ndpsoftware.com/git-cheatsheet.html">Visual Git Cheat Sheet</a>
- </p>
- </div>
- <div class="callout all-commands">
-@@
- <div class='reference-menu'>
- <div class='two-column'>
- <div class='column-left'>
-- <%= render 'shared/ref/setup' %>
-- <%= render 'shared/ref/creating' %>
-- <%= render 'shared/ref/snapshot' %>
-- <%= render 'shared/ref/branching' %>
-- <%= render 'shared/ref/sharing' %>
-- <%= render 'shared/ref/inspection' %>
-- <%= render 'shared/ref/patching' %>
-- <%= render 'shared/ref/debugging' %>
-+ {{< category "setup" >}}
-+ {{< category "projects" >}}
-+ {{< category "snapshotting" >}}
-+ {{< category "branching" >}}
-+ {{< category "sharing" >}}
-+ {{< category "inspection" >}}
-+ {{< category "patching" >}}
-+ {{< category "debugging" >}}
- </div>
- <div class='column-right'>
-- <%= render 'shared/ref/guides' %>
-- <%= render 'shared/ref/email' %>
-- <%= render 'shared/ref/external' %>
-- <%= render 'shared/ref/admin' %>
-- <%= render 'shared/ref/server' %>
-- <%= render 'shared/ref/plumbing' %>
-+ {{< category "guides" >}}
-+ {{< category "email" >}}
-+ {{< category "external" >}}
-+ {{< category "admin" >}}
-+ {{< category "server-admin" >}}
-+ {{< category "plumbing" >}}
- </div>
- </div>
- </div>
-
## data/doc_categories/admin.yml ##
@@
-<h3 class='admin'>Administration</h3>
@@ data/doc_categories/setup.yml
- <li><%= man('git-config') %></li>
- <li><%= man('git-help') %></li>
- <li><%= man('git-bugreport') %></li>
-- <%= link_to "Credential helpers", "/doc/credential-helpers", sidebar_link_options("credential-helpers") %>
+- <li><%= link_to "Credential helpers", "/doc/credential-helpers", sidebar_link_options("credential-helpers") %></li>
-</ul>
+---
+category_id: "setup"
@@ layouts/partials/ref/category.html (new)
+<ul class='unstyled'>
+ {{ range $doc := $category.commands }}
+ <li>
-+ <a href="{{ print "docs/" $doc.doc (cond (and (ne .Params.lang nil) (ne $doc.no_append_lang true)) (print "/" .Params.lang) "") }}">
++ <a href="{{ print "/docs/" $doc.doc (cond (and (ne $.Page.Params.lang nil) (ne $doc.no_append_lang true) (isset (index $.Site.Data.docs.pages $doc.doc) "languages") (isset (index $.Site.Data.docs.pages $doc.doc "languages") $.Page.Params.lang)) (print "/" $.Page.Params.lang) "") }}">
+ {{ if (eq $doc.title nil) }}
+ {{ replace $doc.doc "git-" "" }}
+ {{ else }}
@@ layouts/partials/ref/category.html (new)
+ {{ end }}
+</ul>
- ## layouts/shortcodes/category.html (new) ##
+ ## layouts/partials/ref/index.html ##
@@
-+{{ .Scratch.Set "category_id" (.Get 0) }}
-+{{ partial "ref/category.html" . }}
+-<%- @section = 'documentation' %>
+-<%- @subsection = 'reference' %>
+-<%- @page_title = "Git - Reference" %>
+-
++{{ $context := . }}
+ <div id='main'>
+ <h1>Reference</h1>
+ <div class='callout quickref'>
+ <p>
+ Quick reference guides:
+- <%= link_to "GitHub Cheat Sheet", "https://github.github.com/training-kit/" %>
++ <a href="https://github.github.com/training-kit/">GitHub Cheat Sheet</a>
+ |
+- <%= link_to "Visual Git Cheat Sheet", "https://ndpsoftware.com/git-cheatsheet.html" %>
++ <a href="https://ndpsoftware.com/git-cheatsheet.html">Visual Git Cheat Sheet</a>
+ </p>
+ </div>
+ <div class="callout all-commands">
+@@
+ <div class='reference-menu'>
+ <div class='two-column'>
+ <div class='column-left'>
+- <%= render 'shared/ref/setup' %>
+- <%= render 'shared/ref/creating' %>
+- <%= render 'shared/ref/snapshot' %>
+- <%= render 'shared/ref/branching' %>
+- <%= render 'shared/ref/sharing' %>
+- <%= render 'shared/ref/inspection' %>
+- <%= render 'shared/ref/patching' %>
+- <%= render 'shared/ref/debugging' %>
++ {{ range slice "setup" "projects" "snapshotting" "branching" "sharing" "inspection" "patching" "debugging" }}
++ {{ $context.Scratch.Set "category_id" . }}
++ {{ partial "ref/category.html" $context }}
++ {{ end }}
+ </div>
+ <div class='column-right'>
+- <%= render 'shared/ref/guides' %>
+- <%= render 'shared/ref/email' %>
+- <%= render 'shared/ref/external' %>
+- <%= render 'shared/ref/admin' %>
+- <%= render 'shared/ref/server' %>
+- <%= render 'shared/ref/plumbing' %>
++ {{ range slice "guides" "email" "external" "admin" "server-admin" "plumbing" }}
++ {{ $context.Scratch.Set "category_id" . }}
++ {{ partial "ref/category.html" $context }}
++ {{ end }}
+ </div>
+ </div>
+ </div>
64: a3b5464d2 = 60: 10c090f35 Migrate 'Videos' page
65: ebbf2dc93 ! 61: 9bc68f7dd Migrate individual video pages
@@ app/views/doc/watch.html.erb (deleted)
## layouts/_default/baseof.html ##
@@
- <div id="content-wrapper">
- {{ partial "sidebar.html" . }}
<div id="content">
-- {{ if eq $section "about" }}
-+ {{ if isset .Params "video_title" }}
-+ <div id="main">
+ {{ if (eq .Page.Path "/docs") }}
+ {{ partial "ref/index.html" . }}
++ {{ else if isset .Params "video_title" }}
++ <div id="main">
+ <h1>{{ .Params.category }} Episode {{ .Params.episode }}</h1>
+ <h2>{{ .Params.video_title }}</h2>
+
@@ layouts/_default/baseof.html
+ <iframe src="https://player.vimeo.com/video/{{ .Params.ext_id }}?title=0&byline=0&portrait=0&color=f14e32" width="635" height="360" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>
+ </div>
+ </div>
-+ {{ else if eq $section "about" }}
- <div id="main">
+ {{ else if eq $section "about" }}
+ <div id="main">
<h1>About</h1>
-
66: d97d6afea ! 62: f0e2dad52 Migrate external links page to Hugo
@@ app/views/doc/_ext_tutorials.erb => layouts/shortcodes/external/tutorials.html
</p>
- </li>
+ </li>
- </ul>
- </div>
- <div class='column-right'>
+ <li>
+ <h4><a href="https://www.python4data.science/en/latest/productive/git/index.html">Git for Data Science</a></h4>
+ <p class='description'>
@@
<p class='description'>
Learn the basics of Git and Version Control through detailed and easy to follow steps.
67: 9549255ef = 63: b4755928a Migrate the 'About this site' page to Hugo
68: 4114ef8f4 = 64: 593d99e18 Migrate the Software Freedom Conservancy page
69: d05bb21d4 ! 65: 976c2b5c1 Hugo'ify the "credential helpers" page
@@ layouts/partials/ref/category.html
<ul class='unstyled'>
{{ range $doc := $category.commands }}
<li>
-- <a href="{{ print "docs/" $doc.doc (cond (and (ne .Params.lang nil) (ne $doc.no_append_lang true)) (print "/" .Params.lang) "") }}">
+- <a href="{{ print "/docs/" $doc.doc (cond (and (ne $.Page.Params.lang nil) (ne $doc.no_append_lang true) (isset (index $.Site.Data.docs.pages $doc.doc) "languages") (isset (index $.Site.Data.docs.pages $doc.doc "languages") $.Page.Params.lang)) (print "/" $.Page.Params.lang) "") }}">
+ {{ if (eq $doc.doc "credential-helpers") }}
+ <a href="doc/credential-helpers">
+ {{ else }}
-+ <a href="{{ print "docs/" $doc.doc (cond (and (ne .Params.lang nil) (ne $doc.no_append_lang true)) (print "/" .Params.lang) "") }}">
++ <a href="{{ print "/docs/" $doc.doc (cond (and (ne $.Page.Params.lang nil) (ne $doc.no_append_lang true) (isset (index $.Site.Data.docs.pages $doc.doc) "languages") (isset (index $.Site.Data.docs.pages $doc.doc "languages") $.Page.Params.lang)) (print "/" $.Page.Params.lang) "") }}">
+ {{ end }}
{{ if (eq $doc.title nil) }}
{{ replace $doc.doc "git-" "" }}
70: 00a42808e = 66: ccecdf517 Move the search results page
71: 5a183e236 ! 67: 00d2b544f Implement client-side search using Pagefind
@@ Commit message
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
+ ## .github/workflows/ci.yml ##
+@@ .github/workflows/ci.yml: jobs:
+ steps:
+ - uses: actions/checkout@v4
+
+- - name: configure Hugo version
++ - name: configure Hugo and Pagefind version
+ run: |
+ set -x &&
+ echo "HUGO_VERSION=$(sed -n 's/^ *hugo_version: *//p' <hugo.yml)" >>$GITHUB_ENV
++ echo "PAGEFIND_VERSION=$(sed -n 's/^ *pagefind_version: *//p' <hugo.yml)" >>$GITHUB_ENV
+
+ - name: install Hugo ${{ env.HUGO_VERSION }}
+ run: |
+@@ .github/workflows/ci.yml: jobs:
+ - name: run Hugo to build the pages
+ run: hugo
+
++ - name: run Pagefind ${{ env.PAGEFIND_VERSION }} to build the search index
++ run: npx -y pagefind@${{ env.PAGEFIND_VERSION }} --site public
++
+ - name: build tar archive
+ run: cd public && tar czvf ../pages.tar.gz *
+
+
## README.md ##
-@@ README.md: You'll need the extended version of [Hugo](https://gohugo.io/). On Windows, we r
+@@ README.md: To render the site locally, you'll need the extended version of [Hugo](https://g
The site should be running on http://127.0.0.1:1313. Note that it may be advisable to do this in a sparse checkout that excludes large parts of `content/`, to speed up the rendering time.
@@ README.md: You'll need the extended version of [Hugo](https://gohugo.io/). On Wi
(TODO!)
@@ README.md: The [list of GUI clients](https://git-scm.com/downloads/guis) has been construct
-
- 2. Add the image to `static/images/guis/<GUI_CLIENT_NAME>@2x.png` and `static/images/guis/<GUI_CLIENT_NAME>.png` making sure the aspect ratio matches a 588:332 image.
-
--## Useful link regarding working with Hugo
-+## Useful links regarding working with Hugo and Pagefind
-
* https://gohugo.io/
* https://gohugo.io/content-management/shortcodes/
-+* https://pagefind.app/
++### Pagefind (client-side search)
++
++* https://pagefind.app/
++
## License
+ The source code for the site is licensed under the MIT license, which you can find in
## assets/sass/search.scss ##
@@
@@ content/search/results.html
+ <ol class="full-search-results"></ol>
</div>
+ ## hugo.yml ##
+@@ hugo.yml: markup:
+ unsafe: true
+ params:
+ hugo_version: 0.134.1
++ pagefind_version: 1.1.1
+ latest_version: 2.46.0
+ latest_relnote_url: https://raw.github.com/git/git/master/Documentation/RelNotes/2.46.0.txt
+ latest_release_date: '2024-07-29'
+
## static/js/application.js ##
@@ static/js/application.js: var Search = {
selectedIndex: 0,
72: 1c55e8995 ! 68: fd440ba66 Implement "live search" using Pagefind
@@ static/js/application.js: var Search = {
- })
+ (async () => {
+ Search.pagefind = await import(`${baseURLPrefix}pagefind/pagefind.js`);
-+ Search.pagefind.init();
++ await Search.pagefind.init();
+ await callback();
+ })().catch(console.log);
},
73: 99046a762 = 69: 03d63b90d Mark pages with the correct language
74: 3d70c728b ! 70: a12108c7f Direct Pagefind what parts of the pages to index
@@ layouts/_default/baseof.html
{{ partial "sidebar.html" . }}
- <div id="content">
+ <div id="content" data-pagefind-body>
- {{ if isset .Params "video_title" }}
- <div id="main">
- <h1>{{ .Params.category }} Episode {{ .Params.episode }}</h1>
+ {{ if (eq .Page.Path "/docs") }}
+ {{ partial "ref/index.html" . }}
+ {{ else if isset .Params "video_title" }}
75: 1b6bb3c10 = 71: 23433ad6d Live search: only load 10 results at a time
76: cd28ebbe1 ! 72: a688de393 Respect the language in non-live search
@@ static/js/application.js: var Search = {
}
(async () => {
Search.pagefind = await import(`${baseURLPrefix}pagefind/pagefind.js`);
++ const options = {}
+ const language = this.getQueryValue('language');
-+ if (language) Search.pagefind.options({language});
- Search.pagefind.init();
++ if (language) options.language = language;
++ await Search.pagefind.options(options);
+ await Search.pagefind.init();
await callback();
})().catch(console.log);
77: 338a2e6c0 ! 73: 2a357df65 Use Pagefind's UI for the full search
@@ layouts/_default/baseof.html
<link href='/favicon.ico' rel='shortcut icon' type='image/x-icon'>
+ {{ if eq $section "search" }}<link href="{{ relURL "pagefind/pagefind-ui.css" }}" rel="stylesheet">{{ end }}
- {{ $style := resources.Get "sass/application.scss" | resources.ExecuteAsTemplate "application.scss" . | resources.ToCSS | resources.Minify }}
+ {{ $style := resources.Get "sass/application.scss" | resources.ExecuteAsTemplate "application.scss" . | css.Sass | resources.Minify }}
<link rel="stylesheet" href="{{ $style.RelPermalink }}">
<script src="/js/modernizr.js"></script>
@@ layouts/partials/header.html
+
+ {{ if ne (.Scratch.Get "section") "search" }}
<form id="search" action="/search/results">
- <input id="search-text" name="search" placeholder="Search entire site..." autocomplete="off" type="text" />
+ <input id="search-text" name="search" placeholder="Type / to search entire site…" autocomplete="off" type="text" />
</form>
<div id="search-results"></div>
+ {{ end }}
@@ static/js/application.js: var Search = {
- this.initializeSearchIndex(async () => {
- const results = await Search.pagefind.search(searchTerm);
- if (!results || !results.results || !results.results.length) return;
-+ new PagefindUI({ element: "#search-div", showSubResults: true, language });
-
+-
- const list = (await Promise.all(results.results.map(async e => {
- const result = await e.data();
- const href = result.url;
@@ static/js/application.js: var Search = {
- <a class="url" href="${href}">${href}</a>
- <p>${result.excerpt}</p></li>`;
- }))).join('');
--
++ new PagefindUI({
++ element: "#search-div",
++ showSubResults: true,
++ language
++ });
+
- searchResultsElements[0].innerHTML = list || '<li>No results found</li>';
- })
+ const searchTerm = this.getQueryValue('search');
-: --------- > 74: c7ff8dad0 Add a helper script to run Pagefind
-: --------- > 75: c32fdf3dc ci: verify the order of the search results
78: 8147144aa = 76: 26ff8cb61 Implement the `relurl` shortcode
79: 61d1610e4 ! 77: c8a20dffc Use relative URLs
@@ content/community/_index.html: aliases:
<h2> Contributing to Git </h2>
<p>
-- The <a href="https://github.com/git/git/tree/master/Documentation">Documentation directory</a> in the Git source code has several files of interest to developers who are looking to help contribute. After reading the <a href="https://github.com/git/git/blob/master/Documentation/CodingGuidelines">coding guidelines</a>, you can learn <a href="/docs/SubmittingPatches">how to submit patches</a>. If you are just starting out, you can read the <a href="/docs/MyFirstContribution">My First Contribution tutorial</a>. For those looking to get more deeply involved, there is a <a href="https://github.com/git/git/blob/master/Documentation/howto/maintain-git.txt">howto for Git maintainers</a>.
-+ The <a href="https://github.com/git/git/tree/master/Documentation">Documentation directory</a> in the Git source code has several files of interest to developers who are looking to help contribute. After reading the <a href="https://github.com/git/git/blob/master/Documentation/CodingGuidelines">coding guidelines</a>, you can learn <a href="{{< relurl "docs/SubmittingPatches" >}}">how to submit patches</a>. If you are just starting out, you can read the <a href="{{< relurl "docs/MyFirstContribution" >}}">My First Contribution tutorial</a>. For those looking to get more deeply involved, there is a <a href="https://github.com/git/git/blob/master/Documentation/howto/maintain-git.txt">howto for Git maintainers</a>.
+- The <a href="https://github.com/git/git/tree/master/Documentation">Documentation directory</a> in the Git source code has several files of interest to developers who are looking to help contribute. After reading the <a href="https://github.com/git/git/blob/master/Documentation/CodingGuidelines">coding guidelines</a> and <a href="https://github.com/git/git/blob/master/CODE_OF_CONDUCT.md">code of conduct</a>, you can learn <a href="/docs/SubmittingPatches">how to submit patches</a>. If you are just starting out, you can read the <a href="/docs/MyFirstContribution">My First Contribution tutorial</a>. For those looking to get more deeply involved, there is a <a href="https://github.com/git/git/blob/master/Documentation/howto/maintain-git.txt">howto for Git maintainers</a>.
++ The <a href="https://github.com/git/git/tree/master/Documentation">Documentation directory</a> in the Git source code has several files of interest to developers who are looking to help contribute. After reading the <a href="https://github.com/git/git/blob/master/Documentation/CodingGuidelines">coding guidelines</a> and <a href="https://github.com/git/git/blob/master/CODE_OF_CONDUCT.md">code of conduct</a>, you can learn <a href="{{< relurl "docs/SubmittingPatches" >}}">how to submit patches</a>. If you are just starting out, you can read the <a href="{{< relurl "docs/MyFirstContribution" >}}">My First Contribution tutorial</a>. For those looking to get more deeply involved, there is a <a href="https://github.com/git/git/blob/master/Documentation/howto/maintain-git.txt">howto for Git maintainers</a>.
</p>
<p>
@@ content/doc/_index.html: aliases:
</div>
- ## content/docs/_index.html ##
-@@ content/docs/_index.html: aliases:
- </p>
- </div>
- <div class="callout all-commands">
-- <a href="/docs/git#_git_commands">Complete list of all commands</a>
-+ <a href="{{< relurl "docs/git#_git_commands" >}}">Complete list of all commands</a>
- </div>
- <div class='reference-menu'>
- <div class='two-column'>
-
## content/downloads/_index.html ##
@@ content/downloads/_index.html: aliases:
<table class="binaries">
@@ layouts/_default/baseof.html
+ <link href="{{ relURL "favicon.ico" }}" rel='shortcut icon' type='image/x-icon'>
{{ if eq $section "search" }}<link href="{{ relURL "pagefind/pagefind-ui.css" }}" rel="stylesheet">{{ end }}
- {{ $style := resources.Get "sass/application.scss" | resources.ExecuteAsTemplate "application.scss" . | resources.ToCSS | resources.Minify }}
+ {{ $style := resources.Get "sass/application.scss" | resources.ExecuteAsTemplate "application.scss" . | css.Sass | resources.Minify }}
<link rel="stylesheet" href="{{ $style.RelPermalink }}">
- <script src="/js/modernizr.js"></script>
- <script src="/js/modernize.js"></script>
@@ layouts/partials/header.html
{{ if ne (.Scratch.Get "section") "search" }}
- <form id="search" action="/search/results">
+ <form id="search" action="{{ relURL "search/results" }}">
- <input id="search-text" name="search" placeholder="Search entire site..." autocomplete="off" type="text" />
+ <input id="search-text" name="search" placeholder="Type / to search entire site…" autocomplete="off" type="text" />
</form>
<div id="search-results"></div>
@@ layouts/partials/ref/category.html
- <a href="doc/credential-helpers">
+ <a href="{{ relURL "doc/credential-helpers" }}">
{{ else }}
-- <a href="{{ print "docs/" $doc.doc (cond (and (ne .Params.lang nil) (ne $doc.no_append_lang true)) (print "/" .Params.lang) "") }}">
-+ <a href="{{ relURL (print "docs/" $doc.doc (cond (and (ne .Params.lang nil) (ne $doc.no_append_lang true)) (print "/" .Params.lang) "")) }}">
+- <a href="{{ print "/docs/" $doc.doc (cond (and (ne $.Page.Params.lang nil) (ne $doc.no_append_lang true) (isset (index $.Site.Data.docs.pages $doc.doc) "languages") (isset (index $.Site.Data.docs.pages $doc.doc "languages") $.Page.Params.lang)) (print "/" $.Page.Params.lang) "") }}">
++ <a href="{{ relURL (print "docs/" $doc.doc (cond (and (ne $.Page.Params.lang nil) (ne $doc.no_append_lang true) (isset (index $.Site.Data.docs.pages $doc.doc) "languages") (isset (index $.Site.Data.docs.pages $doc.doc "languages") $.Page.Params.lang)) (print "/" $.Page.Params.lang) "")) }}">
{{ end }}
{{ if (eq $doc.title nil) }}
{{ replace $doc.doc "git-" "" }}
+ ## layouts/partials/ref/index.html ##
+@@
+ </p>
+ </div>
+ <div class="callout all-commands">
+- <a href="/docs/git#_git_commands">Complete list of all commands</a>
++ <a href="{{ relURL "docs/git#_git_commands" }}">Complete list of all commands</a>
+ </div>
+ <div class='reference-menu'>
+ <div class='two-column'>
+
## layouts/partials/sidebar.html ##
@@
<nav>
80: 199ad72ad = 78: 943375d44 Accommodate for base URLs other than `/`
81: 905f3d1b1 ! 79: 312d96605 ci: ensure that there are only relative URLs
@@ .github/workflows/ci.yml: jobs:
+ exit 1
+ fi
+
- - name: run Pagefind to build the search index
- run: npx -y pagefind --site public
+ - name: run Pagefind ${{ env.PAGEFIND_VERSION }} to build the search index
+ run: npx -y pagefind@${{ env.PAGEFIND_VERSION }} --site public
82: efccaef38 = 80: f54c9f6af Drop the Rails version of the ProGit book
83: 046ae69cf = 81: 05158a866 Move the ProGit book related Ruby code to a new location
84: 1b6c1ef2c ! 82: 34b4c74b9 Transmogrify the Rake script to generate the Pro Git book sections
@@ README.md: Now you need to get the latest downloads for the downloads pages:
+If you have 2FA enabled, you'll need to create a [Personal Access Token](https://help.github.com/articles/creating-an-access-token-for-command-line-use/).
-Alternatively, you can get the book content from a repository on your computer by specifying the path in the `GENPATH` environment variable to the `local_genbook2` target:
-+If you want to build the book for all available languages, just skip the language code:
++If you want to build the book for all available languages, just omit the language code parameter:
- $ GENLANG=fr GENPATH=../progit2-fr rake local_genbook2
+ $ ruby ./script/update-book2.rb
@@ README.md: Now you need to get the latest downloads for the downloads pages:
## Contributing
+ ## hugo.yml ##
+@@ hugo.yml: markup:
+ goldmark:
+ renderer:
+ unsafe: true
++module:
++ mounts:
++ - source: content
++ target: content
++ - source: static
++ target: static
++ - source: data
++ target: data
++ - source: external/book/data/book
++ target: data/book
++ - source: external/book/content/book
++ target: content/book
++ - source: external/book/static/book
++ target: static/book
+ params:
+ hugo_version: 0.134.1
+ pagefind_version: 1.1.1
+
## layouts/_default/baseof.html ##
@@
</div> <!-- .inner -->
@@ script/book.rb: class Book < ApplicationRecord
+ }
+ end
+
++ def content_note
++ "### DO NOT EDIT! Generated by script/update-book2.rb"
++ end
++
++ def wrap_front_matter(front_matter)
++ "#{front_matter.to_yaml.sub("---\n", "---\n#{self.content_note}\n")}---\n"
++ end
++
+ def absolute_path(path)
-+ File.absolute_path(File.join(File.dirname(__FILE__), "..", "content", "book", @language_code, "v#{@edition}", path))
++ File.absolute_path(File.join(File.dirname(__FILE__), "..", "external", "book", "content", "book", @language_code, "v#{@edition}", path))
+ end
+
+ def removeAllFiles
@@ script/book.rb: class Book < ApplicationRecord
+ return front_matter
+ end
+
++ def wrap_front_matter(front_matter)
++ @book.wrap_front_matter(front_matter)
++ end
++
+ attr_accessor :title
+ attr_accessor :chapter_type
+ attr_accessor :chapter_number
@@ script/book.rb: class Book < ApplicationRecord
+ def save
+ return if self.slug.nil?
+
-+ front_matter = "#{self.front_matter.to_yaml}\n---\n"
-+
+ path = self.absolute_path(self.slug)
+ FileUtils.mkdir_p(File.dirname(path))
+ File.open("#{path}.html", 'w') do |file|
-+ file.write(front_matter)
++ file.write(@chapter.wrap_front_matter(self.front_matter))
+ file.write(self.html.strip)
+ end
end
85: cdb7f4377 ! 83: 803869e33 update-book2: adjust navigation
@@ layouts/shortcodes/previous-section.html (new)
## script/book.rb ##
@@ script/book.rb: class Book
- File.absolute_path(File.join(File.dirname(__FILE__), "..", "content", "book", @language_code, "v#{@edition}", path))
+ File.absolute_path(File.join(File.dirname(__FILE__), "..", "external", "book", "content", "book", @language_code, "v#{@edition}", path))
end
+ def relative_url(path)
86: 44c163eaa ! 84: f6734888d update-book2: also include the images
@@ Commit message
## script/book.rb ##
@@ script/book.rb: class Book
- }
+ "#{front_matter.to_yaml.sub("---\n", "---\n#{self.content_note}\n")}---\n"
end
- def absolute_path(path)
-- File.absolute_path(File.join(File.dirname(__FILE__), "..", "content", "book", @language_code, "v#{@edition}", path))
+- File.absolute_path(File.join(File.dirname(__FILE__), "..", "external", "book", "content", "book", @language_code, "v#{@edition}", path))
+ def absolute_path(path, top_level = "content")
-+ File.absolute_path(File.join(File.dirname(__FILE__), "..", top_level, "book", @language_code, "v#{@edition}", path))
++ File.absolute_path(File.join(File.dirname(__FILE__), "..", "external", "book", top_level, "book", @language_code, "v#{@edition}", path))
end
def relative_url(path)
87: 7d0edee4b = 85: dcff0ad8c update-book2: show the chapter/section numbers in the titles
88: eb4e84dfd ! 86: 91531feee Generate the front page of the Pro Git book
@@ script/book.rb: class Book
+ front_matter["book"]["ebook_mobi"] = self.ebook_mobi
+ end
+
-+ front_matter = "#{front_matter.to_yaml}\n---"
-+
+ path = self.absolute_path("_index.html")
+ FileUtils.mkdir_p(File.dirname(path))
+ File.open(path, 'w') do |file|
-+ file.write(front_matter)
++ file.write(self.wrap_front_matter(front_matter))
+ end
+
++ front_matter = { "redirect_to" => "book/#{@language_code}/v#{@edition}" }
+ File.open(self.absolute_path("../_index.html"), 'w') do |file|
-+ file.write("---\nredirect_to: \"book/#{@language_code}/v#{@edition}\"\n---\n")
++ file.write(self.wrap_front_matter(front_matter))
+ end
++
+ if @language_code == "en"
+ File.open(self.absolute_path("../../_index.html"), 'w') do |file|
-+ file.write("---\nredirect_to: \"book/#{@language_code}/v#{@edition}\"\n---\n")
++ file.write(self.wrap_front_matter(front_matter))
+ end
+ end
+ end
89: 714b23ec6 ! 87: 419be615f book: also generate the URLs for the downloadable formats of the book
@@ Commit message
... but do this only for the English version, as the other versions are
not available in downloadable formats.
+ As the idea is to run this script in a GitHub workflow on a shallow
+ clone, let's be prepared for the situation where the tip commit of the
+ default branch is _not_ (yet?) tagged and therefore no tag is present in
+ the clone. In this situation, let's just go ahead and fetch all tags,
+ then move along and update the URLs accordingly.
+
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
## script/update-book2.rb ##
@@ script/update-book2.rb: def local_genbook2(language_code, worktree_path)
end
+ if language_code == 'en'
+ latest_tag = `git -C "#{worktree_path}" for-each-ref --format '%(refname:short)' --sort=-committerdate --count=1 refs/tags/`.chomp
++ if latest_tag.empty?
++ puts "No tag found in #{worktree_path}, trying to fetch tags"
++ latest_tag = `git -C "#{worktree_path}" fetch --tags origin && git -C "#{worktree_path}" for-each-ref --format '%(refname:short)' --sort=-committerdate --count=1 refs/tags/`.chomp
++ raise "Still no tags in #{worktree_path}?" if latest_tag.empty?
++ end
+ book.ebook_pdf = "https://github.com/progit/progit2/releases/download/#{latest_tag}/progit.pdf"
+ book.ebook_epub = "https://github.com/progit/progit2/releases/download/#{latest_tag}/progit.epub"
+ book.ebook_mobi = "https://github.com/progit/progit2/releases/download/#{latest_tag}/progit.mobi"
90: 68e96e524 < -: --------- Record SHA of the Pro Git book even when generating it locally
-: --------- > 88: 406254667 update-book2.rb: gracefully warn about missing files, but continue
-: --------- > 89: 9f7d416f5 Record SHA of the Pro Git book even when generating it locally
91: 915329bc2 ! 90: e6e83c127 Pro Git book: populate the `Chapters` drop-down
@@ layouts/_default/baseof.html
{{ partial "footer.html" . }}
</div> <!-- #content-wrapper -->
{{ else if (isset .Params "book") }}
-+ {{ .Scratch.Set "book" (index .Site.Data (print "book-" .Params.book.language_code)) }}
++ {{ .Scratch.Set "book" (index .Site.Data.book .Params.book.language_code) }}
<div class="inner">
<div id="content-wrapper">
{{ partial "sidebar.html" . }}
@@ script/book.rb: class Book
+ "language_code" => @language_code,
+ "chapters" => chapters
+ }
-+ path = File.join(File.dirname(__FILE__), "..", "data", "book-#{@language_code}.yml")
++ path = File.join(File.dirname(__FILE__), "..", "external", "book", "data", "book", "#{@language_code}.yml")
+ FileUtils.mkdir_p(File.dirname(path))
+ File.open(path, 'w') do |file|
++ file.write("#{self.content_note}\n")
+ file.write(data.to_yaml.strip)
+ end
+
92: 6156ecfdd = 91: 1a51fcc94 book: keep colons and other special characters in URLs
93: 2dd98a59e = 92: e492c9c63 book: fix translated labels
94: 289ee87b7 ! 93: 7f3b191a3 book: generate cross-references correctly
@@ script/book.rb: class Book
def front_matter
@@ script/book.rb: class Book
- file.write("---\nredirect_to: \"book/#{@language_code}/v#{@edition}\"\n---\n")
+ file.write(self.wrap_front_matter(front_matter))
end
end
+
@@ script/book.rb: class Book
+ @xrefs.each do |id_xref, section|
+ path = self.absolute_path("ch00/#{id_xref}.html")
+ relurl = "#{section.relative_url(nil)}##{id_xref}"
++ front_matter = { "redirect_to" => relurl }
+ File.open(path, 'w') do |file|
-+ file.write("---\nredirect_to: \"#{relurl}\"\n---\n")
++ file.write(self.wrap_front_matter(front_matter))
+ end
+ end
end
95: ded726a6c = 94: 4a31646bc book-tl: work around an incorrect image reference
96: 4078053ef = 95: 01b1dd71f book: work around lagging translations' image paths
97: 8f4d3d8a3 ! 96: 731b6b686 book(xrefs): maintain question marks that are part of the URL path
@@ Commit message
sections' titles; These need to be (URL-)encoded in the URL and not be
mistaken for the separator between path and GET parameter(s).
+ While at it, also install redirects for URLs containing a question mark
+ so that incorrect URLs that contain a literal question mark (which is
+ interpreted as separator between the URL path and the `GET`
+ parameter(s)) redirect to the correct ones.
+
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
## script/book.rb ##
@@ script/book.rb: class Section
}
if @slug =~ /:|[^-A-Za-z0-9_]/
- front_matter["url"] = self.relative_url(@slug)
-+ front_matter["url"] = self.relative_url(@slug).gsub(/%3F/, '?')
++ relative_url = self.relative_url(@slug)
++ front_matter["url"] = "/#{relative_url.gsub(/%3F/, '?')}.html"
++ if relative_url =~ /%3F/
++ front_matter["aliases"] = [
++ "/#{relative_url.gsub(/%3F.*/, '')}.html"
++ ]
++ end
end
return front_matter
end
98: b99c5d1d5 ! 97: 0343bf0ab book: redirect missing xrefs to the English book
@@ script/book.rb: class Book
@xrefs.each do |id_xref, section|
path = self.absolute_path("ch00/#{id_xref}.html")
- relurl = "#{section.relative_url(nil)}##{id_xref}"
+- front_matter = { "redirect_to" => relurl }
+ if section == 'redirect-to-en'
+ url = "book/en/v2/ch00/#{id_xref}"
+ else
+ url = "#{section.relative_url(nil)}##{id_xref}"
+ end
++ front_matter = { "redirect_to" => url }
File.open(path, 'w') do |file|
-- file.write("---\nredirect_to: \"#{relurl}\"\n---\n")
-+ file.write("---\nredirect_to: \"#{url}\"\n---\n")
+ file.write(self.wrap_front_matter(front_matter))
end
- end
- end
## script/update-book2.rb ##
@@ script/update-book2.rb: def genbook(language_code, &get_content)
99: c3f723764 = 98: 8b30c3748 book: handle footnotes gracefully
100: 58dcc1d03 = 99: bedb26d29 book: fix a couple of broken redirects
101: be1163d71 = 100: f890fa149 docs: prepare for `index.rake` to become a proper Ruby script
102: 73280317a ! 101: 990ac016c Turn what used to be the `index.rake` file into a proper Ruby script
@@ README.md: Note that this will take about 7 times as long, and the site will not
Similarly, you can also populate the localized man pages. From a local clone of https://github.com/jnavila/git-html-l10n :
+ ## hugo.yml ##
+@@ hugo.yml: module:
+ target: content/book
+ - source: external/book/static/book
+ target: static/book
++ - source: external/docs/data
++ target: data
++ - source: external/docs/content
++ target: content
+ params:
+ hugo_version: 0.134.1
+ pagefind_version: 1.1.1
+
## layouts/_default/baseof.html ##
@@
</div>
@@ script/update-docs.rb
+require_relative "version"
+
+SITE_ROOT = File.join(File.expand_path(File.dirname(__FILE__)), '../')
-+DATA_FILE = "#{SITE_ROOT}data/docs.yml"
++DOCS_INDEX_FILE = "#{SITE_ROOT}external/docs/content/docs/_index.html"
++DATA_FILE = "#{SITE_ROOT}external/docs/data/docs.yml"
+
+def read_data
+ if File.exists?(DATA_FILE)
@@ script/update-docs.rb
def make_asciidoc(content)
Asciidoctor::Document.new(content,
+@@ script/update-docs.rb: def make_asciidoc(content)
+ doctype: "book")
+ end
+
++def content_note
++ "### DO NOT EDIT! Generated by script/update-docs.rb\n"
++end
++
++def wrap_front_matter(front_matter)
++ "#{front_matter.to_yaml.sub("---\n", "---\n#{content_note}\n")}---\n"
++end
++
+ def expand_l10n(path, content, get_f_content, categories)
+ content.gsub!(/include::(\S+)\.txt/) do |line|
+ line.gsub!("include::", "")
@@ script/update-docs.rb: def expand_l10n(path, content, get_f_content, categories)
end
@@ script/update-docs.rb: def index_doc(filter_tags, doc_list, get_content)
next if doc_limit && path !~ /#{doc_limit}/
- file = DocFile.where(name: docname).first_or_create
-+ doc_path = "#{SITE_ROOT}content/docs/#{docname}"
++ doc_path = "#{SITE_ROOT}external/docs/content/docs/#{docname}"
puts " build: #{docname}"
@@ script/update-docs.rb: def index_doc(filter_tags, doc_list, get_content)
+
+ FileUtils.mkdir_p(doc_path)
+ File.open("#{doc_path}/#{tagname}.html", "w") do |out|
-+ out.write("#{front_matter.to_yaml}\n---\n", out)
++ out.write(wrap_front_matter(front_matter))
+ out.write(html, out)
+ end
@@ script/update-docs.rb: def index_doc(filter_tags, doc_list, get_content)
+ FileUtils.mkdir_p(File.dirname(doc_path))
+ File.open("#{doc_path}.html", "w") do |out|
+ front_matter["aliases"] = ["/docs/#{docname}/index.html"]
-+ out.write("#{front_matter.to_yaml}\n---\n")
++ out.write(wrap_front_matter(front_matter))
+ out.write(html)
+ end
+ end
@@ script/update-docs.rb: def index_doc(filter_tags, doc_list, get_content)
- Rails.cache.write("latest-version", Version.latest_version.name)
+ data["latest-version"] = tagname
+ end
++
++ front_matter = {
++ "section" => "documentation",
++ "subsection" => "reference",
++ "title" => "Git - Reference",
++ "url" => "/docs.html",
++ "aliases" => ["/docs/index.html"]
++ }
++
++ File.open(DOCS_INDEX_FILE, "w") do |out|
++ out.write(wrap_front_matter(front_matter))
++ end
++
+ File.open(DATA_FILE, "w") do |out|
+ YAML.dump(data, out)
end
103: e34a4915b = 102: c7eb81c73 Highlight the `Reference` nav item for manual pages
104: 42a90c22a ! 103: 5d5bfe56a update-docs: install redirects for the various versions
@@ script/update-docs.rb: def index_doc(filter_tags, doc_list, get_content)
FileUtils.mkdir_p(doc_path)
- File.open("#{doc_path}/#{tagname}.html", "w") do |out|
-- out.write("#{front_matter.to_yaml}\n---\n", out)
+- out.write(wrap_front_matter(front_matter))
- out.write(html, out)
+ front_matter_with_redirects = front_matter.clone
+ front_matter_with_redirects["aliases"] =
@@ script/update-docs.rb: def index_doc(filter_tags, doc_list, get_content)
+ ["/docs/#{docname}/#{v}/index.html"]
+ end
+ File.open("#{doc_path}/#{doc_versions[changed_in]}.html", "w") do |out|
-+ out.write("#{front_matter_with_redirects.to_yaml}\n---\n")
++ out.write(wrap_front_matter(front_matter_with_redirects))
+ out.write(html)
end
105: 6a68ca809 ! 104: 1fc1b2d4b Show the different versions of the manual pages
@@ script/update-docs.rb: def index_doc(filter_tags, doc_list, get_content)
- anchor += "-1" while ids.include?(anchor)
- ids.add(anchor)
- "<dt class=\"hdlist1\" id=\"#{anchor}\"> <a class=\"anchor\" href=\"##{anchor}\"></a>#{$1} </dt>"
-+ if !File.exists?("#{SITE_ROOT}_generated-asciidoc/#{asciidoc_sha}")
-+ FileUtils.mkdir_p("#{SITE_ROOT}_generated-asciidoc")
-+ File.open("#{SITE_ROOT}_generated-asciidoc/#{asciidoc_sha}", "w") do |out|
++ if !File.exists?("#{SITE_ROOT}external/docs/asciidoc/#{asciidoc_sha}")
++ FileUtils.mkdir_p("#{SITE_ROOT}external/docs/asciidoc")
++ File.open("#{SITE_ROOT}external/docs/asciidoc/#{asciidoc_sha}", "w") do |out|
+ out.write(content)
end
end
@@ script/update-docs.rb: def index_doc(filter_tags, doc_list, get_content)
+ page_data["diff-cache"] = {} if !page_data["diff-cache"]
+ cached_diff = page_data["diff-cache"]["#{pre_sha}..#{post_sha}"]
+ if !cached_diff
-+ pre_content = File.read("#{SITE_ROOT}_generated-asciidoc/#{pre_sha}")
-+ post_content = File.read("#{SITE_ROOT}_generated-asciidoc/#{post_sha}")
++ pre_content = File.read("#{SITE_ROOT}external/docs/asciidoc/#{pre_sha}")
++ post_content = File.read("#{SITE_ROOT}external/docs/asciidoc/#{post_sha}")
+ cached_diff = page_data["diff-cache"]["#{pre_sha}..#{post_sha}"] = diff(pre_content, post_content)
+ end
+ page_versions.unshift({
@@ script/update-docs.rb: def index_doc(filter_tags, doc_list, get_content)
- data["latest-version"] = tagname
+ data["latest-version"] = version if !data["latest-version"] || Version.version_to_num(data["latest-version"]) < Version.version_to_num(version)
end
- File.open(DATA_FILE, "w") do |out|
- YAML.dump(data, out)
+
+ front_matter = {
106: 1ab0c772b ! 105: 9953afacd search: exclude older manual page versions
@@ layouts/_default/baseof.html
- <div id="main" data-pagefind-body>
+ <!-- older manual page versions are less interesting and need to be excluded from the search -->
-+ {{ $include_in_search := (or (not (isset .Params "docname")) (isset .Params "latest-changes")) }}
++ {{ $include_in_search := (or (not (isset .Params "docname")) (isset .Params "latest-changes") (isset .Params "lang")) }}
+ <div id="main"{{ if $include_in_search }} data-pagefind-body{{ end }}>
{{ .Content }}
</div>
@@ script/update-docs.rb: def index_doc(filter_tags, doc_list, get_content)
File.open("#{doc_path}.html", "w") do |out|
+ front_matter["latest-changes"] = version
front_matter["aliases"] = ["/docs/#{docname}/index.html"]
- out.write("#{front_matter.to_yaml}\n---\n")
+ out.write(wrap_front_matter(front_matter))
out.write(html)
107: c1948441b ! 106: ec44e3010 search: offer the section as a filter
@@ layouts/_default/baseof.html
@@
<!-- older manual page versions are less interesting and need to be excluded from the search -->
- {{ $include_in_search := (or (not (isset .Params "docname")) (isset .Params "latest-changes")) }}
+ {{ $include_in_search := (or (not (isset .Params "docname")) (isset .Params "latest-changes") (isset .Params "lang")) }}
- <div id="main"{{ if $include_in_search }} data-pagefind-body{{ end }}>
+ <div id="main"{{ if $include_in_search }} data-pagefind-filter="category:{{ $section }}" data-pagefind-body{{ end }}>
{{ .Content }}
@@ layouts/_default/baseof.html
{{ partial "sidebar.html" . }}
- <div id="content" data-pagefind-body>
+ <div id="content" data-pagefind-filter="category:{{ $section }}" data-pagefind-body>
- {{ if isset .Params "video_title" }}
- <div id="main">
- <h1>{{ .Params.category }} Episode {{ .Params.episode }}</h1>
+ {{ if (eq .Page.Path "/docs") }}
+ {{ partial "ref/index.html" . }}
+ {{ else if isset .Params "video_title" }}
108: ad3768be5 < -: --------- search: give the manual pages' titles maximal weight
-: --------- > 107: 5e6f328ce search: give the manual pages' titles maximal weight
109: 05a15df77 ! 108: 25906cd41 search: reintroduce the categories in the live search
@@ Commit message
We do this by specifically adding metadata indicating the category of
manual pages as well as for the sections of the book (for details, see
https://pagefind.app/docs/metadata/). Then, we use that information to
- sort the results as they arrive into the correct table row (and
- displaying it when necessary, as the empty rows are initially hidden).
+ sort the results into the correct table row. Due to the `async` nature
+ of the search results coming in, we need to be
+ careful to process them in order when doing that.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
@@ layouts/_default/baseof.html
2nd Edition
</span>
</div>
-- <div id="main" data-pagefind-filter="category:{{ $section }}" data-pagefind-body class="book edition2">
-+ <div id="main" data-pagefind-filter="category:{{ $section }}" data-pagefind-meta="category:Book" data-pagefind-body class="book edition2">
+- <div id="main" data-pagefind-filter="category:{{ $section }}" data-pagefind-weight="0.05" data-pagefind-body class="book edition2">
++ <div id="main" data-pagefind-filter="category:{{ $section }}" data-pagefind-meta="category:Book" data-pagefind-weight="0.05" data-pagefind-body class="book edition2">
<h1>{{ .Params.book.section.cs_number }} {{ .Params.book.chapter.title }} - {{ .Params.book.section.title }}</h1>
<div>
{{ .Content }}
@@
<!-- older manual page versions are less interesting and need to be excluded from the search -->
- {{ $include_in_search := (or (not (isset .Params "docname")) (isset .Params "latest-changes")) }}
-- <div id="main"{{ if $include_in_search }} data-pagefind-filter="category:{{ $section }}" data-pagefind-body{{ end }}>
-+ <div id="main"{{ if $include_in_search }} data-pagefind-filter="category:{{ $section }}" data-pagefind-meta="category:Reference" data-pagefind-body{{ end }}>
- {{ safe.HTML (replaceRE "(?s:>NAME</h2>.*?<p)" "$0 data-pagefind-weight=\"7\"" .Content) }}
- </div>
- </div>
+ {{ $include_in_search := (or (not (isset .Params "docname")) (isset .Params "latest-changes") (isset .Params "lang")) }}
+- <div id="main"{{ if $include_in_search }} data-pagefind-filter="category:{{ $section }}" data-pagefind-weight="0.05" data-pagefind-body{{ end }}>
++ <div id="main"{{ if $include_in_search }} data-pagefind-filter="category:{{ $section }}" data-pagefind-meta="category:Reference" data-pagefind-weight="0.05" data-pagefind-body{{ end }}>
+ {{ .Content }}
+ {{ $match := findRESubmatch "(?s)>NAME</h2>.*?<p[^>]*>(git-)?([^ ]+)" .Content 1 }}
+ {{ if (eq ($match | len) 1) }}
## static/js/application.js ##
@@ static/js/application.js: var Search = {
@@ static/js/application.js: var Search = {
+
const chunkLength = 10;
let displayCount = 0;
++
++ const categorizeResult = (i) => {
++ while (i < displayCount && typeof results.results[i].data === 'object') {
++ const result = results.results[i++];
++ if (result.data.meta.category === 'Reference') {
++ if (ulReference.children().length === 0) ulReference.parent().parent().css("display", "table-row")
++ ulReference.append(result.li)
++ } else if (result.data.meta.category === 'Book') {
++ if (ulBook.children().length === 0) ulBook.parent().parent().css("display", "table-row")
++ ulBook.append(result.li)
++ }
++ }
++ };
++
const loadResultsChunk = () => {
-@@ static/js/application.js: var Search = {
+ if (loadButton.loading || displayCount >= results.results.length) return;
+
+ loadButton.loading = true;
+ const n = displayCount + chunkLength;
+ while (displayCount < n) {
+- const li = $("<li><a>…</a></li>");
+- li.insertBefore(loadButton);
++ const result = results.results[displayCount]
++ result.li = $("<li><a>…</a></li>");
++ result.li.insertBefore(loadButton);
+
// load the result lazily
- (async () => {
- const result = await results.results[displayCount].data();
-+ if (result.meta.category === 'Reference') {
-+ if (ulReference.children().length === 0) ulReference.parent().parent().css("display", "table-row")
-+ ulReference.append(li)
-+ } else if (result.meta.category === 'Book') {
-+ if (ulBook.children().length === 0) ulBook.parent().parent().css("display", "table-row")
-+ ulBook.append(li)
-+ }
- li.html(`<a href = "${result.url}">${result.meta.title}</a>`);
- })().catch(console.log);
+- (async () => {
+- const result = await results.results[displayCount].data();
+- li.html(`<a href = "${result.url}">${result.meta.title}</a>`);
+- })().catch(console.log);
++ (async (i) => {
++ result.data = await results.results[displayCount].data();
++ if (!i || typeof results.results[i - 1].data === 'object') categorizeResult(i);
++ result.li.html(`<a href = "${result.data.url}">${result.data.meta.title}</a>`);
++ })(displayCount).catch((err) => {
++ console.log(err);
++ result.li.html(`<i>Error loading result</i>`);
++ });
+ if (++displayCount >= results.results.length) {
+ loadButton.remove();
110: 49f58f182 < -: --------- search: show manual pages' short title in the live search
-: --------- > 109: 4f239bc08 search: show manual pages' short title in the live search
-: --------- > 110: 347830d09 search: link to "pretty" URLs
111: 6fc0f8e9e = 111: cb68f3611 docs: handle multiple `linkgit:` in the same line
112: 1f9dc5079 = 112: 687183039 docs: correctly handle `{litdd}` in `linkgit` values
113: 44dca56fe = 113: 2b061bf40 docs: handle `gitlink:` gracfully
114: 702ce1711 = 114: 149872c37 docs: handle double colon in `linkgit::` gracefully
115: 26a84723f = 115: 25d0d5463 docs: handle `linkgit:curl[1]` gracefully
116: 9cb3ff53a = 116: 187843aba Allow `redirect_to` with fully-qualified URLs
117: 412391840 ! 117: f20b1c76d docs: add fall-back redirects for unrendered pages
@@ script/update-docs.rb: def index_doc(filter_tags, doc_list, get_content)
+ # that are not populated. Let's redirect to the source files in the
+ # git/git repository.
+ check_paths.each do |path|
-+ doc_path = "#{SITE_ROOT}content/#{path}.html"
++ doc_path = "#{SITE_ROOT}external/docs/content/#{path}.html"
+ if !File.exists?(doc_path)
+ type = 'blob'
+ target = path.sub(/^docs\//, '')
@@ script/update-docs.rb: def index_doc(filter_tags, doc_list, get_content)
+ front_matter = { "redirect_to" => "https://github.com/git/git/#{type}/HEAD/Documentation/#{target}" } # ltrim `docs/`
+ FileUtils.mkdir_p(File.dirname(doc_path))
+ File.open(doc_path, "w") do |out|
-+ out.write("#{front_matter.to_yaml}\n---\n")
++ out.write(wrap_front_matter(front_matter))
+ end
+ end
+ end
118: 55c7b5f48 ! 118: fcbfb1f1d docs: work around a `link:` bug in older versions
@@ Metadata
Author: Johannes Schindelin <johannes.schindelin@gmx.de>
## Commit message ##
- docs: work around a `link:` bug in older versions
+ docs: work around `link:`/`linkgit:` bugs in older versions
Since we want to build older Git versions' manual pages, too, we have to
work around bugs since fixed.
@@ script/update-docs.rb: def index_doc(filter_tags, doc_list, get_content)
+ # Handle erroneous `link:api-trace2.txt`, see 4945f046c7f5 (api docs:
+ # link to html version of api-trace2, 2022-09-16)
+ content.gsub!(/link:api-trace2.txt/, 'link:api-trace2.html')
++ # Handle `linkgit:git-config.txt` mistake, fixed in ad52148a7d0
++ # (Documentation: fix broken linkgit to git-config, 2016-03-21)
++ content.gsub!(/linkgit:git-config.txt/, 'linkgit:git-config')
content.gsub!(/link:(?:technical\/)?(\S*?)\.html(\#\S*?)?\[(.*?)\]/m, "link:/docs/\\1\\2[\\3]")
asciidoc = make_asciidoc(content)
119: a7344a9d2 ! 119: 5b1d692eb Migrate the translated manual pages to the Hugo world
@@ layouts/_default/baseof.html
<div id="content">
<div id='reference-version'>
+ {{ partial "ref/languages.html" . }}
-+ {{ partialCached "ref/topics.html" . }}
++ {{ partial "ref/topics.html" . }}
{{ partial "ref/versions.html" . }}
</div>
@@ script/update-docs.rb: def index_l10n_doc(filter_tags, doc_list, get_content)
path = File.basename(full_path, ".txt")
- file = DocFile.where(name: path).first_or_create
-+ doc_path = "#{SITE_ROOT}content/docs/#{path}"
++ doc_path = "#{SITE_ROOT}external/docs/content/docs/#{path}"
puts " build: #{path} for #{lang}"
@@ script/update-docs.rb: def index_l10n_doc(filter_tags, doc_list, get_content)
- html.gsub!(/linkgit:(\S+?)\[(\d+)\]/) do |line|
- x = /^linkgit:(\S+?)\[(\d+)\]/.match(line)
- "<a href='/docs/#{x[1].gsub(/-/, '-')}/#{lang}'>#{x[1]}[#{x[2]}]</a>"
-+ if !File.exists?("#{SITE_ROOT}_generated-asciidoc/#{asciidoc_sha}")
-+ FileUtils.mkdir_p("#{SITE_ROOT}_generated-asciidoc")
-+ File.open("#{SITE_ROOT}_generated-asciidoc/#{asciidoc_sha}", "w") do |out|
++ if !File.exists?("#{SITE_ROOT}external/docs/asciidoc/#{asciidoc_sha}")
++ FileUtils.mkdir_p("#{SITE_ROOT}external/docs/asciidoc")
++ File.open("#{SITE_ROOT}external/docs/asciidoc/#{asciidoc_sha}", "w") do |out|
+ out.write(content)
end
- # HTML anchor on hdlist1 (i.e. command options)
@@ script/update-docs.rb: def index_l10n_doc(filter_tags, doc_list, get_content)
+
+ FileUtils.mkdir_p(doc_path)
+ File.open("#{doc_path}/#{lang}.html", "w") do |out|
-+ out.write("#{front_matter.to_yaml}\n---\n")
++ out.write(wrap_front_matter(front_matter))
+ out.write(html)
+ end
+
120: dd2d5016c = 120: b88d2bef6 docs(zh_HANS-CN): a trailing "full stop" character is not part of a URL
121: 9c93bfdec < -: --------- redirect_to: keep the anchor, if any was specified
-: --------- > 121: 968e6e25b redirect_to/aliases: keep the anchor, if any was specified
122: 6ef6dbe2f ! 122: f2e7a5ffa docs(translated): add redirects for missing files
@@ script/update-docs.rb: def index_l10n_doc(filter_tags, doc_list, get_content)
+ end
asciidoc = make_asciidoc(content)
asciidoc_sha = Digest::SHA1.hexdigest(asciidoc.source)
- if !File.exists?("#{SITE_ROOT}_generated-asciidoc/#{asciidoc_sha}")
+ if !File.exists?("#{SITE_ROOT}external/docs/asciidoc/#{asciidoc_sha}")
@@ script/update-docs.rb: def index_l10n_doc(filter_tags, doc_list, get_content)
html.gsub!(/linkgit:(\S+?)\[(\d+)\]/) do |line|
x = /^linkgit:(\S+?)\[(\d+)\]/.match(line)
@@ script/update-docs.rb: def index_l10n_doc(filter_tags, doc_list, get_content)
+ # translated manual pages may point to other translated manual pages that do
+ # not exist. In these cases, redirect to the English version.
+ check_paths.each do |path|
-+ doc_path = "#{SITE_ROOT}content/#{path}.html"
++ doc_path = "#{SITE_ROOT}external/docs/content/#{path}.html"
+ if !File.exists?(doc_path)
+ front_matter = { "redirect_to" => "#{path.sub(/\/[^\/]*$/, '')}" } # rtrim `/<lang>`
+ FileUtils.mkdir_p(File.dirname(doc_path))
+ File.open(doc_path, "w") do |out|
-+ out.write("#{front_matter.to_yaml}\n---\n")
++ out.write(wrap_front_matter(front_matter))
+ end
+ end
+ end
123: e7e038a32 ! 123: 19d453f94 ci: update the books via a GitHub workflow
@@ Commit message
This information is then used by a scheduled workflow to determine what
needs to be updated (if anything) and then performing that task.
+ When GitHub workflows push new changes, they cannot trigger other GitHub
+ workflows (to avoid infinite loops). Therefore, this new GitHub workflow
+ not only synchronizes the books, but also builds the site and deploys
+ it.
+
+ Note: The code to build the site and to deploy it is provided in a
+ custom Action, to make it reusable. It will come in handy over the next
+ commits, where other GitHub workflows are added that likewise need
+ to synchronize changes that desire a site rebuild & deployment.
+
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
## .github/actions/deploy-to-github-pages/action.yml (new) ##
@@ .github/actions/deploy-to-github-pages/action.yml (new)
+
+ - name: setup GitHub Pages
+ id: pages
-+ uses: actions/configure-pages@v3
++ uses: actions/configure-pages@v5
+
-+ - name: install Hugo
-+ env:
-+ HUGO_VERSION: 0.120.3
++ - name: configure Hugo and Pagefind version
++ shell: bash
++ run: |
++ set -x &&
++ echo "HUGO_VERSION=$(sed -n 's/^ *hugo_version: *//p' <hugo.yml)" >>$GITHUB_ENV
++ echo "PAGEFIND_VERSION=$(sed -n 's/^ *pagefind_version: *//p' <hugo.yml)" >>$GITHUB_ENV
++
++ - name: install Hugo ${{ env.HUGO_VERSION }}
+ shell: bash
+ run: |
+ set -x &&
@@ .github/actions/deploy-to-github-pages/action.yml (new)
+ env:
+ HUGO_RELATIVEURLS: false
+ shell: bash
-+ run: hugo --minify --baseURL "${{ steps.pages.outputs.base_url }}/"
++ run: hugo config && hugo --minify --baseURL "${{ steps.pages.outputs.base_url }}/"
+
-+ - name: run Pagefind to build the search index
++ - name: run Pagefind ${{ env.PAGEFIND_VERSION }} to build the search index
+ shell: bash
-+ run: npx -y pagefind --site public
++ run: npx -y pagefind@${{ env.PAGEFIND_VERSION }} --site public
+
+ - name: upload GitHub Pages artifact
-+ uses: actions/upload-pages-artifact@v2
++ uses: actions/upload-pages-artifact@v3
+ with:
+ path: ./public
+
+ - name: deploy
+ id: deploy
-+ uses: actions/deploy-pages@v2
++ uses: actions/deploy-pages@v4
## .github/workflows/update-book.yml (new) ##
@@
@@ .github/workflows/update-book.yml (new)
+ check-for-updates:
+ runs-on: ubuntu-latest
+ steps:
-+ - uses: actions/checkout@v3
++ - uses: actions/checkout@v4
+ with:
+ sparse-checkout: |
-+ _sync_state
++ external/book/sync
+ script
-+ - uses: actions/github-script@v6
++ - uses: actions/github-script@v7
+ id: get-pending
+ with:
+ script: |
@@ .github/workflows/update-book.yml (new)
+ language: ${{ fromJson(needs.check-for-updates.outputs.matrix) }}
+ fail-fast: false
+ steps:
-+ - uses: actions/checkout@v3
++ - uses: actions/checkout@v4
+ with:
+ sparse-checkout: |
-+ _sync_state
+ script
-+ data
-+ content/book/${{ matrix.language.lang }}
-+ static/book/${{ matrix.language.lang }}
++ external/book/sync
++ external/book/data
++ external/book/content/book/${{ matrix.language.lang }}
++ external/book/static/book/${{ matrix.language.lang }}
+ - name: clone ${{ matrix.language.repository }}
+ run: |
+ printf '%s\n' /progit-clone/ /vendor >>.git/info/exclude &&
@@ .github/workflows/update-book.yml (new)
+ - name: commit changes
+ run: |
+ # record the commit hash
-+ mkdir -p _sync_state &&
-+ git -C progit-clone rev-parse HEAD >_sync_state/book-${{ matrix.language.lang }}.sha &&
++ mkdir -p external/book/sync &&
++ git -C progit-clone rev-parse HEAD >external/book/sync/book-${{ matrix.language.lang }}.sha &&
+
+ # commit it all
-+ git add -A \
-+ _sync_state \
-+ data/book-${{ matrix.language.lang }}.yml \
-+ content/book &&
-+ # there might be images
-+ if test -d static/book
-+ then
-+ git add -A static/book
-+ fi &&
++ git add -A external/book &&
+ git -c user.name=${{ github.actor }} \
+ -c user.email=${{ github.actor }}@noreply.github.com \
+ commit -m 'book: update ${{ matrix.language.lang }}' \
@@ .github/workflows/update-book.yml (new)
+ run: |
+ git branch -m book-${{ matrix.language.lang }}
+ git bundle create ${{ matrix.language.lang }}.bundle refs/remotes/origin/${{ github.ref_name }}..book-${{ matrix.language.lang }}
-+ - uses: actions/upload-artifact@v3
++ - uses: actions/upload-artifact@v4
+ with:
+ name: bundle-${{ matrix.language.lang }}
+ path: ${{ matrix.language.lang }}.bundle
@@ .github/workflows/update-book.yml (new)
+ url: ${{ steps.deploy.outputs.url }}
+ runs-on: ubuntu-latest
+ steps:
-+ - uses: actions/checkout@v3
-+ - uses: actions/download-artifact@v3
++ - uses: actions/checkout@v4
++ - uses: actions/download-artifact@v4
+ - name: apply updates
+ id: apply
+ run: |
@@ .github/workflows/update-book.yml (new)
+ id: deploy
+ uses: ./.github/actions/deploy-to-github-pages
- ## _sync_state/.gitignore (new) ##
-
## script/ci-helper.js (new) ##
@@
+const fs = require('fs')
@@ script/ci-helper.js (new)
+ const result = []
+ for (const lang of Object.keys(books)) {
+ try {
-+ const localSha = await getFileContents(`_sync_state/book-${lang}.sha`)
++ const localSha = await getFileContents(`external/book/sync/book-${lang}.sha`)
+
+ const [owner, repo] = books[lang].split('/')
+ const { data: { default_branch: remoteDefaultBranch } } =
124: c7c4d347d ! 124: 1ace765fc Update the download data via a GitHub workflow
@@ .github/workflows/update-download-data.yml (new)
+ name: github-pages
+ url: ${{ steps.deploy.outputs.url }}
+ steps:
-+ - uses: actions/checkout@v3
++ - uses: actions/checkout@v4
+ with:
+ sparse-checkout: |
+ .github/actions
-+ _sync_state
+ script
+ - name: ruby setup
+ uses: ruby/setup-ruby@v1
@@ .github/workflows/update-download-data.yml (new)
+ git \
+ -c user.name=${{ github.actor }} \
+ -c user.email=${{ github.actor }}@noreply.github.com \
-+ commit -m "$commit_message" -- hugo.yml
++ commit -m "$commit_message" \
++ -m 'Updated via the `update-download-data.yml` GitHub workflow.' \
++ -- hugo.yml
+ - name: verify that there are no uncommitted changes
+ run: |
+ git update-index --refresh &&
125: 3bd0e53a3 ! 125: 775c1d220 update-book: allow force-rebuilding
@@ .github/workflows/update-book.yml: jobs:
const { getPendingBookUpdates } = require('./script/ci-helper.js')
- const pending = await getPendingBookUpdates(github)
-+ const pending = await getPendingBookUpdates(github, ${{ inputs.force-rebuild }})
++ const pending = await getPendingBookUpdates(github, ${{ inputs.force-rebuild == true }})
// an empty matrix is invalid and makes the workflow run fail, unfortunately
return pending.length ? pending : ['']
- name: ruby setup
@@ script/ci-helper.js: const getAllBooks = async () => {
const result = []
for (const lang of Object.keys(books)) {
- try {
-- const localSha = await getFileContents(`_sync_state/book-${lang}.sha`)
+- const localSha = await getFileContents(`external/book/sync/book-${lang}.sha`)
+ if (!forceRebuild) {
+ try {
-+ const localSha = await getFileContents(`_sync_state/book-${lang}.sha`)
++ const localSha = await getFileContents(`external/book/sync/book-${lang}.sha`)
- const [owner, repo] = books[lang].split('/')
- const { data: { default_branch: remoteDefaultBranch } } =
126: 835105745 ! 126: 2193295a0 Add a workflow to update the Git version and manual pages
@@ .github/workflows/update-git-version-and-manual-pages.yml (new)
+ name: github-pages
+ url: ${{ steps.deploy.outputs.url }}
+ steps:
-+ - uses: actions/checkout@v3
++ - uses: actions/checkout@v4
+ with:
+ sparse-checkout: |
+ .github/actions
-+ _sync_state
+ script
+ - name: ruby setup
+ uses: ruby/setup-ruby@v1
@@ .github/workflows/update-git-version-and-manual-pages.yml (new)
+ git \
+ -c user.name=${{ github.actor }} \
+ -c user.email=${{ github.actor }}@noreply.github.com \
-+ commit -m "Update git-version ($version)" -- hugo.yml
++ commit -m "Update git-version ($version)" \
++ -m 'Updated via the `update-git-version-and-manual-pages.yml` GitHub workflow.' \
++ -- hugo.yml
+ - name: prepare worktree
+ if: steps.commit.outputs.result != ''
+ run: git sparse-checkout disable
@@ .github/workflows/update-git-version-and-manual-pages.yml (new)
+ - name: commit manual pages
+ if: steps.commit.outputs.result != ''
+ run: |
-+ git add -A _generated-asciidoc data/docs.yml content/docs &&
++ git add -A external/docs &&
+ git \
+ -c user.name=${{ github.actor }} \
+ -c user.email=${{ github.actor }}@noreply.github.com \
-+ commit -m "Update manual pages (${{ steps.commit.outputs.result }})"
++ commit -m "Update manual pages (${{ steps.commit.outputs.result }})" \
++ -m 'Updated via the `update-git-version-and-manual-pages.yml` GitHub workflow.'
+ - name: verify that there are no uncommitted changes
+ run: |
+ git update-index --refresh &&
127: 15a7705ad ! 127: 93af22a96 update-manual-pages: optionally force a complete rebuild
@@ .github/workflows/update-git-version-and-manual-pages.yml: name: Synchronize wit
# check daily for updates
- cron: '37 17 * * *'
@@ .github/workflows/update-git-version-and-manual-pages.yml: jobs:
- -c user.email=${{ github.actor }}@noreply.github.com \
- commit -m "Update git-version ($version)" -- hugo.yml
+ -m 'Updated via the `update-git-version-and-manual-pages.yml` GitHub workflow.' \
+ -- hugo.yml
- name: prepare worktree
- if: steps.commit.outputs.result != ''
-+ if: steps.commit.outputs.result != '' || inputs.force-rebuild
++ if: steps.commit.outputs.result != '' || inputs.force-rebuild == true
run: git sparse-checkout disable
- name: clone git.git
- if: steps.commit.outputs.result != ''
-+ if: steps.commit.outputs.result != '' || inputs.force-rebuild
++ if: steps.commit.outputs.result != '' || inputs.force-rebuild == true
run: git clone --bare https://github.com/git/git '${{ runner.temp }}/git'
- name: update manual pages
- if: steps.commit.outputs.result != ''
- run: bundle exec ruby script/update-docs.rb '${{ runner.temp }}/git' en
-+ if: steps.commit.outputs.result != '' || inputs.force-rebuild
++ if: steps.commit.outputs.result != '' || inputs.force-rebuild == true
+ run: |
-+ test false = '${{ inputs.force-rebuild }}' || export RERUN=true
++ if test true = '${{ inputs.force-rebuild }}'
++ then
++ export RERUN=true
++ fi
+ bundle exec ruby script/update-docs.rb '${{ runner.temp }}/git' en
- name: commit manual pages
- if: steps.commit.outputs.result != ''
+ id: manual-pages
-+ if: steps.commit.outputs.result != '' || inputs.force-rebuild
++ if: steps.commit.outputs.result != '' || inputs.force-rebuild == true
run: |
- git add -A _generated-asciidoc data/docs.yml content/docs &&
-+ if test false != '${{ inputs.force-rebuild }}' && git diff-index --cached --quiet HEAD --
+ git add -A external/docs &&
++ if test true = '${{ inputs.force-rebuild }}' && git diff-index --cached --quiet HEAD --
+ then
+ echo '::notice::A manual pages rebuild was requested but resulted in no changes' >&2
+ exit 0
@@ .github/workflows/update-git-version-and-manual-pages.yml: jobs:
git \
-c user.name=${{ github.actor }} \
-c user.email=${{ github.actor }}@noreply.github.com \
-- commit -m "Update manual pages (${{ steps.commit.outputs.result }})"
-+ commit -m "Update manual pages (${version:-manually forced rebuild})" &&
+- commit -m "Update manual pages (${{ steps.commit.outputs.result }})" \
+- -m 'Updated via the `update-git-version-and-manual-pages.yml` GitHub workflow.'
++ commit -m "Update manual pages (${version:-manually forced rebuild})" \
++ -m 'Updated via the `update-git-version-and-manual-pages.yml` GitHub workflow.' &&
+ echo "result=modified" >>$GITHUB_OUTPUT
- name: verify that there are no uncommitted changes
run: |
128: 21f13a6ef ! 128: 9ccb08bb2 Add a GitHub workflow to deploy `gh-pages` to GitHub Pages
@@ .github/workflows/deploy.yml (new)
+ name: github-pages
+ url: ${{ steps.deploy.outputs.url }}
+ steps:
-+ - uses: actions/checkout@v3
++ - uses: actions/checkout@v4
+ - name: deploy to GitHub Pages
+ id: deploy
+ uses: ./.github/actions/deploy-to-github-pages
129: 6a53852f0 ! 129: ac51259a9 Add a GitHub workflow to update the translated manual pages regularly
@@ .github/workflows/update-translated-manual-pages.yml (new)
+ check-for-updates:
+ runs-on: ubuntu-latest
+ steps:
-+ - uses: actions/checkout@v3
++ - uses: actions/checkout@v4
+ with:
+ sparse-checkout: |
-+ _sync_state
++ external/docs/sync
+ script
-+ - uses: actions/github-script@v6
++ - uses: actions/github-script@v7
+ id: get-pending
+ with:
+ script: |
@@ .github/workflows/update-translated-manual-pages.yml (new)
+ up-to-date: ${{ steps.get-pending.outputs.result }}
+ update-translated-manual-pages:
+ needs: [check-for-updates]
-+ if: inputs.force-rebuild || needs.check-for-updates.outputs.up-to-date == 'false'
++ if: inputs.force-rebuild == true || needs.check-for-updates.outputs.up-to-date == 'false'
+ runs-on: ubuntu-latest
+ permissions:
+ contents: write # to push changes (if any)
@@ .github/workflows/update-translated-manual-pages.yml (new)
+ name: github-pages
+ url: ${{ steps.deploy.outputs.url }}
+ steps:
-+ - uses: actions/checkout@v3
++ - uses: actions/checkout@v4
+ - name: ruby setup
+ uses: ruby/setup-ruby@v1
+ with:
@@ .github/workflows/update-translated-manual-pages.yml (new)
+ run: git clone --bare https://github.com/jnavila/git-html-l10n '${{ runner.temp }}/git-html-l10n'
+ - name: update translated manual pages
+ run: |
-+ test false = '${{ inputs.force-rebuild }}' || export RERUN=true
++ if test true = '${{ inputs.force-rebuild }}'
++ then
++ export RERUN=true
++ fi
+ bundle exec ruby script/update-docs.rb '${{ runner.temp }}/git-html-l10n' l10n
+ - name: commit translated manual pages
+ id: manual-pages
+ run: |
-+ git -C '${{ runner.temp }}/git-html-l10n' rev-parse HEAD >_sync_state/git-html-l10n.sha &&
-+ git add _sync_state/git-html-l10n.sha &&
++ mkdir -p external/docs/sync &&
++ git -C '${{ runner.temp }}/git-html-l10n' rev-parse HEAD >external/docs/sync/git-html-l10n.sha &&
++ git add external/docs/sync/git-html-l10n.sha &&
+
-+ git add -A _generated-asciidoc/ data/docs.yml content/docs &&
-+ if test false != '${{ inputs.force-rebuild }}' && git diff-index --cached --quiet HEAD --
++ git add -A external/docs &&
++ if test true = '${{ inputs.force-rebuild }}' && git diff-index --cached --quiet HEAD --
+ then
+ echo '::notice::Rebuild of the translated manual pages was requested but resulted in no changes' >&2
+ exit 0
@@ .github/workflows/update-translated-manual-pages.yml (new)
+ git \
+ -c user.name=${{ github.actor }} \
+ -c user.email=${{ github.actor }}@noreply.github.com \
-+ commit -m "Update translated manual pages" &&
++ commit -m "Update translated manual pages" \
++ -m 'Updated via the `update-translated-manual-pages.yml` GitHub workflow.' &&
+ echo "result=modified" >>$GITHUB_OUTPUT
+ - name: verify that there are no uncommitted changes
+ run: |
@@ script/ci-helper.js: const getPendingBookUpdates = async (octokit, forceRebuild)
+const areTranslatedManualPagesUpToDate = async (octokit) => {
+ try {
-+ const localSha = await getFileContents(`_sync_state/git-html-l10n.sha`)
++ const localSha = await getFileContents(`external/docs/sync/git-html-l10n.sha`)
+
+ const [owner, repo] = 'jnavila/git-html-l10n'.split('/')
+ const { data: { default_branch: remoteDefaultBranch } } =
-: --------- > 130: 28b147af1 deploy: check for broken links
-: --------- > 131: c9dae6afc deploy(linkcheck): deal with stray "secondary rate limits"
130: bff0ab61c ! 132: 2b63bbb71 Adjust `ARCHITECTURE.md` to the Hugo reality
@@ Commit message
https://github.com/git/git-scm.com/issues/942.
However, I aborted that migration when it turned out that Jekyll
- required 20 minutes to process the files while Hugo spent less than half
- a minute on them.
+ required 20 minutes to process the files while Hugo spent less than
+ half a minute on them.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
@@ ARCHITECTURE.md
+ - original content from this repository
- community book content brought in from https://github.com/progit;
- see the `lib/tasks/book2.rake` file.
-@@ ARCHITECTURE.md: The content is a mix of:
- - manpages from releases of the git project, imported and formatted
- via asciidoctor; see the `lib/tasks/index.rake` task.
+- see the `lib/tasks/book2.rake` file.
++ see the `script/update-book2.rb` and `script/book.rb` files.
-+To deploy to GitHub Pages, it is necessary to turn off the default setting to
-+"publish from a branch" and instead change the setting to "publish with a
-+custom GitHub Actions workflow":
-+https://docs.github.com/en/pages/getting-started-with-github-pages/configuring-a-publishing-source-for-your-github-pages-site#publishing-with-a-custom-github-actions-workflow
+- - manpages from releases of the git project, imported and formatted
+- via asciidoctor; see the `lib/tasks/index.rake` task.
++ The content is pre-rendered and tracked in the `external/book/` directory
++ tree.
+
++ - manual pages from releases of the git project, imported and formatted via
++ AsciiDoctor, and translated versions of the manual pages from
++ https://github.com/jnavila/git-manpages-l10n/ (which itself contains
++ pre-rendered pages from https://github.com/jnavila/git-manpages-l10n/); see
++ the `script/update-docs.rb` file.
-## Heroku
-+## Non-static parts
++ The pre-rendered pages are tracked in the `external/docs/` directory tree.
-The app itself is served by Heroku. The app name is `git-scm` (so you
-can visit it directly as https://git-scm.herokuapp.com). The site is
-owned by the git-scm.com team. If you want to be involved in managing
-uptime/deploys/etc, you'll need a Heroku account and request to be added
-to that team.
++To deploy to GitHub Pages, it is necessary to turn off the default setting to
++"publish from a branch" and instead change the setting to "publish with a
++custom GitHub Actions workflow":
++https://docs.github.com/en/pages/getting-started-with-github-pages/configuring-a-publishing-source-for-your-github-pages-site#publishing-with-a-custom-github-actions-workflow
++With this change, the site can be tested in the fork by pushing to the
++`gh-pages` branch (which will trigger the `deploy.yml` workflow) and then
++navigating to https://git-scm.<user>.github.io/.
+
+-We use a few Heroku add-ons:
++## Non-static parts
+
+- - Bonsai elasticsearch (see below)
+While the site consists mostly of static content, there are a couple of
+parts that are sort of dynamic.
--We use a few Heroku add-ons:
+- - Heroku Postgres as the database
+The search is implemented client-side, via [Pagefind](https://pagefind.app/).
-- - Bonsai elasticsearch (see below)
+- - Heroku Redis for rails caching
+A few scheduled GitHub workflows keep the content up to date:
-- - Heroku Postgres as the database
+- - Heroku scheduler for cron jobs
+ - `update-git-version-and-manual-pages` and `update-download-data` (pick
+ up newly released git versions)
-- - Heroku Redis for rails caching
+-The nightly scheduled jobs are:
+ - `update-translated-manual-pages` (fetch and format translated manual
+ pages from the jnavila/git-html-l10n repository)
-- - Heroku scheduler for cron jobs
--
--The nightly scheduled jobs are:
--
- - `rake downloads` (pick up newly released git versions)
-
- - `rake preindex` (pull in and format manpages for released git
@@ ARCHITECTURE.md: The content is a mix of:
-dyno. So we have Cloudflare sitting in front of it, aggressively caching
-everything. That also should make the site faster to serve to regions
-far away from Heroku's servers.
+-
+-The Cloudflare setup is mostly pretty simple:
+These workflows are also marked as `workflow_dispatch`, i.e. they can be run
+manually (e.g. to update the download links just after Git for Windows
+published a new release).
--The Cloudflare setup is mostly pretty simple:
--
- - they serve DNS for the whole domain (that's where they insert the CDN
- magic)
-
@@ ARCHITECTURE.md: The content is a mix of:
+`deploy` GitHub workflow.
+Note that some of the formatting of manual pages and book content happens
-+when they are imported by the GitHub workflows. Therefore, after fixing some
-+formatting, these workflows may need the force-rebuild flag to be toggled (see
-+the individual workflows for details).
++when they are imported by the GitHub workflows. Therefore, whenever there are
++changes to the scripts/workflows/automation that affect formatting, these
++workflows may need to be triggered using the force-rebuild flag to be toggled
++(see the individual workflows for details).
## DNS
@@ ARCHITECTURE.md: The content is a mix of:
Note that we own both git-scm.com and git-scm.org; the latter redirects
to the former.
-@@ ARCHITECTURE.md: The site mostly just runs without intervention:
- - code merged to `main` is auto-deployed
+-
+ ## Manual Intervention
+
+ The site mostly just runs without intervention:
+
+- - code merged to `main` is auto-deployed
++ - code merged to `gh-pages` is auto-deployed
- - new git versions are detected daily and manpages and download links
+ - new git versions are detected daily and manual pages and download links
@@ ARCHITECTURE.md: The site mostly just runs without intervention:
- `lib/tasks/book2.rake`
+ `script/book.rb`
- - forced re-imports of content (e.g., a formatting fix to imported
+- - forced re-imports of content (e.g., a formatting fix to imported
- manpages) must be triggered manually
-+ manual pages) must be triggered manually with `force-rebuild` toggled
++ - forced re-imports of content (e.g., when fixing formatting in the
++ imported manual pages) must be triggered manually with `force-rebuild`
++ toggled
-: --------- > 133: e91c406fa Add Playwright-based UI tests
-: --------- > 134: a43cdff2c playwright: add a few platform-specific tests
-: --------- > 135: f6b7ccd21 playwright: let the UI tests pass with the Rails app
-: --------- > 136: e7db6d766 playwright: add a regression test for the `git remote renom` issue
-: --------- > 137: 87609ac77 playwright: add a GitHub workflow to run the tests
-: --------- > 138: 5facfdaee playwright: auto-start a web server for the special URL localhost:5000
-: --------- > 139: b54046816 playwright: verify that URLs with question marks work
-: --------- > 140: 4210b9bba ci: run the Playwright tests in every Pull Request
-: --------- > 141: ffb957b5f ci: run the Playwright tests on every deployment
Ciao,
Johannes
^ permalink raw reply [flat|nested] 15+ messages in thread