Git pro mě/Repozitář mluvících ptáků

Tohle je postup vytvoření historie změn pro repozitář mluvících ptáků jistého očarovaného lesa. Postup popíšu krok po kroku. Protože jde ale o historii, ne o kód, vystavím historii na již existujících souborech. Je to drobný detail; při opravdovém psaní kódu by historie nejspíš vypadala stejně, jen kód by vznikal postupně.

Výpisy příkazů se často opakují a jsou dlouhé. Je to proto, že jsem zaznamenával příkazy (včetně výpisů) tak, jak jsem historii tvořil. Často se ujišťuji o stavu repozitáře a často výpisy příkazů jen prolétnu, než abych je četl.

A jak vypadá historie repozitáře?

$ git clone https://git.sr.ht/~qeef/enchanted-forest
Cloning into 'enchanted-forest'...
remote: Enumerating objects: 4, done.
remote: Total 4 (delta 0), reused 0 (delta 0), pack-reused 4
Receiving objects: 100% (4/4), done.
$ cd enchanted-forest/
$ git log --oneline --graph --decorate --all
*   48c405d (HEAD -> master, tag: v0.2.0, origin/master, origin/HEAD) Merge branch 'add-forests'
|\
| * 19acdad Add Sekei Forest
| * 758d3f5 Add Becekew Forest
| * 5745778 Add Bekimet Forest
| | * b381691 (tag: v0.1.0) Merge branch 'add-birds'
| |/|
|/| |
| | * 3839a47 Add talking birds
| |/
| * 6af3ac3 Add tests
|/
| * 4a10200 (tag: v1-add-birds) Add tests
| * bf4e413 Add docstrings
| * 32d4416 Add talking birds
|/
* 2b8558d Add license, readme

Historie je trochu komplikovanější, protože jsem uchovával (pomocí značek v1-add-birds a v0.1.0) i historii, kterou vlastně nechci. "Čistá" historie repozitáře by byla bez v1-add-birds a v0.1.0 by byl místo v0.2.0:

$ git log --oneline --graph --decorate --all
*   48c405d (HEAD -> master, tag: v0.1.0, origin/master) Merge branch 'add-forests'
|\
| * 19acdad Add Sekei Forest
| * 758d3f5 Add Becekew Forest
| * 5745778 Add Bekimet Forest
| * 6af3ac3 Add tests
|/
* 2b8558d Add license, readme

Inicializace repozitáře editovat

Před zaznamenáváním historie je potřeba připravit repozitář pro sledování změn:

$ git init
hint: Using 'master' as the name for the initial branch. This default branch name
hint: is subject to change. To configure the initial branch name to use in all
hint: of your new repositories, which will suppress this warning, call:
hint:
hint:   git config --global init.defaultBranch <name>
hint:
hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and
hint: 'development'. The just-created branch can be renamed via this command:
hint:
hint:   git branch -m <name>
Initialized empty Git repository in /full/path/to/enchanted-forest/.git/

a nastavit základní informace o autorovi změn:

$ git config user.email 'foo@bar.buzz'
$ git config --global user.name 'Foo Bar'

Přidání licence a readme editovat

Jako první přidám soubory s licencí a readme. Tady nevymýšlím žádné složitosti.

Často, a to i v dalších sekcích, kontroluji repozitář pomocí příkazů git status, git diff --cached a git logg (což je alias).

$ git status
On branch master

No commits yet

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        LICENSE
        README
        enchanted-forest.scm

nothing added to commit but untracked files present (use "git add" to track)
$ git add LICENSE README
$ git status
On branch master

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
        new file:   LICENSE
        new file:   README

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        enchanted-forest.scm
$ git diff --cached
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..ca9b17b
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2022 Foo Bar
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README b/README
new file mode 100644
index 0000000..65b23c5
--- /dev/null
+++ b/README
@@ -0,0 +1 @@
+This is implementation of https://wiki.xxiivv.com/site/logic.html

Pokud jsem spokojený s výsledkem příkazu git diff --cached, přidám změnu do historie:

$ git commit -m'Add license, readme'
[master (root-commit) 2b8558d] Add license, readme
 2 files changed, 20 insertions(+)
 create mode 100644 LICENSE
 create mode 100644 README
$ git status
On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)
        enchanted-forest.scm

nothing added to commit but untracked files present (use "git add" to track)

Prohlédnu a zkontroluji historii změn:

$ git log
commit 2b8558d17f2b3cbd29896d8b92e5f8ba68bf8fca (HEAD -> master, origin/master)
Author: Foo Bar <foo@bar.buzz>
Date:   Sat Sep 17 21:09:05 2022 +0200

    Add license, readme
$ git show
commit 2b8558d17f2b3cbd29896d8b92e5f8ba68bf8fca (HEAD -> master, origin/master)
Author: Foo Bar <foo@bar.buzz>
Date:   Sat Sep 17 21:09:05 2022 +0200

    Add license, readme

diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..ca9b17b
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2022 Foo Bar
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README b/README
new file mode 100644
index 0000000..65b23c5
--- /dev/null
+++ b/README
@@ -0,0 +1 @@
+This is implementation of https://wiki.xxiivv.com/site/logic.html

Přidání mluvících ptáků editovat

Přidání mluvících ptáků udělám složitější, než bych musel. Můžu tak ukázat několik zajímavých postupů: historii změn vytvořím v nové větvi, přidám jen část souboru s kódem a výsledek označím.

Nejprve vytvoření a použití nové větve:

$ git branch
* master
$ git branch add-birds
$ git branch
  add-birds
* master
$ git checkout add-birds
Switched to branch 'add-birds'
$ git branch
* add-birds
  master
$ git status
On branch add-birds
Untracked files:
  (use "git add <file>..." to include in what will be committed)
        enchanted-forest.scm

nothing added to commit but untracked files present (use "git add" to track)

Soubor enchanted-forest.scm nejprve připravím na to, že bude přidaný do historie. To dělám kvůli tomu, aby fungoval příkaz git add -p, který na základě toho, co již v historii je a toho, co ještě v historii není, dovolí vybrat pouze některé části změn. Bez následujícícho příkazu by příkaz git add -p vrátil No changes. a nic by se nestalo.

git add -N enchanted-forest.scm
$ git status
On branch add-birds
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        new file:   enchanted-forest.scm

no changes added to commit (use "git add" and/or "git commit -a")

Přidám pouze změny, které přidat chci. Takže procedury jednotlivých mluvících ptáků. Nejprve kompletní výpis změn:

$ git add -p
diff --git a/enchanted-forest.scm b/enchanted-forest.scm
new file mode 100644
index 0000000..7bf1bb5
--- /dev/null
+++ b/enchanted-forest.scm
@@ -0,0 +1,85 @@
+;;;; The Bekimet Forest
+;;; Mockingbird -- repeats the first word.
+(define (M li)
+  (append (list (car li) (car li)) (cdr li)))
+;;; Kite -- discards the first word.
+(define (KI li)
+  (cdr li))
+;;; Thrush -- swaps the first and the second word.
+(define (T li)
+  (append (list (cadr li) (car li)) (cddr li)))
+;;;; The Becekew Forest
+;;; Warbler -- repeats the second word.
+(define (W li)
+  (append (list (car li) (cadr li) (cadr li)) (cddr li)))
+;;; Kestrel -- discards the second word.
+(define (K li)
+  (append (list (car li)) (cddr li)))
+;;; Cardinal -- swaps the second and the third words.
+(define (C li)
+  (append (list (car li) (caddr li) (cadr li)) (cdddr li)))
+;;; Bluebird -- takes three words, and parethesize the third into the second.
+(define (B li)
+  (list (car li) (cdr li)))
+;;;; The Sekei Forest
+;;; Idiot -- hear word, response the same word.
+(define (I w)
+  w)
+;;; Kestrel -- see the Becekew Forest.
+;;; Starling -- apply the first and second words to the last one, then apply the first result to the second one.
+(define (S li)
+  `(,(car li) ,(caddr li) (,(cadr li) ,(caddr li))))
+(define (talk-you-birds)
+  (display "(M '(x y z))")
+  (display " : ")
+  (display (M '(x y z)))
+  (display " =? (x x y z)")
+  (newline)
+
+  (display "(KI '(x y z))")
+  (display " : ")
+  (display (KI '(x y z)))
+  (display " =? (y z)")
+  (newline)
+
+  (display "(T '(x y z))")
+  (display " : ")
+  (display (T '(x y z)))
+  (display " =? (y x z)")
+  (newline)
+
+  (display "(W '(x y z))")
+  (display " : ")
+  (display (W '(x y z)))
+  (display " =? (x y y z)")
+  (newline)
+
+  (display "(K '(x y z))")
+  (display " : ")
+  (display (K '(x y z)))
+  (display " =? (x z)")
+  (newline)
+
+  (display "(C '(x y z))")
+  (display " : ")
+  (display (C '(x y z)))
+  (display " =? (x z y)")
+  (newline)
+
+  (display "(B '(x y z))")
+  (display " : ")
+  (display (B '(x y z)))
+  (display " =? (x (y z))")
+  (newline)
+
+  (display "(I '(x))")
+  (display " : ")
+  (display (I '(x)))
+  (display " =? (x)")
+  (newline)
+
+  (display "(S '(x y z))")
+  (display " : ")
+  (display (S '(x y z)))
+  (display " =? (x z (y z))")
+  (newline))
(1/1) Stage this hunk [y,n,q,a,d,e,?]? e

Z nabídky si vyberu "e" pro manuální editaci. Otevře se textový editor obsahující:

# Manual hunk edit mode -- see bottom for a quick guide.
@@ -0,0 +1,85 @@
+;;;; The Bekimet Forest
+;;; Mockingbird -- repeats the first word.
+(define (M li)
+  (append (list (car li) (car li)) (cdr li)))
+;;; Kite -- discards the first word.
+(define (KI li)
+  (cdr li))
+;;; Thrush -- swaps the first and the second word.
+(define (T li)
+  (append (list (cadr li) (car li)) (cddr li)))
+;;;; The Becekew Forest
+;;; Warbler -- repeats the second word.
+(define (W li)
+  (append (list (car li) (cadr li) (cadr li)) (cddr li)))
+;;; Kestrel -- discards the second word.
+(define (K li)
+  (append (list (car li)) (cddr li)))
+;;; Cardinal -- swaps the second and the third words.
+(define (C li)
+  (append (list (car li) (caddr li) (cadr li)) (cdddr li)))
+;;; Bluebird -- takes three words, and parethesize the third into the second.
+(define (B li)
+  (list (car li) (cdr li)))
+;;;; The Sekei Forest
+;;; Idiot -- hear word, response the same word.
+(define (I w)
+  w)
+;;; Kestrel -- see the Becekew Forest.
+;;; Starling -- apply the first and second words to the last one, then apply the first result to the second one.
+(define (S li)
+  `(,(car li) ,(caddr li) (,(cadr li) ,(caddr li))))
+(define (talk-you-birds)
+  (display "(M '(x y z))")
+  (display " : ")
+  (display (M '(x y z)))
+  (display " =? (x x y z)")
+  (newline)
+
+  (display "(KI '(x y z))")
+  (display " : ")
+  (display (KI '(x y z)))
+  (display " =? (y z)")
+  (newline)
+
+  (display "(T '(x y z))")
+  (display " : ")
+  (display (T '(x y z)))
+  (display " =? (y x z)")
+  (newline)
+
+  (display "(W '(x y z))")
+  (display " : ")
+  (display (W '(x y z)))
+  (display " =? (x y y z)")
+  (newline)
+
+  (display "(K '(x y z))")
+  (display " : ")
+  (display (K '(x y z)))
+  (display " =? (x z)")
+  (newline)
+
+  (display "(C '(x y z))")
+  (display " : ")
+  (display (C '(x y z)))
+  (display " =? (x z y)")
+  (newline)
+
+  (display "(B '(x y z))")
+  (display " : ")
+  (display (B '(x y z)))
+  (display " =? (x (y z))")
+  (newline)
+
+  (display "(I '(x))")
+  (display " : ")
+  (display (I '(x)))
+  (display " =? (x)")
+  (newline)
+
+  (display "(S '(x y z))")
+  (display " : ")
+  (display (S '(x y z)))
+  (display " =? (x z (y z))")
+  (newline))
# ---
# To remove '-' lines, make them ' ' lines (context).
# To remove '+' lines, delete them.
# Lines starting with # will be removed.
# 
# If the patch applies cleanly, the edited hunk will immediately be
# marked for staging.
# If it does not apply cleanly, you will be given an opportunity to
# edit again.  If all lines of the hunk are removed, then the edit is
# aborted and the hunk is left unchanged.

Upravím obsah souboru na:

+(define (M li)
+  (append (list (car li) (car li)) (cdr li)))
+(define (KI li)
+  (cdr li))
+(define (T li)
+  (append (list (cadr li) (car li)) (cddr li)))
+(define (W li)
+  (append (list (car li) (cadr li) (cadr li)) (cddr li)))
+(define (K li)
+  (append (list (car li)) (cddr li)))
+(define (C li)
+  (append (list (car li) (caddr li) (cadr li)) (cdddr li)))
+(define (B li)
+  (list (car li) (cdr li)))
+(define (I w)
+  w)
+(define (S li)
+  `(,(car li) ,(caddr li) (,(cadr li) ,(caddr li))))

A nakonec uložím a zavřu (:wq ve vim). Tím jsem připravil změny, které chci, na zápis do historie. Které že to jsou zkontroluji příkazem:

$ git diff --cached
diff --git a/enchanted-forest.scm b/enchanted-forest.scm
new file mode 100644
index 0000000..ac2f069
--- /dev/null
+++ b/enchanted-forest.scm
@@ -0,0 +1,18 @@
+(define (M li)
+  (append (list (car li) (car li)) (cdr li)))
+(define (KI li)
+  (cdr li))
+(define (T li)
+  (append (list (cadr li) (car li)) (cddr li)))
+(define (W li)
+  (append (list (car li) (cadr li) (cadr li)) (cddr li)))
+(define (K li)
+  (append (list (car li)) (cddr li)))
+(define (C li)
+  (append (list (car li) (caddr li) (cadr li)) (cdddr li)))
+(define (B li)
+  (list (car li) (cdr li)))
+(define (I w)
+  w)
+(define (S li)
+  `(,(car li) ,(caddr li) (,(cadr li) ,(caddr li))))

pak tyto změny do historie přidám:

$ git commit -m'Add talking birds'
[add-birds 32d4416] Add talking birds
 1 file changed, 18 insertions(+)
 create mode 100644 enchanted-forest.scm

a nakonec se podívám, jak historie repozitáře právě vypadá:

$ git log --oneline --graph --decorate --all
* 32d4416 (HEAD -> add-birds) Add talking birds
* 2b8558d (origin/master, master) Add license, readme

K tomu, jak historie repozitáře právě vypadá: první změna (2b8558d Add license, readme) zaznamenává přidání licence a readme. Je vidět, že je ve větvi master. Druhá změna (32d4416 Add talking birds) zaznamenává přidání procedur mluvících ptáků. Ta je ve větvi add-birds, do které přidávám změny související s mluvícími ptáky.

Pak přidám ještě dokumentaci procedur mluvících ptáků, ale nechci přidávat proceduru pro testování.

$ git add -p
diff --git a/enchanted-forest.scm b/enchanted-forest.scm
index ac2f069..7bf1bb5 100644
--- a/enchanted-forest.scm
+++ b/enchanted-forest.scm
@@ -1,18 +1,85 @@
+;;;; The Bekimet Forest
+;;; Mockingbird -- repeats the first word.
 (define (M li)
   (append (list (car li) (car li)) (cdr li)))
+;;; Kite -- discards the first word.
 (define (KI li)
   (cdr li))
+;;; Thrush -- swaps the first and the second word.
 (define (T li)
   (append (list (cadr li) (car li)) (cddr li)))
+;;;; The Becekew Forest
+;;; Warbler -- repeats the second word.
 (define (W li)
   (append (list (car li) (cadr li) (cadr li)) (cddr li)))
+;;; Kestrel -- discards the second word.
 (define (K li)
   (append (list (car li)) (cddr li)))
+;;; Cardinal -- swaps the second and the third words.
 (define (C li)
   (append (list (car li) (caddr li) (cadr li)) (cdddr li)))
+;;; Bluebird -- takes three words, and parethesize the third into the second.
 (define (B li)
   (list (car li) (cdr li)))
+;;;; The Sekei Forest
+;;; Idiot -- hear word, response the same word.
 (define (I w)
   w)
+;;; Kestrel -- see the Becekew Forest.
+;;; Starling -- apply the first and second words to the last one, then apply the first result to the second one.
 (define (S li)
   `(,(car li) ,(caddr li) (,(cadr li) ,(caddr li))))
+(define (talk-you-birds)
+  (display "(M '(x y z))")
+  (display " : ")
+  (display (M '(x y z)))
+  (display " =? (x x y z)")
+  (newline)
+
+  (display "(KI '(x y z))")
+  (display " : ")
+  (display (KI '(x y z)))
+  (display " =? (y z)")
+  (newline)
+
+  (display "(T '(x y z))")
+  (display " : ")
+  (display (T '(x y z)))
+  (display " =? (y x z)")
+  (newline)
+
+  (display "(W '(x y z))")
+  (display " : ")
+  (display (W '(x y z)))
+  (display " =? (x y y z)")
+  (newline)
+
+  (display "(K '(x y z))")
+  (display " : ")
+  (display (K '(x y z)))
+  (display " =? (x z)")
+  (newline)
+
+  (display "(C '(x y z))")
+  (display " : ")
+  (display (C '(x y z)))
+  (display " =? (x z y)")
+  (newline)
+
+  (display "(B '(x y z))")
+  (display " : ")
+  (display (B '(x y z)))
+  (display " =? (x (y z))")
+  (newline)
+
+  (display "(I '(x))")
+  (display " : ")
+  (display (I '(x)))
+  (display " =? (x)")
+  (newline)
+
+  (display "(S '(x y z))")
+  (display " : ")
+  (display (S '(x y z)))
+  (display " =? (x z (y z))")
+  (newline))
(1/1) Stage this hunk [y,n,q,a,d,s,e,?]? s

Tentokrát zvolím "s", pro rozdělení změn (split). Pak přidám (y) ty změny, které chci:

Split into 10 hunks.
@@ -1,2 +1,4 @@
+;;;; The Bekimet Forest
+;;; Mockingbird -- repeats the first word.
 (define (M li)
   (append (list (car li) (car li)) (cdr li)))
(1/10) Stage this hunk [y,n,q,a,d,j,J,g,/,e,?]? y
@@ -1,4 +3,5 @@
 (define (M li)
   (append (list (car li) (car li)) (cdr li)))
+;;; Kite -- discards the first word.
 (define (KI li)
   (cdr li))
(2/10) Stage this hunk [y,n,q,a,d,K,j,J,g,/,e,?]? y
@@ -3,4 +6,5 @@
 (define (KI li)
   (cdr li))
+;;; Thrush -- swaps the first and the second word.
 (define (T li)
   (append (list (cadr li) (car li)) (cddr li)))
(3/10) Stage this hunk [y,n,q,a,d,K,j,J,g,/,e,?]? y
@@ -5,4 +9,6 @@
 (define (T li)
   (append (list (cadr li) (car li)) (cddr li)))
+;;;; The Becekew Forest
+;;; Warbler -- repeats the second word.
 (define (W li)
   (append (list (car li) (cadr li) (cadr li)) (cddr li)))
(4/10) Stage this hunk [y,n,q,a,d,K,j,J,g,/,e,?]? y
@@ -7,4 +13,5 @@
 (define (W li)
   (append (list (car li) (cadr li) (cadr li)) (cddr li)))
+;;; Kestrel -- discards the second word.
 (define (K li)
   (append (list (car li)) (cddr li)))
(5/10) Stage this hunk [y,n,q,a,d,K,j,J,g,/,e,?]? y
@@ -9,4 +16,5 @@
 (define (K li)
   (append (list (car li)) (cddr li)))
+;;; Cardinal -- swaps the second and the third words.
 (define (C li)
   (append (list (car li) (caddr li) (cadr li)) (cdddr li)))
(6/10) Stage this hunk [y,n,q,a,d,K,j,J,g,/,e,?]? y
@@ -11,4 +19,5 @@
 (define (C li)
   (append (list (car li) (caddr li) (cadr li)) (cdddr li)))
+;;; Bluebird -- takes three words, and parethesize the third into the second.
 (define (B li)
   (list (car li) (cdr li)))
(7/10) Stage this hunk [y,n,q,a,d,K,j,J,g,/,e,?]? y
@@ -13,4 +22,6 @@
 (define (B li)
   (list (car li) (cdr li)))
+;;;; The Sekei Forest
+;;; Idiot -- hear word, response the same word.
 (define (I w)
   w)
(8/10) Stage this hunk [y,n,q,a,d,K,j,J,g,/,e,?]? y
@@ -15,4 +26,6 @@
 (define (I w)
   w)
+;;; Kestrel -- see the Becekew Forest.
+;;; Starling -- apply the first and second words to the last one, then apply the first result to the second one.
 (define (S li)
   `(,(car li) ,(caddr li) (,(cadr li) ,(caddr li))))
(9/10) Stage this hunk [y,n,q,a,d,K,j,J,g,/,e,?]? y

a nepřidám (n) ty změny, které nechci:

@@ -17,2 +30,56 @@
 (define (S li)
   `(,(car li) ,(caddr li) (,(cadr li) ,(caddr li))))
+(define (talk-you-birds)
+  (display "(M '(x y z))")
+  (display " : ")
+  (display (M '(x y z)))
+  (display " =? (x x y z)")
+  (newline)
+
+  (display "(KI '(x y z))")
+  (display " : ")
+  (display (KI '(x y z)))
+  (display " =? (y z)")
+  (newline)
+
+  (display "(T '(x y z))")
+  (display " : ")
+  (display (T '(x y z)))
+  (display " =? (y x z)")
+  (newline)
+
+  (display "(W '(x y z))")
+  (display " : ")
+  (display (W '(x y z)))
+  (display " =? (x y y z)")
+  (newline)
+
+  (display "(K '(x y z))")
+  (display " : ")
+  (display (K '(x y z)))
+  (display " =? (x z)")
+  (newline)
+
+  (display "(C '(x y z))")
+  (display " : ")
+  (display (C '(x y z)))
+  (display " =? (x z y)")
+  (newline)
+
+  (display "(B '(x y z))")
+  (display " : ")
+  (display (B '(x y z)))
+  (display " =? (x (y z))")
+  (newline)
+
+  (display "(I '(x))")
+  (display " : ")
+  (display (I '(x)))
+  (display " =? (x)")
+  (newline)
+
+  (display "(S '(x y z))")
+  (display " : ")
+  (display (S '(x y z)))
+  (display " =? (x z (y z))")
+  (newline))
(10/10) Stage this hunk [y,n,q,a,d,K,g,/,e,?]? n

Stav repozitáře je teď trochu schizofrení:

$ git status
On branch add-birds
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   enchanted-forest.scm

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   enchanted-forest.scm

Ale pokud se podívám na změny, které jsou připravené pro zápis do historie:

$ git diff --cached
diff --git a/enchanted-forest.scm b/enchanted-forest.scm
index ac2f069..5b390c7 100644
--- a/enchanted-forest.scm
+++ b/enchanted-forest.scm
@@ -1,18 +1,31 @@
+;;;; The Bekimet Forest
+;;; Mockingbird -- repeats the first word.
 (define (M li)
   (append (list (car li) (car li)) (cdr li)))
+;;; Kite -- discards the first word.
 (define (KI li)
   (cdr li))
+;;; Thrush -- swaps the first and the second word.
 (define (T li)
   (append (list (cadr li) (car li)) (cddr li)))
+;;;; The Becekew Forest
+;;; Warbler -- repeats the second word.
 (define (W li)
   (append (list (car li) (cadr li) (cadr li)) (cddr li)))
+;;; Kestrel -- discards the second word.
 (define (K li)
   (append (list (car li)) (cddr li)))
+;;; Cardinal -- swaps the second and the third words.
 (define (C li)
   (append (list (car li) (caddr li) (cadr li)) (cdddr li)))
+;;; Bluebird -- takes three words, and parethesize the third into the second.
 (define (B li)
   (list (car li) (cdr li)))
+;;;; The Sekei Forest
+;;; Idiot -- hear word, response the same word.
 (define (I w)
   w)
+;;; Kestrel -- see the Becekew Forest.
+;;; Starling -- apply the first and second words to the last one, then apply the first result to the second one.
 (define (S li)
   `(,(car li) ,(caddr li) (,(cadr li) ,(caddr li))))

a na změny, které připravené nejsou:

$ git diff
diff --git a/enchanted-forest.scm b/enchanted-forest.scm
index 5b390c7..7bf1bb5 100644
--- a/enchanted-forest.scm
+++ b/enchanted-forest.scm
@@ -29,3 +29,57 @@
 ;;; Starling -- apply the first and second words to the last one, then apply the first result to the second one.
 (define (S li)
   `(,(car li) ,(caddr li) (,(cadr li) ,(caddr li))))
+(define (talk-you-birds)
+  (display "(M '(x y z))")
+  (display " : ")
+  (display (M '(x y z)))
+  (display " =? (x x y z)")
+  (newline)
+
+  (display "(KI '(x y z))")
+  (display " : ")
+  (display (KI '(x y z)))
+  (display " =? (y z)")
+  (newline)
+
+  (display "(T '(x y z))")
+  (display " : ")
+  (display (T '(x y z)))
+  (display " =? (y x z)")
+  (newline)
+
+  (display "(W '(x y z))")
+  (display " : ")
+  (display (W '(x y z)))
+  (display " =? (x y y z)")
+  (newline)
+
+  (display "(K '(x y z))")
+  (display " : ")
+  (display (K '(x y z)))
+  (display " =? (x z)")
+  (newline)
+
+  (display "(C '(x y z))")
+  (display " : ")
+  (display (C '(x y z)))
+  (display " =? (x z y)")
+  (newline)
+
+  (display "(B '(x y z))")
+  (display " : ")
+  (display (B '(x y z)))
+  (display " =? (x (y z))")
+  (newline)
+
+  (display "(I '(x))")
+  (display " : ")
+  (display (I '(x)))
+  (display " =? (x)")
+  (newline)
+
+  (display "(S '(x y z))")
+  (display " : ")
+  (display (S '(x y z)))
+  (display " =? (x z (y z))")
+  (newline))

je to jasné. Připravené změny, tedy dokumentaci k procedurám mluvících ptáků, přidám potom příkazem:

$ git commit -m'Add docstrings'
[add-birds bf4e413] Add docstrings
 1 file changed, 13 insertions(+)

A nakonec přidám i proceduru pro testování:

$ git add enchanted-forest.scm
$ git commit -m'Add tests'
[add-birds 4a10200] Add tests
 1 file changed, 54 insertions(+)

Poté, co přidám poslední změnu si poznačím, kde jsem skončil:

$ git tag v1-add-birds

Jak vypadá stav repozitáře teď?

$ git status
On branch add-birds
nothing to commit, working tree clean

A historie repozitáře?

$ git log --oneline --graph --decorate --all
* 4a10200 (HEAD -> add-birds, tag: v1-add-birds) Add tests
* bf4e413 Add docstrings
* 32d4416 Add talking birds
* 2b8558d (origin/master, master) Add license, readme

Tady je vidět, že tři změny související s mluvícími ptáky (ve větvi add-birds) vychází z hlavní větve (master) a obsahují změny pro "přidání mluvících ptáků", "přidání dokumentace" a "přidání testů".

Navíc jsem historii, která odpovídá změnám ve větvi add-birds, opatřil značkou v1-add-birds. Rozdíl mezi větví (branch) a značkou (tag) je ten, že když jsem "na větvi" (git checkout add-birds), přidáním další změny větev posunu, takže nově přidaná změna (git commit) bude také součástí větve. To ale neplatí o značce (git checkout v1-add-birds). Přidáním nové změny značku nezměním a nová změna je tím pádem ztracená.

Přeskupení a oprava historie editovat

Vycházím z toho, že mám změny ve větvi add-birds, ale rozmyslel jsem si pořadí změn. Také jsem se rozhodl, že dokumentaci chci přidat přímo s kódem procedur.

Pro změnu historie použiji příkaz

$ git rebase -i master

který otevře textový editor, ve kterém původní obsah:

pick 32d4416 Add talking birds
pick bf4e413 Add docstrings
pick 4a10200 Add tests

# Rebase 2b8558d..4a10200 onto 2b8558d (3 commands)
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup <commit> = like "squash", but discard this commit's log message
# x, exec <command> = run command (the rest of the line) using shell
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop <commit> = remove commit
# l, label <label> = label current HEAD with a name
# t, reset <label> = reset HEAD to a label
# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
# .       create a merge commit using the original merge commit's
# .       message (or the oneline, if no original merge commit was
# .       specified). Use -c <commit> to reword the commit message.
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#

změním na:

pick 4a10200 Add tests
pick 32d4416 Add talking birds
f bf4e413 Add docstrings

což znamená, že změna obsahující testy bude první a potom bude následovat změna s přidáním procedur mluvících ptáků, do které bude začleněna dokumentace.

Protože 4a10200 Add tests předpokládá existenci souboru enchanted-forset.scm, ale ten po přeskládání změn neexistuje, dojde ke konfliktu a git nebude vědět, co s tím:

$ git rebase -i master
CONFLICT (modify/delete): enchanted-forest.scm deleted in HEAD and modified in 4a10200 (Add tests). Version 4a10200 (Add tests) of enchanted-forest.scm left in tree.
error: could not apply 4a10200... Add tests
Resolve all conflicts manually, mark them as resolved with
"git add/rm <conflicted_files>", then run "git rebase --continue".
You can instead skip this commit: run "git rebase --skip".
To abort and get back to the state before "git rebase", run "git rebase --abort".
Could not apply 4a10200... Add tests

Historie repozitáře v dané chvíli je:

$ git log --oneline --graph --decorate --all
* 4a10200 (tag: v1-add-birds, add-birds) Add tests
* bf4e413 Add docstrings
* 32d4416 Add talking birds
* 2b8558d (HEAD, origin/master, master) Add license, readme

a stav repozitáře je:

$ git status
interactive rebase in progress; onto 2b8558d
Last command done (1 command done):
   pick 4a10200 Add tests
Next commands to do (2 remaining commands):
   pick 32d4416 Add talking birds
   fixup bf4e413 Add docstrings
  (use "git rebase --edit-todo" to view and edit)
You are currently rebasing branch 'add-birds' on '2b8558d'.
  (fix conflicts and then run "git rebase --continue")
  (use "git rebase --skip" to skip this patch)
  (use "git rebase --abort" to check out the original branch)

Unmerged paths:
  (use "git restore --staged <file>..." to unstage)
  (use "git add/rm <file>..." as appropriate to mark resolution)
        deleted by us:   enchanted-forest.scm

no changes added to commit (use "git add" and/or "git commit -a")

Konflikt opravím tak, že otevřu soubor enchanted-forest.scm a nechám v něm jen to, co tam má být: testovací proceduru talk-you-birds. Po editaci souboru jej připravím pro zápis do historie:

$ git add enchanted-forest.scm

a budu pokračovat v jejím přepisování (přepisování historie):

$ git rebase --continue

Protože jsem změnil původní "Add tests" změnu, otevře se editor kvůli možné změně krátké zprávy. Nechám tu původní:

Add tests

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# interactive rebase in progress; onto 2b8558d
# Last command done (1 command done):
#    pick 4a10200 Add tests
# Next commands to do (2 remaining commands):
#    pick 32d4416 Add talking birds
#    fixup bf4e413 Add docstrings
# You are currently rebasing branch 'add-birds' on '2b8558d'.
#
# Changes to be committed:
#	new file:   enchanted-forest.scm
#

Úprava původní změny ústí v další konflikt, protože soubor enchanted-forset.scm obsahuje něco, co původní změna (32d4416 Add talking birds) nepředpokládala.

$ git rebase --continue
[detached HEAD 6af3ac3] Add tests
 1 file changed, 54 insertions(+)
 create mode 100644 enchanted-forest.scm
CONFLICT (add/add): Merge conflict in enchanted-forest.scm
Auto-merging enchanted-forest.scm
error: could not apply 32d4416... Add talking birds
Resolve all conflicts manually, mark them as resolved with
"git add/rm <conflicted_files>", then run "git rebase --continue".
You can instead skip this commit: run "git rebase --skip".
To abort and get back to the state before "git rebase", run "git rebase --abort".
Could not apply 32d4416... Add talking birds

Historie změn v dané chvíli značí rozdíl mezi původní a novou změnou pro přidání testů:

$ git log --oneline --graph --decorate --all
* 6af3ac3 (HEAD) Add tests
| * 4a10200 (tag: v1-add-birds, add-birds) Add tests
| * bf4e413 Add docstrings
| * 32d4416 Add talking birds
|/
* 2b8558d (origin/master, master) Add license, readme

A pro úplnost i stav repozitáře:

$ git status
interactive rebase in progress; onto 2b8558d
Last commands done (2 commands done):
   pick 4a10200 Add tests
   pick 32d4416 Add talking birds
Next command to do (1 remaining command):
   fixup bf4e413 Add docstrings
  (use "git rebase --edit-todo" to view and edit)
You are currently rebasing branch 'add-birds' on '2b8558d'.
  (fix conflicts and then run "git rebase --continue")
  (use "git rebase --skip" to skip this patch)
  (use "git rebase --abort" to check out the original branch)

Unmerged paths:
  (use "git restore --staged <file>..." to unstage)
  (use "git add <file>..." to mark resolution)
        both added:      enchanted-forest.scm

no changes added to commit (use "git add" and/or "git commit -a")

Pro vyřešení konfliktu otevřu soubor enchanted-forest.scm. Kód mezi <<< HEAD a === značí, co v historii právě je a kód mezi === a >>> 32d4416 značí, co by na daném místě chtěla mít změna, kterou se v rámci přepisování historie právě snažím aplikovat.

<<<<<<< HEAD
(define (talk-you-birds)
  (display "(M '(x y z))")
  (display " : ")
  (display (M '(x y z)))
  (display " =? (x x y z)")
  (newline)

  (display "(KI '(x y z))")
  (display " : ")
  (display (KI '(x y z)))
  (display " =? (y z)")
  (newline)

  (display "(T '(x y z))")
  (display " : ")
  (display (T '(x y z)))
  (display " =? (y x z)")
  (newline)

  (display "(W '(x y z))")
  (display " : ")
  (display (W '(x y z)))
  (display " =? (x y y z)")
  (newline)

  (display "(K '(x y z))")
  (display " : ")
  (display (K '(x y z)))
  (display " =? (x z)")
  (newline)

  (display "(C '(x y z))")
  (display " : ")
  (display (C '(x y z)))
  (display " =? (x z y)")
  (newline)

  (display "(B '(x y z))")
  (display " : ")
  (display (B '(x y z)))
  (display " =? (x (y z))")
  (newline)

  (display "(I '(x))")
  (display " : ")
  (display (I '(x)))
  (display " =? (x)")
  (newline)

  (display "(S '(x y z))")
  (display " : ")
  (display (S '(x y z)))
  (display " =? (x z (y z))")
  (newline))
=======
(define (M li)
  (append (list (car li) (car li)) (cdr li)))
(define (KI li)
  (cdr li))
(define (T li)
  (append (list (cadr li) (car li)) (cddr li)))
(define (W li)
  (append (list (car li) (cadr li) (cadr li)) (cddr li)))
(define (K li)
  (append (list (car li)) (cddr li)))
(define (C li)
  (append (list (car li) (caddr li) (cadr li)) (cdddr li)))
(define (B li)
  (list (car li) (cdr li)))
(define (I w)
  w)
(define (S li)
  `(,(car li) ,(caddr li) (,(cadr li) ,(caddr li))))
>>>>>>> 32d4416 (Add talking birds)

Pravidlo pro řešení konfliktů je "opravit soubor aby vypadal tak, jak bych chtěl aby vypadal po aplikování obou změn (4a10200 Add tests a 32d4416 Add talking birds):

(define (M li)
  (append (list (car li) (car li)) (cdr li)))
(define (KI li)
  (cdr li))
(define (T li)
  (append (list (cadr li) (car li)) (cddr li)))
(define (W li)
  (append (list (car li) (cadr li) (cadr li)) (cddr li)))
(define (K li)
  (append (list (car li)) (cddr li)))
(define (C li)
  (append (list (car li) (caddr li) (cadr li)) (cdddr li)))
(define (B li)
  (list (car li) (cdr li)))
(define (I w)
  w)
(define (S li)
  `(,(car li) ,(caddr li) (,(cadr li) ,(caddr li))))
(define (talk-you-birds)
  (display "(M '(x y z))")
  (display " : ")
  (display (M '(x y z)))
  (display " =? (x x y z)")
  (newline)

  (display "(KI '(x y z))")
  (display " : ")
  (display (KI '(x y z)))
  (display " =? (y z)")
  (newline)

  (display "(T '(x y z))")
  (display " : ")
  (display (T '(x y z)))
  (display " =? (y x z)")
  (newline)

  (display "(W '(x y z))")
  (display " : ")
  (display (W '(x y z)))
  (display " =? (x y y z)")
  (newline)

  (display "(K '(x y z))")
  (display " : ")
  (display (K '(x y z)))
  (display " =? (x z)")
  (newline)

  (display "(C '(x y z))")
  (display " : ")
  (display (C '(x y z)))
  (display " =? (x z y)")
  (newline)

  (display "(B '(x y z))")
  (display " : ")
  (display (B '(x y z)))
  (display " =? (x (y z))")
  (newline)

  (display "(I '(x))")
  (display " : ")
  (display (I '(x)))
  (display " =? (x)")
  (newline)

  (display "(S '(x y z))")
  (display " : ")
  (display (S '(x y z)))
  (display " =? (x z (y z))")
  (newline))

Soubor enchanted-forest.scm připravím pro zápis do historie a pokračuji v jejím přepisování:

$ git add enchanted-forest.scm
$ git rebase --continue

při zachování původní zprávy:

Add talking birds

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# interactive rebase in progress; onto 2b8558d
# Last commands done (2 commands done):
#    pick 4a10200 Add tests
#    pick 32d4416 Add talking birds
# Next command to do (1 remaining command):
#    fixup bf4e413 Add docstrings
# You are currently rebasing branch 'add-birds' on '2b8558d'.
#
# Changes to be committed:
#	modified:   enchanted-forest.scm
#

Výsledkem je úspěšný rebase:

$ git rebase --continue
[detached HEAD c4ae104]  Add talking birds
 1 file changed, 18 insertions(+)
Successfully rebased and updated refs/heads/add-birds.

Historie repozitáře vypadá:

$ git log --oneline --graph --decorate --all
* 3839a47 (HEAD -> add-birds)  Add talking birds
* 6af3ac3 Add tests
| * 4a10200 (tag: v1-add-birds) Add tests
| * bf4e413 Add docstrings
| * 32d4416 Add talking birds
|/
* 2b8558d (origin/master, master) Add license, readme

A tady bych chtěl zmínit, že poslední identifikátor změny (3839a47 Add talking birds) neodpovídá tomu po posledním rebase ([detached HEAD c4ae104] Add talking birds). To je proto, že poslední změna při přepisování historie byla označena "f" jako "fix", tedy oprav. Změna c4ae104 Add talking birds, obsahující procedury mluvících ptáků, se tak změnila na změnu 3839a47 Add talking birds obsahující procedury mluvících ptáků spolu s dokumentací.

To ověřím zobrazením poslední změny:

$ git show
commit 3839a47fe70bc1cfd5ec86d07de188a0b4b7e9d4 (HEAD -> add-birds)
Author: Foo Bar <foo@bar.buzz>
Date:   Wed Oct 5 00:24:08 2022 +0200

    Add talking birds

diff --git a/enchanted-forest.scm b/enchanted-forest.scm
index 304d7ce..7bf1bb5 100644
--- a/enchanted-forest.scm
+++ b/enchanted-forest.scm
@@ -1,3 +1,34 @@
+;;;; The Bekimet Forest
+;;; Mockingbird -- repeats the first word.
+(define (M li)
+  (append (list (car li) (car li)) (cdr li)))
+;;; Kite -- discards the first word.
+(define (KI li)
+  (cdr li))
+;;; Thrush -- swaps the first and the second word.
+(define (T li)
+  (append (list (cadr li) (car li)) (cddr li)))
+;;;; The Becekew Forest
+;;; Warbler -- repeats the second word.
+(define (W li)
+  (append (list (car li) (cadr li) (cadr li)) (cddr li)))
+;;; Kestrel -- discards the second word.
+(define (K li)
+  (append (list (car li)) (cddr li)))
+;;; Cardinal -- swaps the second and the third words.
+(define (C li)
+  (append (list (car li) (caddr li) (cadr li)) (cdddr li)))
+;;; Bluebird -- takes three words, and parethesize the third into the second.
+(define (B li)
+  (list (car li) (cdr li)))
+;;;; The Sekei Forest
+;;; Idiot -- hear word, response the same word.
+(define (I w)
+  w)
+;;; Kestrel -- see the Becekew Forest.
+;;; Starling -- apply the first and second words to the last one, then apply the first result to the second one.
+(define (S li)
+  `(,(car li) ,(caddr li) (,(cadr li) ,(caddr li))))
 (define (talk-you-birds)
   (display "(M '(x y z))")
   (display " : ")

Merge je cíl editovat

Poslední, co zbývá, je zahrnout větev přidávající procedury mluvících ptáků (add-birds) do hlavní větve (master).

Nejdřív se na větev přepnu a zorientuji se:

$ git checkout master
Switched to branch 'master'
$ git status
On branch master
nothing to commit, working tree clean
$ git log --oneline --graph --decorate --all
* 3839a47 (add-birds)  Add talking birds
* 6af3ac3 Add tests
| * 4a10200 (tag: v1-add-birds) Add tests
| * bf4e413 Add docstrings
| * 32d4416 Add talking birds
|/
* 2b8558d (HEAD -> master, origin/master) Add license, readme

Potom začlením větev mluvících ptáků (add-birds) tak, aby bylo jasné, kde začíná a kde končí:

$ git merge --no-ff add-birds

Příkazem výše se otevře textový editor. Nechám původní zprávu, uložím a zavřu:

Merge branch 'add-birds'
# Please enter a commit message to explain why this merge is necessary,
# especially if it merges an updated upstream into a topic branch.
#
# Lines starting with '#' will be ignored, and an empty message aborts
# the commit.

Výsledek je:

$ git merge --no-ff add-birds
Merge made by the 'recursive' strategy.
 enchanted-forest.scm | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 85 insertions(+)
 create mode 100644 enchanted-forest.scm

Zkontroluji, zda historie repozitáře vypadá tak, jak jsem chtěl:

$ git log --oneline --graph --decorate --all
*   b381691 (HEAD -> master) Merge branch 'add-birds'
|\
| * 3839a47 (add-birds) Add talking birds
| * 6af3ac3 Add tests
|/
| * 4a10200 (tag: v1-add-birds) Add tests
| * bf4e413 Add docstrings
| * 32d4416 Add talking birds
|/
* 2b8558d (origin/master) Add license, readme

a to vypadá. Z výpisu je vidět, že úplně původní změny jsou stále uloženy pod označením v1-add-birds. Upravené změny jsou pak začleněny do hlavní vývojové větve (změna b381691 Merge branch 'add-birds').

Větev, která sloužila pro vývoj (add-birds), už nepotřebuji:

$ git branch -d add-birds
Deleted branch add-birds (was 3839a47).

Vydám novou verzi podle sémantického verzování:

$ git tag -a v0.1.0

a původní obsah souboru:

#
# Write a message for tag:
#   v0.1.0
# Lines starting with '#' will be ignored.

změním na:

Release enchanted-forest version 0.1.0

This release contains basic functionality described in
https://wiki.xxiivv.com/site/logic.html along with the basic tests.

---

Foo Bar (4):
      Add license, readme
      Add tests
      Add talking birds
      Merge branch 'add-birds'

kde část pod --- vygeneruji příkazem:

$ git shortlog
Foo Bar (4):
      Add license, readme
      Add tests
      Add talking birds
      Merge branch 'add-birds'

který se mi hodí i při vydávání dalších verzí. To pak ale potřebuji ještě rozsah změn, tedy například:

$ git shortlog v0.1.0..HEAD

Všechna označení (tag) v historii zobrazím příkazem:

$ git tag
v0.1.0
v1-add-birds

a pro zahrnutí zpráv (git tag -n POČET-ŘÁDKŮ-ZPRÁVY):

$ git tag -n999
v0.1.0          Release enchanted-forest version 0.1.0

    This release contains basic functionality described in
    https://wiki.xxiivv.com/site/logic.html along with the basic tests.

    ---

    Foo Bar (4):
          Add license, readme
          Add tests
          Add talking birds
          Merge branch 'add-birds'
v1-add-birds    Add tests

Nakonec aktualizuji repozitář na vzdáleném serveru:

$ git push --tags origin master
Enumerating objects: 16, done.
Counting objects: 100% (16/16), done.
Delta compression using up to 4 threads
Compressing objects: 100% (15/15), done.
Writing objects: 100% (15/15), 1.91 KiB | 1.91 MiB/s, done.
Total 15 (delta 10), reused 0 (delta 0), pack-reused 0
To git.sr.ht:~qeef/enchanted-forest
   2b8558d..b381691  master -> master
 * [new tag]         v0.1.0 -> v0.1.0
 * [new tag]         v1-add-birds -> v1-add-birds

Příkaz výše provede dvě věci najednou. Aktualizuje hlavní větev (git push) a zároveň nahraje označení (git push --tags). Pokud chci udělat obé naráz, potřebuji specifikovat vzdálený server (jménem) a větev. Proto git push --tags origin master.

Zbývá už jen zkontrolovat historii:

$ git log
commit b3816913e920ff7438a32061cad30fa73e54c39c (HEAD -> master, tag: v0.1.0, origin/master)
Merge: 2b8558d 3839a47
Author: Foo Bar <foo@bar.buzz>
Date:   Wed Oct 5 01:05:16 2022 +0200

    Merge branch 'add-birds'

commit 3839a47fe70bc1cfd5ec86d07de188a0b4b7e9d4
Author: Foo Bar <foo@bar.buzz>
Date:   Wed Oct 5 00:24:08 2022 +0200

    Add talking birds

commit 6af3ac3007b239b36193c79661d116f972643fdd
Author: Foo Bar <foo@bar.buzz>
Date:   Wed Oct 5 00:36:43 2022 +0200

    Add tests

commit 2b8558d17f2b3cbd29896d8b92e5f8ba68bf8fca
Author: Foo Bar <foo@bar.buzz>
Date:   Sat Sep 17 21:09:05 2022 +0200

    Add license, readme

A ještě jednou tak, jak historii rozumím i já:

$ git log --oneline --graph --decorate --all
*   b381691 (HEAD -> master, tag: v0.1.0, origin/master) Merge branch 'add-birds'
|\
| * 3839a47 Add talking birds
| * 6af3ac3 Add tests
|/
| * 4a10200 (tag: v1-add-birds) Add tests
| * bf4e413 Add docstrings
| * 32d4416 Add talking birds
|/
* 2b8558d Add license, readme

Příkaz výše ukazuje základní změnu (2b8558d Add license, readme), ze které vychází celá historie (změn) repozitáře. Vychází z ní tři původní změny. Označení v1-add-birds tyto tři původní změny zachovává (archivuje). Přepsaná (upravená) historie změn opět vychází ze základní změny (2b8558d Add license, readme) a je začleněna do hlavní vývojové větve změnou b381691 Merge branch 'add-birds'. Ta je vydána jako v0.1.0 (kde "v" je zkratka pro "verze").

Druhá změna historie a rozdělení změn editovat

Původně jsem tady chtěl skončit. Repozitář vypadá takhle:

$ git log --oneline --graph --decorate --all
*   b381691 (HEAD -> master, tag: v0.1.0, origin/master) Merge branch 'add-birds'
|\
| * 3839a47 Add talking birds
| * 6af3ac3 Add tests
|/
| * 4a10200 (tag: v1-add-birds) Add tests
| * bf4e413 Add docstrings
| * 32d4416 Add talking birds
|/
* 2b8558d Add license, readme

Nakonec jsem se ale rozhodl nepřidávat všechny mluvící ptáky najednou, ale po jednotlivých lesích. Takže historii přepíši podruhé a změnu s krátkou zprávou "Add talking birds" rozdělím na tři jiné změny.

Začnu vytvořením větve add-forests, která bude obsahovat historii add-birds, ale nebude zahrnuta do master:

$ git checkout -b add-forests 3839a47
Switched to a new branch 'add-forests'

Zkontroluji, zda jsem tam, kde bych chtěl být, tedy na změně, kterou chci rozdělit:

$ git log --oneline --graph --decorate --all
*   b381691 (tag: v0.1.0, origin/master, master) Merge branch 'add-birds'
|\
| * 3839a47 (HEAD -> add-forests) Add talking birds
| * 6af3ac3 Add tests
|/
| * 4a10200 (tag: v1-add-birds) Add tests
| * bf4e413 Add docstrings
| * 32d4416 Add talking birds
|/
* 2b8558d Add license, readme

Větev add-forests přenastavím tak, aby odpovídala jedné změně před "Add talking birds" změnou. Kód, který přináší "Add talking birds" změna, chci ale zanechat. Jenom jej nechci mít v historii. (To je rozdíl mezi git reset a git reset --hard.)

$ git reset HEAD^
Unstaged changes after reset:
M       enchanted-forest.scm

Zkontroluji repozitář:

$ git log --oneline --graph --decorate --all
*   b381691 (tag: v0.1.0, origin/master, master) Merge branch 'add-birds'
|\
| * 3839a47 Add talking birds
| * 6af3ac3 (HEAD -> add-forests) Add tests
|/
| * 4a10200 (tag: v1-add-birds) Add tests
| * bf4e413 Add docstrings
| * 32d4416 Add talking birds
|/
* 2b8558d Add license, readme
$ git status
On branch add-forests
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   enchanted-forest.scm

no changes added to commit (use "git add" and/or "git commit -a")

Zkontroluji změny kódu:

$ git diff
diff --git a/enchanted-forest.scm b/enchanted-forest.scm
index 304d7ce..7bf1bb5 100644
--- a/enchanted-forest.scm
+++ b/enchanted-forest.scm
@@ -1,3 +1,34 @@
+;;;; The Bekimet Forest
+;;; Mockingbird -- repeats the first word.
+(define (M li)
+  (append (list (car li) (car li)) (cdr li)))
+;;; Kite -- discards the first word.
+(define (KI li)
+  (cdr li))
+;;; Thrush -- swaps the first and the second word.
+(define (T li)
+  (append (list (cadr li) (car li)) (cddr li)))
+;;;; The Becekew Forest
+;;; Warbler -- repeats the second word.
+(define (W li)
+  (append (list (car li) (cadr li) (cadr li)) (cddr li)))
+;;; Kestrel -- discards the second word.
+(define (K li)
+  (append (list (car li)) (cddr li)))
+;;; Cardinal -- swaps the second and the third words.
+(define (C li)
+  (append (list (car li) (caddr li) (cadr li)) (cdddr li)))
+;;; Bluebird -- takes three words, and parethesize the third into the second.
+(define (B li)
+  (list (car li) (cdr li)))
+;;;; The Sekei Forest
+;;; Idiot -- hear word, response the same word.
+(define (I w)
+  w)
+;;; Kestrel -- see the Becekew Forest.
+;;; Starling -- apply the first and second words to the last one, then apply the first result to the second one.
+(define (S li)
+  `(,(car li) ,(caddr li) (,(cadr li) ,(caddr li))))
 (define (talk-you-birds)
   (display "(M '(x y z))")
   (display " : ")

Přidám první les:

$ git add -p
diff --git a/enchanted-forest.scm b/enchanted-forest.scm
index 304d7ce..7bf1bb5 100644
--- a/enchanted-forest.scm
+++ b/enchanted-forest.scm
@@ -1,3 +1,34 @@
+;;;; The Bekimet Forest
+;;; Mockingbird -- repeats the first word.
+(define (M li)
+  (append (list (car li) (car li)) (cdr li)))
+;;; Kite -- discards the first word.
+(define (KI li)
+  (cdr li))
+;;; Thrush -- swaps the first and the second word.
+(define (T li)
+  (append (list (cadr li) (car li)) (cddr li)))
+;;;; The Becekew Forest
+;;; Warbler -- repeats the second word.
+(define (W li)
+  (append (list (car li) (cadr li) (cadr li)) (cddr li)))
+;;; Kestrel -- discards the second word.
+(define (K li)
+  (append (list (car li)) (cddr li)))
+;;; Cardinal -- swaps the second and the third words.
+(define (C li)
+  (append (list (car li) (caddr li) (cadr li)) (cdddr li)))
+;;; Bluebird -- takes three words, and parethesize the third into the second.
+(define (B li)
+  (list (car li) (cdr li)))
+;;;; The Sekei Forest
+;;; Idiot -- hear word, response the same word.
+(define (I w)
+  w)
+;;; Kestrel -- see the Becekew Forest.
+;;; Starling -- apply the first and second words to the last one, then apply the first result to the second one.
+(define (S li)
+  `(,(car li) ,(caddr li) (,(cadr li) ,(caddr li))))
 (define (talk-you-birds)
   (display "(M '(x y z))")
   (display " : ")
(1/1) Stage this hunk [y,n,q,a,d,e,?]? e

Manuálně edituji změnu ("e"), originální text v editoru:

# Manual hunk edit mode -- see bottom for a quick guide.
@@ -1,3 +1,34 @@
+;;;; The Bekimet Forest
+;;; Mockingbird -- repeats the first word.
+(define (M li)
+  (append (list (car li) (car li)) (cdr li)))
+;;; Kite -- discards the first word.
+(define (KI li)
+  (cdr li))
+;;; Thrush -- swaps the first and the second word.
+(define (T li)
+  (append (list (cadr li) (car li)) (cddr li)))
+;;;; The Becekew Forest
+;;; Warbler -- repeats the second word.
+(define (W li)
+  (append (list (car li) (cadr li) (cadr li)) (cddr li)))
+;;; Kestrel -- discards the second word.
+(define (K li)
+  (append (list (car li)) (cddr li)))
+;;; Cardinal -- swaps the second and the third words.
+(define (C li)
+  (append (list (car li) (caddr li) (cadr li)) (cdddr li)))
+;;; Bluebird -- takes three words, and parethesize the third into the second.
+(define (B li)
+  (list (car li) (cdr li)))
+;;;; The Sekei Forest
+;;; Idiot -- hear word, response the same word.
+(define (I w)
+  w)
+;;; Kestrel -- see the Becekew Forest.
+;;; Starling -- apply the first and second words to the last one, then apply the first result to the second one.
+(define (S li)
+  `(,(car li) ,(caddr li) (,(cadr li) ,(caddr li))))
 (define (talk-you-birds)
   (display "(M '(x y z))")
   (display " : ")
# ---
# To remove '-' lines, make them ' ' lines (context).
# To remove '+' lines, delete them.
# Lines starting with # will be removed.
# 
# If the patch applies cleanly, the edited hunk will immediately be
# marked for staging.
# If it does not apply cleanly, you will be given an opportunity to
# edit again.  If all lines of the hunk are removed, then the edit is
# aborted and the hunk is left unchanged.

upravím na:

# Manual hunk edit mode -- see bottom for a quick guide.
@@ -1,3 +1,34 @@
+;;;; The Bekimet Forest
+;;; Mockingbird -- repeats the first word.
+(define (M li)
+  (append (list (car li) (car li)) (cdr li)))
+;;; Kite -- discards the first word.
+(define (KI li)
+  (cdr li))
+;;; Thrush -- swaps the first and the second word.
+(define (T li)
+  (append (list (cadr li) (car li)) (cddr li)))
 (define (talk-you-birds)
   (display "(M '(x y z))")
   (display " : ")
# ---
# To remove '-' lines, make them ' ' lines (context).
# To remove '+' lines, delete them.
# Lines starting with # will be removed.
# 
# If the patch applies cleanly, the edited hunk will immediately be
# marked for staging.
# If it does not apply cleanly, you will be given an opportunity to
# edit again.  If all lines of the hunk are removed, then the edit is
# aborted and the hunk is left unchanged.

Zkontroluji repozitář:

$ git status
On branch add-forests
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   enchanted-forest.scm

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   enchanted-forest.scm

Zkontroluji změny, které chci přidat:

$ git diff --cached
diff --git a/enchanted-forest.scm b/enchanted-forest.scm
index 304d7ce..9640c98 100644
--- a/enchanted-forest.scm
+++ b/enchanted-forest.scm
@@ -1,3 +1,13 @@
+;;;; The Bekimet Forest
+;;; Mockingbird -- repeats the first word.
+(define (M li)
+  (append (list (car li) (car li)) (cdr li)))
+;;; Kite -- discards the first word.
+(define (KI li)
+  (cdr li))
+;;; Thrush -- swaps the first and the second word.
+(define (T li)
+  (append (list (cadr li) (car li)) (cddr li)))
 (define (talk-you-birds)
   (display "(M '(x y z))")
   (display " : ")

A přidám je do historie:

$ git commit -m'Add Bekimet Forest'
[add-forests 51ed0c2] Add Bekimet Forest
 1 file changed, 10 insertions(+)

Kontrolou historie repozitáře zjistím, jak vypadá začátek budování historie větve add-forests:

$ git log --oneline --graph --decorate --all
* 5745778 (HEAD -> add-forests) Add Bekimet Forest
| *   b381691 (tag: v0.1.0, origin/master, master) Merge branch 'add-birds'
| |\
| | * 3839a47 Add talking birds
| |/
|/|
* | 6af3ac3 Add tests
|/
| * 4a10200 (tag: v1-add-birds) Add tests
| * bf4e413 Add docstrings
| * 32d4416 Add talking birds
|/
* 2b8558d Add license, readme

Ověřím právě přidanou změnu:

$ git show
commit 574577878bb2b51cb93fc74e409786fa41cf4799 (HEAD -> add-forests)
Author: Foo Bar <foo@bar.buzz>
Date:   Sun Oct 16 00:04:59 2022 +0200

    Add Bekimet Forest

diff --git a/enchanted-forest.scm b/enchanted-forest.scm
index 304d7ce..9640c98 100644
--- a/enchanted-forest.scm
+++ b/enchanted-forest.scm
@@ -1,3 +1,13 @@
+;;;; The Bekimet Forest
+;;; Mockingbird -- repeats the first word.
+(define (M li)
+  (append (list (car li) (car li)) (cdr li)))
+;;; Kite -- discards the first word.
+(define (KI li)
+  (cdr li))
+;;; Thrush -- swaps the first and the second word.
+(define (T li)
+  (append (list (cadr li) (car li)) (cddr li)))
 (define (talk-you-birds)
   (display "(M '(x y z))")
   (display " : ")

Pokračuji v přidávání dalších změn zbylých lesů:

$ git add -p
diff --git a/enchanted-forest.scm b/enchanted-forest.scm
index 9640c98..7bf1bb5 100644
--- a/enchanted-forest.scm
+++ b/enchanted-forest.scm
@@ -8,6 +8,27 @@
 ;;; Thrush -- swaps the first and the second word.
 (define (T li)
   (append (list (cadr li) (car li)) (cddr li)))
+;;;; The Becekew Forest
+;;; Warbler -- repeats the second word.
+(define (W li)
+  (append (list (car li) (cadr li) (cadr li)) (cddr li)))
+;;; Kestrel -- discards the second word.
+(define (K li)
+  (append (list (car li)) (cddr li)))
+;;; Cardinal -- swaps the second and the third words.
+(define (C li)
+  (append (list (car li) (caddr li) (cadr li)) (cdddr li)))
+;;; Bluebird -- takes three words, and parethesize the third into the second.
+(define (B li)
+  (list (car li) (cdr li)))
+;;;; The Sekei Forest
+;;; Idiot -- hear word, response the same word.
+(define (I w)
+  w)
+;;; Kestrel -- see the Becekew Forest.
+;;; Starling -- apply the first and second words to the last one, then apply the first result to the second one.
+(define (S li)
+  `(,(car li) ,(caddr li) (,(cadr li) ,(caddr li))))
 (define (talk-you-birds)
   (display "(M '(x y z))")
   (display " : ")
(1/1) Stage this hunk [y,n,q,a,d,e,?]? e

Originální text v editoru:

# Manual hunk edit mode -- see bottom for a quick guide.
@@ -8,6 +8,27 @@
 ;;; Thrush -- swaps the first and the second word.
 (define (T li)
   (append (list (cadr li) (car li)) (cddr li)))
+;;;; The Becekew Forest
+;;; Warbler -- repeats the second word.
+(define (W li)
+  (append (list (car li) (cadr li) (cadr li)) (cddr li)))
+;;; Kestrel -- discards the second word.
+(define (K li)
+  (append (list (car li)) (cddr li)))
+;;; Cardinal -- swaps the second and the third words.
+(define (C li)
+  (append (list (car li) (caddr li) (cadr li)) (cdddr li)))
+;;; Bluebird -- takes three words, and parethesize the third into the second.
+(define (B li)
+  (list (car li) (cdr li)))
+;;;; The Sekei Forest
+;;; Idiot -- hear word, response the same word.
+(define (I w)
+  w)
+;;; Kestrel -- see the Becekew Forest.
+;;; Starling -- apply the first and second words to the last one, then apply the first result to the second one.
+(define (S li)
+  `(,(car li) ,(caddr li) (,(cadr li) ,(caddr li))))
 (define (talk-you-birds)
   (display "(M '(x y z))")
   (display " : ")
# ---
# To remove '-' lines, make them ' ' lines (context).
# To remove '+' lines, delete them.
# Lines starting with # will be removed.
# 
# If the patch applies cleanly, the edited hunk will immediately be
# marked for staging.
# If it does not apply cleanly, you will be given an opportunity to
# edit again.  If all lines of the hunk are removed, then the edit is
# aborted and the hunk is left unchanged.

změním na:

@@ -8,6 +8,27 @@
 ;;; Thrush -- swaps the first and the second word.
 (define (T li)
   (append (list (cadr li) (car li)) (cddr li)))
+;;;; The Becekew Forest
+;;; Warbler -- repeats the second word.
+(define (W li)
+  (append (list (car li) (cadr li) (cadr li)) (cddr li)))
+;;; Kestrel -- discards the second word.
+(define (K li)
+  (append (list (car li)) (cddr li)))
+;;; Cardinal -- swaps the second and the third words.
+(define (C li)
+  (append (list (car li) (caddr li) (cadr li)) (cdddr li)))
+;;; Bluebird -- takes three words, and parethesize the third into the second.
+(define (B li)
+  (list (car li) (cdr li)))
 (define (talk-you-birds)
   (display "(M '(x y z))")
   (display " : ")

Zkontroluji stav repozitáře:

$ git status
On branch add-forests
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   enchanted-forest.scm

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   enchanted-forest.scm

Zkontroluji, co budu přidávat do historie:

$ git diff --cached
diff --git a/enchanted-forest.scm b/enchanted-forest.scm
index 9640c98..9ef0dc5 100644
--- a/enchanted-forest.scm
+++ b/enchanted-forest.scm
@@ -8,6 +8,19 @@
 ;;; Thrush -- swaps the first and the second word.
 (define (T li)
   (append (list (cadr li) (car li)) (cddr li)))
+;;;; The Becekew Forest
+;;; Warbler -- repeats the second word.
+(define (W li)
+  (append (list (car li) (cadr li) (cadr li)) (cddr li)))
+;;; Kestrel -- discards the second word.
+(define (K li)
+  (append (list (car li)) (cddr li)))
+;;; Cardinal -- swaps the second and the third words.
+(define (C li)
+  (append (list (car li) (caddr li) (cadr li)) (cdddr li)))
+;;; Bluebird -- takes three words, and parethesize the third into the second.
+(define (B li)
+  (list (car li) (cdr li)))
 (define (talk-you-birds)
   (display "(M '(x y z))")
   (display " : ")

Přidám druhý les:

$ git commit -m'Add Becekew Forest'
[add-forests 758d3f5] Add Becekew Forest
 1 file changed, 13 insertions(+)

Podívám se, jak buduji historii větve add-forests:

$ git log --oneline --graph --decorate --all
* 758d3f5 (HEAD -> add-forests) Add Becekew Forest
* 5745778 Add Bekimet Forest
| *   b381691 (tag: v0.1.0, origin/master, master) Merge branch 'add-birds'
| |\
| | * 3839a47 Add talking birds
| |/
|/|
* | 6af3ac3 Add tests
|/
| * 4a10200 (tag: v1-add-birds) Add tests
| * bf4e413 Add docstrings
| * 32d4416 Add talking birds
|/
* 2b8558d Add license, readme

Podívám se na aktuální změny v repozitáři:

$ git diff
diff --git a/enchanted-forest.scm b/enchanted-forest.scm
index 9ef0dc5..7bf1bb5 100644
--- a/enchanted-forest.scm
+++ b/enchanted-forest.scm
@@ -21,6 +21,14 @@
 ;;; Bluebird -- takes three words, and parethesize the third into the second.
 (define (B li)
   (list (car li) (cdr li)))
+;;;; The Sekei Forest
+;;; Idiot -- hear word, response the same word.
+(define (I w)
+  w)
+;;; Kestrel -- see the Becekew Forest.
+;;; Starling -- apply the first and second words to the last one, then apply the first result to the second one.
+(define (S li)
+  `(,(car li) ,(caddr li) (,(cadr li) ,(caddr li))))
 (define (talk-you-birds)
   (display "(M '(x y z))")
   (display " : ")

Protože zbývá poslední les, přidám soubor obsahující kód a rovnou jej zaznamenám do historie:

$ git add enchanted-forest.scm
$ git commit -m'Add Sekei Forest'
[add-forests 19acdad] Add Sekei Forest
 1 file changed, 8 insertions(+)

Zkontroluji historii budované větve add-forests:

$ git log --oneline --graph --decorate --all
* 19acdad (HEAD -> add-forests) Add Sekei Forest
* 758d3f5 Add Becekew Forest
* 5745778 Add Bekimet Forest
| *   b381691 (tag: v0.1.0, origin/master, master) Merge branch 'add-birds'
| |\
| | * 3839a47 Add talking birds
| |/
|/|
* | 6af3ac3 Add tests
|/
| * 4a10200 (tag: v1-add-birds) Add tests
| * bf4e413 Add docstrings
| * 32d4416 Add talking birds
|/
* 2b8558d Add license, readme

V tuhle chvíli mám změnu s krátkou zprávou "Add talking birds" nahrazenou třemi novými změnami, jak jsem chtěl. Další krok je zahrnout větev add-forests do větve master stejným způsobem, jakým byla zahrnuta větev add-birds. Postup je stejný.

Nicméně jiné je to, že původní větev (add-birds) ve větvi master nechci. Jdu tedy pozpátku po změnách větve master a hledám, na kterou změnu větev master nastavit.

Začínám změnou b381691 Merge branch 'add-birds', která zahrnuje začlenění větve add-birds. To vím, že nechci.

Pak se historie větví. První možnost je jít směrem 3839a47 Add talking birds, což je změna, kterou jsem nahradil. (Takže ji nechci.) Tato změna staví na 6af3ac3 Add tests, na které staví i nové tři změny. Tady je ale potřeba zmínit, že 6af3ac3 Add tests je součástí vývojové větve add-birds. Kdybych přenastavil větev master na změnu 6af3ac3 Add tests, nebyla by to chyba, ale pletl bych dohromady hlavní vývojovou větev (master) s větvemi reprezentujícími nové funkce (jako add-birds). V tomto příkladě to nechci.

Tím se dostávám k druhé možnosti, a tou je změna 2b8558d Add license, readme. Z historie repozitáře je vidět, že po přidání licence a readme byla další změna zahrnutí větve add-birds. Já se rozhodl jednu ze změn této větve opravit a vytvořil tak novou větev add-forests. Chtěl bych tedy, aby historie hlavní vývojové větve (master) vypadala tak, že další změna po přidání licence a readme bude zahrnutí opravené větve add-forests. Z toho vyplývá, že změna, na kterou chci přenastavit větev master je změna 2b8558d Add license, readme.

Nejprve se přepnu na větev master:

$ git checkout master
Switched to branch 'master'

Pak ji přenastavím na vybranou změnu. Protože historii, kterou chci začlenit, mám již vybudovanou, při změně nechci zachovat žádný kód.

$ git reset --hard 2b8558d
HEAD is now at 2b8558d Add license, readme

Zkontroluji, jak aktuálně vypadá historie repozitáře:

$ git log --oneline --graph --decorate --all
* 19acdad (add-forests) Add Sekei Forest
* 758d3f5 Add Becekew Forest
* 5745778 Add Bekimet Forest
| *   b381691 (tag: v0.1.0, origin/master) Merge branch 'add-birds'
| |\
| | * 3839a47 Add talking birds
| |/
|/|
* | 6af3ac3 Add tests
|/
| * 4a10200 (tag: v1-add-birds) Add tests
| * bf4e413 Add docstrings
| * 32d4416 Add talking birds
|/
* 2b8558d (HEAD -> master) Add license, readme

Začlením větev nové funkce add-forests:

$ git merge --no-ff add-forests
Merge made by the 'recursive' strategy.
 enchanted-forest.scm | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 85 insertions(+)
 create mode 100644 enchanted-forest.scm

Po začlenění vývojovou větev již nepotřebuji a mohu ji smazat:

$ git branch -d add-forests
Deleted branch add-forests (was 19acdad).

Vytvořím novou značku:

$ git tag -a v0.2.0

Do release zprávy napíši:

Release enchanted-forest version 0.2.0

This release contains basic functionality described in
https://wiki.xxiivv.com/site/logic.html along with the basic tests.

---

Foo Bar (6):
      Add license, readme
      Add tests
      Add Bekimet Forest
      Add Becekew Forest
      Add Sekei Forest
      Merge branch 'add-forests'

A zkontroluji historii repozitáře:

$ git log --oneline --graph --decorate --all
*   48c405d (HEAD -> master, tag: v0.2.0) Merge branch 'add-forests'
|\
| * 19acdad Add Sekei Forest
| * 758d3f5 Add Becekew Forest
| * 5745778 Add Bekimet Forest
| | * b381691 (tag: v0.1.0, origin/master) Merge branch 'add-birds'
| |/|
|/| |
| | * 3839a47 Add talking birds
| |/
| * 6af3ac3 Add tests
|/
| * 4a10200 (tag: v1-add-birds) Add tests
| * bf4e413 Add docstrings
| * 32d4416 Add talking birds
|/
* 2b8558d Add license, readme

Zbývá změny provedené lokálně zapsat na server:

$ git push
To git.sr.ht:~qeef/enchanted-forest
 ! [rejected]        master -> master (non-fast-forward)
error: failed to push some refs to 'git.sr.ht:~qeef/enchanted-forest'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

což selže, protože jsem přepsal historii větve (v tomto případě hlavní vývojové větve master). Selhání má smysl, protože publikovanou historii změn již může někdo používat a přepsáním publikované historie dotyčné(mu) zkomplikuji práci.

Selhání objedu vynucením zapsání na server:

$ git push -f
Enumerating objects: 13, done.
Counting objects: 100% (13/13), done.
Delta compression using up to 4 threads
Compressing objects: 100% (10/10), done.
Writing objects: 100% (10/10), 1.35 KiB | 1.35 MiB/s, done.
Total 10 (delta 6), reused 0 (delta 0), pack-reused 0
To git.sr.ht:~qeef/enchanted-forest
 + b381691...48c405d master -> master (forced update)

Vynucení zapsání na server se pro hlavní vývojovou větev nepoužívá. Používá se ale pro aktualizaci větví nových funkcí při použití Pull/Merge Request workflow, většinou jako další krok po obdržení revize kódu a úpravě kódu nové funkce.

Nakonec naposledy historie repozitáře:

$ git log --oneline --graph --decorate --all
*   48c405d (HEAD -> master, tag: v0.2.0, origin/master) Merge branch 'add-forests'
|\
| * 19acdad Add Sekei Forest
| * 758d3f5 Add Becekew Forest
| * 5745778 Add Bekimet Forest
| | * b381691 (tag: v0.1.0) Merge branch 'add-birds'
| |/|
|/| |
| | * 3839a47 Add talking birds
| |/
| * 6af3ac3 Add tests
|/
| * 4a10200 (tag: v1-add-birds) Add tests
| * bf4e413 Add docstrings
| * 32d4416 Add talking birds
|/
* 2b8558d Add license, readme

Použité příkazy editovat

Inicializace repozitáře:

git init
git config user.email 'foo@bar.buzz'
git config --global user.name 'Foo Bar'

Přidání license a readme:

git status
git add LICENSE README
git diff --cached
git commit -m'Add license, readme'
git log
git show

Přidání mluvících ptáků:

git branch
git branch add-birds
git checkout add-birds
git add -N enchanted-forest.scm
git add -p
git log --oneline --graph --decorate --all
git tag v1-add-birds

Přeskupení a oprava historie:

git rebase -i master

plus řešení konfliktů.

Merge je cíl:

git merge --no-ff add-birds
git branch -d add-birds
git tag -a v0.1.0
git tag -n99

Oprava historie přepsáním změny:

git checkout -b add-forests ZMENA-ZE-KTERE-VYCHAZI-NOVA-VETEV
git reset HEAD^
git reset --hard ZMENA-NA-KTERE-MA-BYT-AKTUALNI-VETEV
git push -f