Git pro mě/Rebase je základ
Teďka poznámky k vytvoření repozitáře pro workshop rebase is base. Úkol zní jasně: Vytvořte Python3 balíček args
, který obsahuje modul evaluator
s procedurouev
.
def ev(op, *args):
"""Return value computed from ``args`` based on ``op``.
Procedure ``ev`` returns:
- sum of arguments for ``op == "+"``,
- product of arguments for ``op == "*"``,
- true if arguments are non-descending for ``op == "<"``,
- true if arguments are non-increasing for ``op == ">"``.
:param op: An operator (as string) to be applied to ``args``.
:param args: The list (of numbers) to apply ``op`` to.
"""
pass # TODO
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. Všechny příkazy píšu do příkazové řádky v adresáři args
(root repozitáře).
Inicializace repozitáře
editovatPř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/args/.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
editovatJako první přidám soubory s licencí a readme. Licence je důležitá proto, aby kód mohl znovupoužít někdo další. Často používám MIT Licenci.
Readme píšu pro sebe. Chci vědět, CO je pointa, protože to do zítra zapomenu. Občas to, co si napíšu, zní dost divně, takže přidám PROČ zrovna to. Navíc do readme přidám JAK dělat věci, které dělám pořád (třeba jak projekt zkompilovat) a v neposlední řadě KAM a KOMU napsat dotaz či bug report (komunikační kanál).
$ git status On branch master No commits yet Untracked files: (use "git add <file>..." to include in what will be committed) LICENSE README 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
$ git diff --cached diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..5fd1bda --- /dev/null +++ b/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2023 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..4e3d26f --- /dev/null +++ b/README @@ -0,0 +1,2 @@ +Python3 package with the procedure evaluating arguments based on the +operator.
Pokud jsem spokojený s výsledkem příkazu git diff --cached
, přidám změnu do historie:
$ git commit
Tim se otevře okno výchozího editoru, napíšu stručně co přidávám a zavřu jej.
# Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. # # On branch master # # Initial commit # # Changes to be committed: # new file: LICENSE # new file: README #
Vim se zavírá ZZ
(tedy "shift" a dvakrát "z"). Výchozí editor se dá nastavit:
git config --global core.editor 'vim'
Jde použít i jiný editor:
git config --global core.editor 'gedit' git config --global core.editor 'notepad'
Při práci na Windows je vhodné vynutit stejné zakončení řádků, jaké používá git:
git config core.autocrlf false git config core.eol lf
Stručné zprávě se říká commit message. Může mít více řádků, kde první řádek začíná velkým pismenem, má maximálně 52 znaků, nepíše se tečka a je to imperativní pokračování věty "When applied, this patch will ...". Pak jeden prázdný řádek a nakonec zbytek textu, popisující CO a PROČ, zarovnaný na 72 znaků. JAK je v kódu.
Add license, readme # Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. # # On branch master # # Initial commit # # Changes to be committed: # new file: LICENSE # new file: README #
$ git commit [master (root-commit) 8dc1c0a] Add license, readme 2 files changed, 21 insertions(+) create mode 100644 LICENSE create mode 100644 README
$ git status On branch master nothing to commit, working tree clean
Prohlédnu a zkontroluji historii změn:
$ git log commit 8dc1c0a0e483227c03810acbc6a52882492d0012 (HEAD -> master) Author: Foo Bar <foo@bar.buzz> Date: Mon Jun 26 22:39:23 2023 +0200 Add license, readme
$ git show commit 8dc1c0a0e483227c03810acbc6a52882492d0012 (HEAD -> master) Author: Foo Bar <foo@bar.buzz> Date: Mon Jun 26 22:39:23 2023 +0200 Add license, readme diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..5fd1bda --- /dev/null +++ b/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2023 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..4e3d26f --- /dev/null +++ b/README @@ -0,0 +1,2 @@ +Python3 package with the procedure evaluating arguments based on the +operator.
Dost často, a to i v dalších sekcích, kontroluji repozitář pomocí příkazů:
git status git diff git diff --cached git log git show git logg
Ten poslední je alias pro git log --oneline --graph --decorate --all
, který můžu nastavit příkazem:
git config --global --add alias.logg 'log --oneline --graph --decorate --all'
$ git logg * d0dbc16 (HEAD -> master) Add license, readme
Přidání operátoru "+"
editovatNejprve je potřeba přidat Python3 balíček args
.
$ git status On branch master Untracked files: (use "git add <file>..." to include in what will be committed) args/ nothing added to commit but untracked files present (use "git add" to track)
$ tree . ├── args │ └── __init__.py ├── LICENSE └── README 1 directory, 3 files
$ git add args/
$ git status On branch master Changes to be committed: (use "git restore --staged <file>..." to unstage) new file: args/__init__.py
$ git commit [master d26defa] Add args package 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 args/__init__.py
$ git show commit d26defa80cf953415b2b826825c2d641fa28960a (HEAD -> master) Author: Foo Bar <foo@bar.buzz> Date: Tue Jun 27 00:56:49 2023 +0200 Add args Python3 package diff --git a/args/__init__.py b/args/__init__.py new file mode 100644 index 0000000..e69de29
Potom přidat evaluator
modul s procedurou ev
; není čas ztrácet čas, takže rovnou s implementací operátoru "+".
$ git status On branch master Untracked files: (use "git add <file>..." to include in what will be committed) args/evaluator.py nothing added to commit but untracked files present (use "git add" to track)
$ tree . ├── args │ ├── evaluator.py │ └── __init__.py ├── LICENSE └── README 1 directory, 4 files
$ cat args/evaluator.py def ev(op, *args): if "+" == op: s = 0 for a in args: s += a return s
$ git add args/evaluator.py
$ git status On branch master Changes to be committed: (use "git restore --staged <file>..." to unstage) new file: args/evaluator.py
$ git commit [master 0da38ec] Add evaluator module, operator "+" 1 file changed, 6 insertions(+) create mode 100644 args/evaluator.py
$ git show commit 0da38ece7090b024298053cc6ee7fba1c4b05b3d (HEAD -> master) Author: Foo Bar <foo@bar.buzz> Date: Tue Jun 27 01:10:10 2023 +0200 Add evaluator module, operator "+" diff --git a/args/evaluator.py b/args/evaluator.py new file mode 100644 index 0000000..13c2609 --- /dev/null +++ b/args/evaluator.py @@ -0,0 +1,6 @@ +def ev(op, *args): + if "+" == op: + s = 0 + for a in args: + s += a + return s
Nakonec přidat unit testy ...
$ git status On branch master Untracked files: (use "git add <file>..." to include in what will be committed) tests/ nothing added to commit but untracked files present (use "git add" to track)
$ tree . ├── args │ ├── evaluator.py │ └── __init__.py ├── LICENSE ├── README └── tests └── test_sum.py 2 directories, 5 files
$ cat tests/test_sum.py from unittest import TestCase from args.evaluator import ev class TestEvaluator(TestCase): def test_sum(self): assert 6 == ev("+", 1, 2, 3)
$ git add tests/
$ git status On branch master Changes to be committed: (use "git restore --staged <file>..." to unstage) new file: tests/test_sum.py
$ git commit [master 2bd56ca] Add operator "+" unit test 1 file changed, 8 insertions(+) create mode 100644 tests/test_sum.py
$ git show commit 2bd56ca80495fd03819b7a6fe842136593a2343d (HEAD -> master) Author: Foo Bar <foo@bar.buzz> Date: Tue Jun 27 01:20:38 2023 +0200 Add operator "+" unit test diff --git a/tests/test_sum.py b/tests/test_sum.py new file mode 100644 index 0000000..9699439 --- /dev/null +++ b/tests/test_sum.py @@ -0,0 +1,8 @@ +from unittest import TestCase + +from args.evaluator import ev + + +class TestEvaluator(TestCase): + def test_sum(self): + assert 6 == ev("+", 1, 2, 3)
$ python3 -m unittest discover tests . ---------------------------------------------------------------------- Ran 1 test in 0.000s OK
... a prozkoumat aktuální stav repozitáře.
$ git status On branch master Untracked files: (use "git add <file>..." to include in what will be committed) args/__pycache__/ tests/__pycache__/ nothing added to commit but untracked files present (use "git add" to track)
$ tree . ├── args │ ├── evaluator.py │ ├── __init__.py │ └── __pycache__ │ ├── evaluator.cpython-39.pyc │ └── __init__.cpython-39.pyc ├── LICENSE ├── README └── tests ├── __pycache__ │ └── test_sum.cpython-39.pyc └── test_sum.py 4 directories, 8 files
$ git log commit 2bd56ca80495fd03819b7a6fe842136593a2343d (HEAD -> master) Author: Foo Bar <foo@bar.buzz> Date: Tue Jun 27 01:20:38 2023 +0200 Add operator "+" unit test commit 0da38ece7090b024298053cc6ee7fba1c4b05b3d Author: Foo Bar <foo@bar.buzz> Date: Tue Jun 27 01:10:10 2023 +0200 Add evaluator module, operator "+" commit fe22dec52bb37dba41e0f211c2c5ab9a0a90720d Author: Foo Bar <foo@bar.buzz> Date: Tue Jun 27 00:56:49 2023 +0200 Add args Python3 package commit d0dbc16408ef5bbe2c2949c8a123185ee3e2614c Author: Foo Bar <foo@bar.buzz> Date: Mon Jun 26 22:59:20 2023 +0200 Add license, readme
$ git show commit 2bd56ca80495fd03819b7a6fe842136593a2343d (HEAD -> master) Author: Foo Bar <foo@bar.buzz> Date: Tue Jun 27 01:20:38 2023 +0200 Add operator "+" unit test diff --git a/tests/test_sum.py b/tests/test_sum.py new file mode 100644 index 0000000..9699439 --- /dev/null +++ b/tests/test_sum.py @@ -0,0 +1,8 @@ +from unittest import TestCase + +from args.evaluator import ev + + +class TestEvaluator(TestCase): + def test_sum(self): + assert 6 == ev("+", 1, 2, 3)
$ git show HEAD^ commit 0da38ece7090b024298053cc6ee7fba1c4b05b3d Author: Foo Bar <foo@bar.buzz> Date: Tue Jun 27 01:10:10 2023 +0200 Add evaluator module, operator "+" diff --git a/args/evaluator.py b/args/evaluator.py new file mode 100644 index 0000000..13c2609 --- /dev/null +++ b/args/evaluator.py @@ -0,0 +1,6 @@ +def ev(op, *args): + if "+" == op: + s = 0 + for a in args: + s += a + return s
$ git logg * 2bd56ca (HEAD -> master) Add operator "+" unit test * 0da38ec Add evaluator module, operator "+" * fe22dec Add args Python3 package * d0dbc16 Add license, readme
A ještě schovám generované soubory, aby se mi nepletly.
$ git status On branch master Untracked files: (use "git add <file>..." to include in what will be committed) .gitignore nothing added to commit but untracked files present (use "git add" to track)
$ cat .gitignore __pycache__
$ git add .gitignore
$ git commit -m'Add gitignore' [master 1fe5611] Add gitignore 1 file changed, 1 insertion(+) create mode 100644 .gitignore
$ git show commit 1fe561194e50072a9895f44dc0ebec84a70b1faf (HEAD -> master) Author: Foo Bar <foo@bar.buzz> Date: Tue Jun 27 01:44:13 2023 +0200 Add gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bee8a64 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +__pycache__
$ git logg * 1fe5611 (HEAD -> master) Add gitignore * 096d3c8 Add operator "+" unit test * 0da38ec Add evaluator module, operator "+" * fe22dec Add args Python3 package * d0dbc16 Add license, readme
$ git status On branch master nothing to commit, working tree clean
Přidání operátoru "*"
editovatTrochu přeskupím historii -- když přidávám Python3 balíček, je jasné, že budu mít nějaké vygenerované soubory, které nechci ukládat do historie. Commit, který přidává .gitignore
přesunu těsně za commit s přidáním balíčku.
$ git rebase -i d0dbc16
Původní historii (zhora dolů) ...
pick fe22dec Add args Python3 package pick 0da38ec Add evaluator module, operator "+" pick 5d73571 Add operator "+" unit test pick 4450ade Add gitignore # Rebase d0dbc16..4450ade onto d0dbc16 (4 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. #
... upravím přehozením řádků.
pick fe22dec Add args Python3 package pick 4450ade Add gitignore pick 0da38ec Add evaluator module, operator "+" pick 5d73571 Add operator "+" unit test # Rebase d0dbc16..4450ade onto d0dbc16 (4 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. #
$ git rebase -i d0dbc16 Successfully rebased and updated refs/heads/master.
$ git logg * ac5242f (HEAD -> master) Add operator "+" unit test * 4cae1c7 Add evaluator module, operator "+" * 24784c8 Add gitignore * fe22dec Add args Python3 package * d0dbc16 Add license, readme
Asi bude lepší dát testy do jednoho souboru, kde se otestují všechny operátory. Opravím poslední commit.
$ git mv tests/test_sum.py tests/test_operators.py $ git status On branch master Changes to be committed: (use "git restore --staged <file>..." to unstage) renamed: tests/test_sum.py -> tests/test_operators.py
$ git commit --amend
Commit zprávu nechám.
Add operator "+" unit test # Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. # # Date: Tue Jun 27 01:20:38 2023 +0200 # # On branch master # Changes to be committed: # new file: tests/test_operators.py #
$ git commit --amend [master fdebe49] Add operator "+" unit test Date: Tue Jun 27 01:20:38 2023 +0200 1 file changed, 8 insertions(+) create mode 100644 tests/test_operators.py
$ git status On branch master nothing to commit, working tree clean
$ tree . ├── args │ ├── evaluator.py │ ├── __init__.py │ └── __pycache__ │ ├── evaluator.cpython-39.pyc │ └── __init__.cpython-39.pyc ├── LICENSE ├── README └── tests ├── __pycache__ │ └── test_sum.cpython-39.pyc └── test_operators.py 4 directories, 8 files
Přidám unit testy pro operátor "*".
$ git status On branch master 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: tests/test_operators.py no changes added to commit (use "git add" and/or "git commit -a")
$ git add tests/test_operators.py
$ git status On branch master Changes to be committed: (use "git restore --staged <file>..." to unstage) modified: tests/test_operators.py
$ git diff
$ git diff --cached diff --git a/tests/test_operators.py b/tests/test_operators.py index 9699439..b57f0f3 100644 --- a/tests/test_operators.py +++ b/tests/test_operators.py @@ -6,3 +6,6 @@ from args.evaluator import ev class TestEvaluator(TestCase): def test_sum(self): assert 6 == ev("+", 1, 2, 3) + + def test_prod(self): + assert 6 == ev("*", 1, 2, 3)
$ python3 -m unittest discover tests F. ====================================================================== FAIL: test_prod (test_operators.TestEvaluator) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/jiri/args/tests/test_operators.py", line 11, in test_prod assert 6 == ev("*", 1, 2, 3) AssertionError ---------------------------------------------------------------------- Ran 2 tests in 0.000s FAILED (failures=1)
$ git commit -m'Add operator "*" unit test' [master 865b12b] Add operator "*" unit test 1 file changed, 3 insertions(+)
$ git logg * 865b12b (HEAD -> master) Add operator "*" unit test * 44eda15 Add operator "+" unit test * 4cae1c7 Add evaluator module, operator "+" * 24784c8 Add gitignore * fe22dec Add args Python3 package * d0dbc16 Add license, readme
Implementuji operátor "*".
$ git diff diff --git a/args/evaluator.py b/args/evaluator.py index 13c2609..d964dca 100644 --- a/args/evaluator.py +++ b/args/evaluator.py @@ -4,3 +4,8 @@ def ev(op, *args): for a in args: s += a return s + elif "*" == op: + p = 1 + for a in args: + p *= a + return p
$ python3 -m unittest discover tests .. ---------------------------------------------------------------------- Ran 2 tests in 0.000s OK
$ git add args/evaluator.py $ git commit -m'Add operator "*"' [master d9212c1] Add operator "*" 1 file changed, 5 insertions(+)
$ git logg * d9212c1 (HEAD -> master) Add operator "*" * 865b12b Add operator "*" unit test * 44eda15 Add operator "+" unit test * 4cae1c7 Add evaluator module, operator "+" * 24784c8 Add gitignore * fe22dec Add args Python3 package * d0dbc16 Add license, readme
Podle Test Driven Development se testy píší před implementací, tak ať je to alespoň v historii správně.
$ git rebase -i d0dbc16
pick fe22dec Add args Python3 package pick 24784c8 Add gitignore pick 4cae1c7 Add evaluator module, operator "+" pick 44eda15 Add operator "+" unit test pick 865b12b Add operator "*" unit test pick d9212c1 Add operator "*" # Rebase d0dbc16..d9212c1 onto d0dbc16 (6 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. #
Přeskupit commity:
pick fe22dec Add args Python3 package pick 24784c8 Add gitignore pick 44eda15 Add operator "+" unit test pick 4cae1c7 Add evaluator module, operator "+" pick 865b12b Add operator "*" unit test pick d9212c1 Add operator "*" # Rebase d0dbc16..d9212c1 onto d0dbc16 (6 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. #
Výsledek rebase:
$ git rebase -i d0dbc16 Successfully rebased and updated refs/heads/master.
Aktuální historie:
$ git logg * 0681891 (HEAD -> master) Add operator "*" * 03b9ab3 Add operator "*" unit test * 5ed5048 Add evaluator module, operator "+" * e77e2a0 Add operator "+" unit test * 24784c8 Add gitignore * fe22dec Add args Python3 package * d0dbc16 Add license, readme
Nakonec ověřím, že všechny testy úspěšně projdou:
$ python3 -m unittest discover tests .. ---------------------------------------------------------------------- Ran 2 tests in 0.000s OK
Přidání docstringu pro "+" a "*" unit testy
editovatPřidám docstring pro test_operators
modul a pro test_sum
a test_prod
metody a změny přidám do historie.
$ git add -p tests/test_operators.py diff --git a/tests/test_operators.py b/tests/test_operators.py index b57f0f3..5dfc209 100644 --- a/tests/test_operators.py +++ b/tests/test_operators.py @@ -1,3 +1,4 @@ +"""Unit tests for the Evaluator's operators.""" from unittest import TestCase from args.evaluator import ev (1/2) Stage this hunk [y,n,q,a,d,j,J,g,/,e,?]? y @@ -5,7 +6,9 @@ from args.evaluator import ev class TestEvaluator(TestCase): def test_sum(self): + """Test the operator "+".""" assert 6 == ev("+", 1, 2, 3) def test_prod(self): + """Test the operator "*".""" assert 6 == ev("*", 1, 2, 3) (2/2) Stage this hunk [y,n,q,a,d,K,g,/,s,e,?]? s Split into 2 hunks. @@ -5,6 +6,7 @@ class TestEvaluator(TestCase): def test_sum(self): + """Test the operator "+".""" assert 6 == ev("+", 1, 2, 3) def test_prod(self): (2/3) Stage this hunk [y,n,q,a,d,K,j,J,g,/,e,?]? y @@ -8,4 +10,5 @@ assert 6 == ev("+", 1, 2, 3) def test_prod(self): + """Test the operator "*".""" assert 6 == ev("*", 1, 2, 3) (3/3) Stage this hunk [y,n,q,a,d,K,g,/,e,?]? n
git add -p
mi dovolí přidat jen některé změny v souboru. y
změnu přidá, n
změnu nepřidá a s
změnu rozdělí na menší změny, pokud je to možné.
Mimochodem, na aktuálním stavu repozitáře, jmenovitě na souboru test_operators.py
je krásně vidět rozdíl mezi změnami, které jsou připravené pro zápis do historie a mezi těmi, které ne.
$ git diff diff --git a/tests/test_operators.py b/tests/test_operators.py index a01cdb0..5dfc209 100644 --- a/tests/test_operators.py +++ b/tests/test_operators.py @@ -10,4 +10,5 @@ class TestEvaluator(TestCase): assert 6 == ev("+", 1, 2, 3) def test_prod(self): + """Test the operator "*".""" assert 6 == ev("*", 1, 2, 3)
$ git diff --cached diff --git a/tests/test_operators.py b/tests/test_operators.py index b57f0f3..a01cdb0 100644 --- a/tests/test_operators.py +++ b/tests/test_operators.py @@ -1,3 +1,4 @@ +"""Unit tests for the Evaluator's operators.""" from unittest import TestCase from args.evaluator import ev @@ -5,6 +6,7 @@ from args.evaluator import ev class TestEvaluator(TestCase): def test_sum(self): + """Test the operator "+".""" assert 6 == ev("+", 1, 2, 3) def test_prod(self):
$ git status On branch master Changes to be committed: (use "git restore --staged <file>..." to unstage) modified: tests/test_operators.py 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: tests/test_operators.py
Změnu dělám proto, abych opravil změnu, která v historii už je -- docstring by měl být součástí změny, která přidává modul a testovací metodu. Proto vypadá zpráva změny trochu divně:
$ git commit -m'F e77e2a0' [master c823f04] F e77e2a0 1 file changed, 2 insertions(+)
Pak přidám druhou změnu, opravující druhou změnu v historii.
$ git add tests/test_operators.py
$ git diff --cached diff --git a/tests/test_operators.py b/tests/test_operators.py index a01cdb0..5dfc209 100644 --- a/tests/test_operators.py +++ b/tests/test_operators.py @@ -10,4 +10,5 @@ class TestEvaluator(TestCase): assert 6 == ev("+", 1, 2, 3) def test_prod(self): + """Test the operator "*".""" assert 6 == ev("*", 1, 2, 3)
$ git commit -m'F 03b9ab3' [master a7f67a9] F 03b9ab3 1 file changed, 1 insertion(+)
$ git status On branch master nothing to commit, working tree clean
$ git logg * a7f67a9 (HEAD -> master) F 03b9ab3 * c823f04 F e77e2a0 * 0681891 Add operator "*" * 03b9ab3 Add operator "*" unit test * 5ed5048 Add evaluator module, operator "+" * e77e2a0 Add operator "+" unit test * 24784c8 Add gitignore * fe22dec Add args Python3 package * d0dbc16 Add license, readme
Nakonec přepíšu historii tak, aby obsahovala opravené změny.
$ git rebase -i 24784c8
V interaktivním rebase změním
pick e77e2a0 Add operator "+" unit test pick 5ed5048 Add evaluator module, operator "+" pick 03b9ab3 Add operator "*" unit test pick 0681891 Add operator "*" pick c823f04 F e77e2a0 pick a7f67a9 F 03b9ab3 # Rebase 24784c8..a7f67a9 onto 24784c8 (6 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. #
na
pick e77e2a0 Add operator "+" unit test f c823f04 F e77e2a0 pick 5ed5048 Add evaluator module, operator "+" pick 03b9ab3 Add operator "*" unit test f a7f67a9 F 03b9ab3 pick 0681891 Add operator "*" # Rebase 24784c8..a7f67a9 onto 24784c8 (6 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. #
což krásně ukazuje, proč jsou "divné" zprávy změn užitečné. (F
je zkratka pro FIX.)
Při interaktivním rebase, tj. rebase -i IDENTIFIKATOR-ZMENY
, se otevře textový editor se seznamem změn, které se aplikují na změnu IDENTIFIKATOR-ZMENY
postupně zhora dolů. To, že se aplikují, je proto, že před každou změnou je pick
. Další možnosti, které jde napsat místo pick
, jsou uvedené jako komentář. Já použiji f
(jako fixup
). f
začlení změnu (commit) do předchozí (změna na předchozím řádku) a nechá commit message stejnou (jako na předchozím řádku). Možná ještě jiný pohled -- při rebase se změny pick
aplikují zhora dolů. Pokud je po pick
změna f
, je to jako bych v tu chvíli udělal git commit --amend
. f
změn může být pod sebou více.
$ git rebase -i 24784c8 Successfully rebased and updated refs/heads/master.
$ git status On branch master nothing to commit, working tree clean
$ git logg * f8467dc (HEAD -> master) Add operator "*" * 4e81de9 Add operator "*" unit test * 2eaeb68 Add evaluator module, operator "+" * 0715dc9 Add operator "+" unit test * 24784c8 Add gitignore * fe22dec Add args Python3 package * d0dbc16 Add license, readme
$ git show 0715dc9 commit 0715dc9c3bae0e38f6e7498c9a363352855b14c6 Author: Foo Bar <foo@bar.buzz> Date: Tue Jun 27 01:20:38 2023 +0200 Add operator "+" unit test diff --git a/tests/test_operators.py b/tests/test_operators.py new file mode 100644 index 0000000..a8f199e --- /dev/null +++ b/tests/test_operators.py @@ -0,0 +1,10 @@ +"""Unit tests for the Evaluator's operators.""" +from unittest import TestCase + +from args.evaluator import ev + + +class TestEvaluator(TestCase): + def test_sum(self): + """Test the operator "+".""" + assert 6 == ev("+", 1, 2, 3)
$ git show 4e81de9 commit 4e81de9f7c30480f3639e7822f233740f59be746 Author: Foo Bar <foo@bar.buzz> Date: Wed Jun 28 01:11:46 2023 +0200 Add operator "*" unit test diff --git a/tests/test_operators.py b/tests/test_operators.py index a8f199e..5dfc209 100644 --- a/tests/test_operators.py +++ b/tests/test_operators.py @@ -8,3 +8,7 @@ class TestEvaluator(TestCase): def test_sum(self): """Test the operator "+".""" assert 6 == ev("+", 1, 2, 3) + + def test_prod(self): + """Test the operator "*".""" + assert 6 == ev("*", 1, 2, 3)
Alternativní historie
editovatAktuálně je historie přímočará a můžu se v ní pohybovat.
$ git logg * f8467dc (HEAD -> master) Add operator "*" * 4e81de9 Add operator "*" unit test * 2eaeb68 Add evaluator module, operator "+" * 0715dc9 Add operator "+" unit test * 24784c8 Add gitignore * fe22dec Add args Python3 package * d0dbc16 Add license, readme
$ tree . ├── args │ ├── evaluator.py │ ├── __init__.py │ └── __pycache__ │ ├── evaluator.cpython-39.pyc │ └── __init__.cpython-39.pyc ├── LICENSE ├── README └── tests ├── __pycache__ │ ├── test_operators.cpython-39.pyc │ └── test_sum.cpython-39.pyc └── test_operators.py 4 directories, 9 files
$ git checkout 24784c8 Note: switching to '24784c8'. You are in 'detached HEAD' state. You can look around, make experimental changes and commit them, and you can discard any commits you make in this state without impacting any branches by switching back to a branch. If you want to create a new branch to retain commits you create, you may do so (now or later) by using -c with the switch command. Example: git switch -c <new-branch-name> Or undo this operation with: git switch - Turn off this advice by setting config variable advice.detachedHead to false HEAD is now at 24784c8 Add gitignore
$ git logg * f8467dc (master) Add operator "*" * 4e81de9 Add operator "*" unit test * 2eaeb68 Add evaluator module, operator "+" * 0715dc9 Add operator "+" unit test * 24784c8 (HEAD) Add gitignore * fe22dec Add args Python3 package * d0dbc16 Add license, readme
$ tree . ├── args │ ├── __init__.py │ └── __pycache__ │ ├── evaluator.cpython-39.pyc │ └── __init__.cpython-39.pyc ├── LICENSE ├── README └── tests └── __pycache__ ├── test_operators.cpython-39.pyc └── test_sum.cpython-39.pyc 4 directories, 7 files
HEAD
znamená změnu (commit), kde v historii právě jsem. master
je větev -- jméno pro změnu (commit), ze které historii vytvářím (přidáním dalších změn). Větví, tedy změn, ze kterých vytvářím historii, může být více.
$ git checkout master Previous HEAD position was 24784c8 Add gitignore Switched to branch 'master'
$ git logg * f8467dc (HEAD -> master) Add operator "*" * 4e81de9 Add operator "*" unit test * 2eaeb68 Add evaluator module, operator "+" * 0715dc9 Add operator "+" unit test * 24784c8 Add gitignore * fe22dec Add args Python3 package * d0dbc16 Add license, readme
$ git branch add-sum-and-prod-operators
$ git logg * f8467dc (HEAD -> master, add-sum-and-prod-operators) Add operator "*" * 4e81de9 Add operator "*" unit test * 2eaeb68 Add evaluator module, operator "+" * 0715dc9 Add operator "+" unit test * 24784c8 Add gitignore * fe22dec Add args Python3 package * d0dbc16 Add license, readme
Větev mohu nastavit na libovolnou změnu v historii. (POZOR! Pokud jsou v repozitáři změny, které jsou vidět pomocí git diff
nebo git diff --cached
, tyto budou ztraceny!)
$ git reset --hard 24784c8 HEAD is now at 24784c8 Add gitignore
$ git logg * f8467dc (add-sum-and-prod-operators) Add operator "*" * 4e81de9 Add operator "*" unit test * 2eaeb68 Add evaluator module, operator "+" * 0715dc9 Add operator "+" unit test * 24784c8 (HEAD -> master) Add gitignore * fe22dec Add args Python3 package * d0dbc16 Add license, readme
Mezi větvemi se mohu pohybovat, jako se mohu pohybovat mezi změnami (commit) v historii. Konec konců, větve jsou jména pro změny.
$ git checkout add-sum-and-prod-operators Switched to branch 'add-sum-and-prod-operators'
$ git logg * f8467dc (HEAD -> add-sum-and-prod-operators) Add operator "*" * 4e81de9 Add operator "*" unit test * 2eaeb68 Add evaluator module, operator "+" * 0715dc9 Add operator "+" unit test * 24784c8 (master) Add gitignore * fe22dec Add args Python3 package * d0dbc16 Add license, readme
$ git checkout master Switched to branch 'master'
$ git logg * f8467dc (add-sum-and-prod-operators) Add operator "*" * 4e81de9 Add operator "*" unit test * 2eaeb68 Add evaluator module, operator "+" * 0715dc9 Add operator "+" unit test * 24784c8 (HEAD -> master) Add gitignore * fe22dec Add args Python3 package * d0dbc16 Add license, readme
A konečně, větve mohu spojovat.
$ git merge --no-ff add-sum-and-prod-operators
Merge branch 'add-sum-and-prod-operators' # 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.
$ git merge --no-ff add-sum-and-prod-operators Merge made by the 'recursive' strategy. args/evaluator.py | 11 +++++++++++ tests/test_operators.py | 14 ++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 args/evaluator.py create mode 100644 tests/test_operators.py
$ git logg * 8febb4c (HEAD -> master) Merge branch 'add-sum-and-prod-operators' |\ | * f8467dc (add-sum-and-prod-operators) Add operator "*" | * 4e81de9 Add operator "*" unit test | * 2eaeb68 Add evaluator module, operator "+" | * 0715dc9 Add operator "+" unit test |/ * 24784c8 Add gitignore * fe22dec Add args Python3 package * d0dbc16 Add license, readme
Přesnější je říci, že jednu větev (v tomto případě add-sum-and-prod-operators
) začlením do jiné, aktuální větve (master
).
Takovým způsobem většinou funguje vývoj nové funkce. Když je dočasná větev (add-sum-and-prod-operators
) začleněna do hlavní větve (master
), už není potřeba a smažu ji.
$ git branch -d add-sum-and-prod-operators Deleted branch add-sum-and-prod-operators (was f8467dc).
$ git logg * 8febb4c (HEAD -> master) Merge branch 'add-sum-and-prod-operators' |\ | * f8467dc Add operator "*" | * 4e81de9 Add operator "*" unit test | * 2eaeb68 Add evaluator module, operator "+" | * 0715dc9 Add operator "+" unit test |/ * 24784c8 Add gitignore * fe22dec Add args Python3 package * d0dbc16 Add license, readme
Konfliktní historie
editovatZbývá přidat operátory "<" a ">". Vývoj provedu v nových větvích, vytvořím tedy dvě alternativní historie. Každá větev bude obsahovat dvě změny (commit) -- jednu pro unit test, druhou pro implementaci.
$ git branch add-non-desc-op
$ git checkout add-non-desc-op Switched to branch 'add-non-desc-op'
$ git logg * 8febb4c (HEAD -> add-non-desc-op, master) Merge branch 'add-sum-and-prod-operators' |\ | * f8467dc Add operator "*" | * 4e81de9 Add operator "*" unit test | * 2eaeb68 Add evaluator module, operator "+" | * 0715dc9 Add operator "+" unit test |/ * 24784c8 Add gitignore * fe22dec Add args Python3 package * d0dbc16 Add license, readme
$ git diff diff --git a/tests/test_operators.py b/tests/test_operators.py index 5dfc209..0056ab1 100644 --- a/tests/test_operators.py +++ b/tests/test_operators.py @@ -12,3 +12,9 @@ class TestEvaluator(TestCase): def test_prod(self): """Test the operator "*".""" assert 6 == ev("*", 1, 2, 3) + + def test_non_desc(self): + """Test the operator "<".""" + assert ev("<", 1, 2, 3) + assert ev("<", 1, 1, 3) + assert not ev("<", 3, 2, 1)
$ git add tests/test_operators.py
$ git commit -m'Add operator "<" unit test' [add-non-desc-op 4d80713] Add operator "<" unit test 1 file changed, 6 insertions(+)
$ git logg * 4d80713 (HEAD -> add-non-desc-op) Add operator "<" unit test * 8febb4c (master) Merge branch 'add-sum-and-prod-operators' |\ | * f8467dc Add operator "*" | * 4e81de9 Add operator "*" unit test | * 2eaeb68 Add evaluator module, operator "+" | * 0715dc9 Add operator "+" unit test |/ * 24784c8 Add gitignore * fe22dec Add args Python3 package * d0dbc16 Add license, readme
$ python3 -m unittest discover tests F.. ====================================================================== FAIL: test_non_desc (test_operators.TestEvaluator) Test the operator "<". ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/jiri/args/tests/test_operators.py", line 18, in test_non_desc assert ev("<", 1, 2, 3) AssertionError ---------------------------------------------------------------------- Ran 3 tests in 0.001s FAILED (failures=1)
Teď mě napadá, že jsem zapomněl do README napsat, jak se spouští testy. A to by mělo být v hlavní vývojové větvi.
$ git checkout master Switched to branch 'master'
$ git diff diff --git a/README b/README index 4e3d26f..470c1a1 100644 --- a/README +++ b/README @@ -1,2 +1,6 @@ Python3 package with the procedure evaluating arguments based on the operator. + +Run tests: + + python3 -m unittest discover tests
$ git add README
$ git commit -m'Update README with how to run tests' [master 250bc4e] Update README with how to run tests 1 file changed, 4 insertions(+)
$ git logg * 250bc4e (HEAD -> master) Update README with how to run tests | * 4d80713 (add-non-desc-op) Add operator "<" unit test |/ * 8febb4c Merge branch 'add-sum-and-prod-operators' |\ | * f8467dc Add operator "*" | * 4e81de9 Add operator "*" unit test | * 2eaeb68 Add evaluator module, operator "+" | * 0715dc9 Add operator "+" unit test |/ * 24784c8 Add gitignore * fe22dec Add args Python3 package * d0dbc16 Add license, readme
A zpátky k operátoru "<".
$ git checkout add-non-desc-op Switched to branch 'add-non-desc-op'
$ git logg * 250bc4e (master) Update README with how to run tests | * 4d80713 (HEAD -> add-non-desc-op) Add operator "<" unit test |/ * 8febb4c Merge branch 'add-sum-and-prod-operators' |\ | * f8467dc Add operator "*" | * 4e81de9 Add operator "*" unit test | * 2eaeb68 Add evaluator module, operator "+" | * 0715dc9 Add operator "+" unit test |/ * 24784c8 Add gitignore * fe22dec Add args Python3 package * d0dbc16 Add license, readme
$ git diff diff --git a/args/evaluator.py b/args/evaluator.py index d964dca..1397bec 100644 --- a/args/evaluator.py +++ b/args/evaluator.py @@ -9,3 +9,8 @@ def ev(op, *args): for a in args: p *= a return p + elif "<" == op: + for i in range(1, len(args)): + if args[i - 1] > args[i]: + return False + return True
$ git commit -m'Implement operator "<"' On branch add-non-desc-op 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: args/evaluator.py no changes added to commit (use "git add" and/or "git commit -a")
Vlastně ještě přidat soubor.
$ git add args/evaluator.py
$ git commit -m'Implement operator "<"' [add-non-desc-op 715cfee] Implement operator "<" 1 file changed, 5 insertions(+)
$ git logg * 715cfee (HEAD -> add-non-desc-op) Implement operator "<" * 4d80713 Add operator "<" unit test | * 250bc4e (master) Update README with how to run tests |/ * 8febb4c Merge branch 'add-sum-and-prod-operators' |\ | * f8467dc Add operator "*" | * 4e81de9 Add operator "*" unit test | * 2eaeb68 Add evaluator module, operator "+" | * 0715dc9 Add operator "+" unit test |/ * 24784c8 Add gitignore * fe22dec Add args Python3 package * d0dbc16 Add license, readme
$ python3 -m unittest discover tests ... ---------------------------------------------------------------------- Ran 3 tests in 0.000s OK
Nakonec operátor ">". Větev by měl začínat ze stejné změny jako operátor "<".
$ git branch add-non-incr-op 8febb4c
$ git checkout add-non-incr-op Switched to branch 'add-non-incr-op'
$ git logg * 715cfee (add-non-desc-op) Implement operator "<" * 4d80713 Add operator "<" unit test | * 250bc4e (master) Update README with how to run tests |/ * 8febb4c (HEAD -> add-non-incr-op) Merge branch 'add-sum-and-prod-operators' |\ | * f8467dc Add operator "*" | * 4e81de9 Add operator "*" unit test | * 2eaeb68 Add evaluator module, operator "+" | * 0715dc9 Add operator "+" unit test |/ * 24784c8 Add gitignore * fe22dec Add args Python3 package * d0dbc16 Add license, readme
$ git diff diff --git a/args/evaluator.py b/args/evaluator.py index d964dca..adfe8e2 100644 --- a/args/evaluator.py +++ b/args/evaluator.py @@ -9,3 +9,8 @@ def ev(op, *args): for a in args: p *= a return p + elif ">" == op: + for i in range(1, len(args)): + if args[i - 1] < args[i]: + return False + return True diff --git a/tests/test_operators.py b/tests/test_operators.py index 5dfc209..4c75980 100644 --- a/tests/test_operators.py +++ b/tests/test_operators.py @@ -12,3 +12,9 @@ class TestEvaluator(TestCase): def test_prod(self): """Test the operator "*".""" assert 6 == ev("*", 1, 2, 3) + + def test_non_incr(self): + """Test the operator ">".""" + assert ev(">", 3, 2, 1) + assert ev(">", 3, 2, 2) + assert not ev(">", 1, 2, 3)
$ git add -p diff --git a/args/evaluator.py b/args/evaluator.py index d964dca..adfe8e2 100644 --- a/args/evaluator.py +++ b/args/evaluator.py @@ -9,3 +9,8 @@ def ev(op, *args): for a in args: p *= a return p + elif ">" == op: + for i in range(1, len(args)): + if args[i - 1] < args[i]: + return False + return True (1/1) Stage this hunk [y,n,q,a,d,e,?]? n diff --git a/tests/test_operators.py b/tests/test_operators.py index 5dfc209..4c75980 100644 --- a/tests/test_operators.py +++ b/tests/test_operators.py @@ -12,3 +12,9 @@ class TestEvaluator(TestCase): def test_prod(self): """Test the operator "*".""" assert 6 == ev("*", 1, 2, 3) + + def test_non_incr(self): + """Test the operator ">".""" + assert ev(">", 3, 2, 1) + assert ev(">", 3, 2, 2) + assert not ev(">", 1, 2, 3) (1/1) Stage this hunk [y,n,q,a,d,e,?]? y
$ git diff --cached diff --git a/tests/test_operators.py b/tests/test_operators.py index 5dfc209..4c75980 100644 --- a/tests/test_operators.py +++ b/tests/test_operators.py @@ -12,3 +12,9 @@ class TestEvaluator(TestCase): def test_prod(self): """Test the operator "*".""" assert 6 == ev("*", 1, 2, 3) + + def test_non_incr(self): + """Test the operator ">".""" + assert ev(">", 3, 2, 1) + assert ev(">", 3, 2, 2) + assert not ev(">", 1, 2, 3)
$ git commit -m'Add operator ">" unit test' [add-non-incr-op 676ab0f] Add operator ">" unit test 1 file changed, 6 insertions(+)
$ git diff diff --git a/args/evaluator.py b/args/evaluator.py index d964dca..adfe8e2 100644 --- a/args/evaluator.py +++ b/args/evaluator.py @@ -9,3 +9,8 @@ def ev(op, *args): for a in args: p *= a return p + elif ">" == op: + for i in range(1, len(args)): + if args[i - 1] < args[i]: + return False + return True
$ git add args/evaluator.py
$ git commit -m'Implement operator ">"' [add-non-incr-op 7d1e491] Implement operator ">" 1 file changed, 5 insertions(+)
$ git logg * 7d1e491 (HEAD -> add-non-incr-op) Implement operator ">" * 676ab0f Add operator ">" unit test | * 715cfee (add-non-desc-op) Implement operator "<" | * 4d80713 Add operator "<" unit test |/ | * 250bc4e (master) Update README with how to run tests |/ * 8febb4c Merge branch 'add-sum-and-prod-operators' |\ | * f8467dc Add operator "*" | * 4e81de9 Add operator "*" unit test | * 2eaeb68 Add evaluator module, operator "+" | * 0715dc9 Add operator "+" unit test |/ * 24784c8 Add gitignore * fe22dec Add args Python3 package * d0dbc16 Add license, readme
Nezbývá než začlenit dočasné vývojové větve do hlavní větve. Každý, kdo vytváří větve, by měl pochopit, že cíl je větev začlenit.
$ git checkout master Switched to branch 'master'
$ git logg * 7d1e491 (add-non-incr-op) Implement operator ">" * 676ab0f Add operator ">" unit test | * 715cfee (add-non-desc-op) Implement operator "<" | * 4d80713 Add operator "<" unit test |/ | * 250bc4e (HEAD -> master) Update README with how to run tests |/ * 8febb4c Merge branch 'add-sum-and-prod-operators' |\ | * f8467dc Add operator "*" | * 4e81de9 Add operator "*" unit test | * 2eaeb68 Add evaluator module, operator "+" | * 0715dc9 Add operator "+" unit test |/ * 24784c8 Add gitignore * fe22dec Add args Python3 package * d0dbc16 Add license, readme
$ git merge --no-ff add-non-desc-op add-non-incr-op Trying simple merge with add-non-desc-op Trying simple merge with add-non-incr-op Simple merge did not work, trying automatic merge. Auto-merging args/evaluator.py ERROR: content conflict in args/evaluator.py Auto-merging tests/test_operators.py ERROR: content conflict in tests/test_operators.py fatal: merge program failed Automatic merge failed; fix conflicts and then commit the result.
Konflikt znamená, že git si neví rady, jakým způsobem spojit alternativní historie. V tomhle případě je to jednoduché, protože chci oba dva operátory včetně unit testů.
$ git status On branch master You have unmerged paths. (fix conflicts and run "git commit") (use "git merge --abort" to abort the merge) Unmerged paths: (use "git add <file>..." to mark resolution) both modified: args/evaluator.py both modified: tests/test_operators.py no changes added to commit (use "git add" and/or "git commit -a")
$ git diff diff --cc args/evaluator.py index 1397bec,adfe8e2..0000000 --- a/args/evaluator.py +++ b/args/evaluator.py @@@ -9,8 -9,8 +9,14 @@@ def ev(op, *args) for a in args: p *= a return p ++<<<<<<< .merge_file_w7odEj + elif "<" == op: + for i in range(1, len(args)): + if args[i - 1] > args[i]: ++======= + elif ">" == op: + for i in range(1, len(args)): + if args[i - 1] < args[i]: ++>>>>>>> .merge_file_sUueSl return False return True diff --cc tests/test_operators.py index 0056ab1,4c75980..0000000 --- a/tests/test_operators.py +++ b/tests/test_operators.py @@@ -13,8 -13,8 +13,16 @@@ class TestEvaluator(TestCase) """Test the operator "*".""" assert 6 == ev("*", 1, 2, 3) ++<<<<<<< .merge_file_PX9087 + def test_non_desc(self): + """Test the operator "<".""" + assert ev("<", 1, 2, 3) + assert ev("<", 1, 1, 3) + assert not ev("<", 3, 2, 1) ++======= + def test_non_incr(self): + """Test the operator ">".""" + assert ev(">", 3, 2, 1) + assert ev(">", 3, 2, 2) + assert not ev(">", 1, 2, 3) ++>>>>>>> .merge_file_Tlr21b
$ git status On branch master You have unmerged paths. (fix conflicts and run "git commit") (use "git merge --abort" to abort the merge) Unmerged paths: (use "git add <file>..." to mark resolution) both modified: args/evaluator.py both modified: tests/test_operators.py no changes added to commit (use "git add" and/or "git commit -a")
$ git diff diff --cc args/evaluator.py index 1397bec,adfe8e2..0000000 --- a/args/evaluator.py +++ b/args/evaluator.py @@@ -9,8 -9,8 +9,13 @@@ def ev(op, *args) for a in args: p *= a return p + elif "<" == op: + for i in range(1, len(args)): + if args[i - 1] > args[i]: + return False + return True + elif ">" == op: + for i in range(1, len(args)): + if args[i - 1] < args[i]: + return False + return True diff --cc tests/test_operators.py index 0056ab1,4c75980..0000000 --- a/tests/test_operators.py +++ b/tests/test_operators.py @@@ -13,8 -13,8 +13,14 @@@ class TestEvaluator(TestCase) """Test the operator "*".""" assert 6 == ev("*", 1, 2, 3) + def test_non_desc(self): + """Test the operator "<".""" + assert ev("<", 1, 2, 3) + assert ev("<", 1, 1, 3) + assert not ev("<", 3, 2, 1) ++ + def test_non_incr(self): + """Test the operator ">".""" + assert ev(">", 3, 2, 1) + assert ev(">", 3, 2, 2) + assert not ev(">", 1, 2, 3)
$ python3 -m unittest discover tests .... ---------------------------------------------------------------------- Ran 4 tests in 0.000s OK
$ git status On branch master You have unmerged paths. (fix conflicts and run "git commit") (use "git merge --abort" to abort the merge) Unmerged paths: (use "git add <file>..." to mark resolution) both modified: args/evaluator.py both modified: tests/test_operators.py no changes added to commit (use "git add" and/or "git commit -a")
$ git add args/evaluator.py tests/test_operators.py
$ git status On branch master All conflicts fixed but you are still merging. (use "git commit" to conclude merge) Changes to be committed: modified: args/evaluator.py modified: tests/test_operators.py
$ git diff --cached diff --git a/args/evaluator.py b/args/evaluator.py index d964dca..b00bfab 100644 --- a/args/evaluator.py +++ b/args/evaluator.py @@ -9,3 +9,13 @@ def ev(op, *args): for a in args: p *= a return p + elif "<" == op: + for i in range(1, len(args)): + if args[i - 1] > args[i]: + return False + return True + elif ">" == op: + for i in range(1, len(args)): + if args[i - 1] < args[i]: + return False + return True diff --git a/tests/test_operators.py b/tests/test_operators.py index 5dfc209..114275b 100644 --- a/tests/test_operators.py +++ b/tests/test_operators.py @@ -12,3 +12,15 @@ class TestEvaluator(TestCase): def test_prod(self): """Test the operator "*".""" assert 6 == ev("*", 1, 2, 3) + + def test_non_desc(self): + """Test the operator "<".""" + assert ev("<", 1, 2, 3) + assert ev("<", 1, 1, 3) + assert not ev("<", 3, 2, 1) + + def test_non_incr(self): + """Test the operator ">".""" + assert ev(">", 3, 2, 1) + assert ev(">", 3, 2, 2) + assert not ev(">", 1, 2, 3)
$ git merge --continue
Merge branches 'add-non-desc-op' and 'add-non-incr-op' # Conflicts: # args/evaluator.py # tests/test_operators.py # # It looks like you may be committing a merge. # If this is not correct, please run # git update-ref -d MERGE_HEAD # and try again. # Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. # # On branch master # All conflicts fixed but you are still merging. # # Changes to be committed: # modified: args/evaluator.py # modified: tests/test_operators.py #
$ git merge --continue [master 3ef21b4] Merge branches 'add-non-desc-op' and 'add-non-incr-op'
$ git status On branch master nothing to commit, working tree clean
$ git logg *-. 3ef21b4 (HEAD -> master) Merge branches 'add-non-desc-op' and 'add-non-incr-op' |\ \ | | * 7d1e491 (add-non-incr-op) Implement operator ">" | | * 676ab0f Add operator ">" unit test | * | 715cfee (add-non-desc-op) Implement operator "<" | * | 4d80713 Add operator "<" unit test | |/ * / 250bc4e Update README with how to run tests |/ * 8febb4c Merge branch 'add-sum-and-prod-operators' |\ | * f8467dc Add operator "*" | * 4e81de9 Add operator "*" unit test | * 2eaeb68 Add evaluator module, operator "+" | * 0715dc9 Add operator "+" unit test |/ * 24784c8 Add gitignore * fe22dec Add args Python3 package * d0dbc16 Add license, readme
$ python3 -m unittest discover tests .... ---------------------------------------------------------------------- Ran 4 tests in 0.000s OK
Vymazat dočasné vývojové větve.
$ git branch -d add-non-desc-op add-non-incr-op Deleted branch add-non-desc-op (was 715cfee). Deleted branch add-non-incr-op (was 7d1e491).
$ git logg *-. 3ef21b4 (HEAD -> master) Merge branches 'add-non-desc-op' and 'add-non-incr-op' |\ \ | | * 7d1e491 Implement operator ">" | | * 676ab0f Add operator ">" unit test | * | 715cfee Implement operator "<" | * | 4d80713 Add operator "<" unit test | |/ * / 250bc4e Update README with how to run tests |/ * 8febb4c Merge branch 'add-sum-and-prod-operators' |\ | * f8467dc Add operator "*" | * 4e81de9 Add operator "*" unit test | * 2eaeb68 Add evaluator module, operator "+" | * 0715dc9 Add operator "+" unit test |/ * 24784c8 Add gitignore * fe22dec Add args Python3 package * d0dbc16 Add license, readme
$ git show commit 3ef21b4a5bb92bd014838709945c7fcf89341fd6 (HEAD -> master) Merge: 250bc4e 715cfee 7d1e491 Author: Foo Bar <foo@bar.buzz> Date: Thu Jun 29 00:48:53 2023 +0200 Merge branches 'add-non-desc-op' and 'add-non-incr-op' diff --cc args/evaluator.py index d964dca,1397bec,adfe8e2..b00bfab --- a/args/evaluator.py +++ b/args/evaluator.py @@@@ -9,3 -9,8 -9,8 +9,13 @@@@ def ev(op, *args) for a in args: p *= a return p + + elif "<" == op: + + for i in range(1, len(args)): + + if args[i - 1] > args[i]: + + return False + + return True ++ elif ">" == op: ++ for i in range(1, len(args)): ++ if args[i - 1] < args[i]: ++ return False ++ return True diff --cc tests/test_operators.py index 5dfc209,0056ab1,4c75980..114275b --- a/tests/test_operators.py +++ b/tests/test_operators.py @@@@ -12,3 -12,9 -12,9 +12,15 @@@@ class TestEvaluator(TestCase) def test_prod(self): """Test the operator "*".""" assert 6 == ev("*", 1, 2, 3) + + + def test_non_desc(self): + + """Test the operator "<".""" + + assert ev("<", 1, 2, 3) + + assert ev("<", 1, 1, 3) + + assert not ev("<", 3, 2, 1) +++ ++ def test_non_incr(self): ++ """Test the operator ">".""" ++ assert ev(">", 3, 2, 1) ++ assert ev(">", 3, 2, 2) ++ assert not ev(">", 1, 2, 3)
$ git status On branch master nothing to commit, working tree clean
Použité příkazy
editovatInicializace repozitáře:
$ git init $ git config user.email 'foo@bar.buzz' $ git config --global user.name 'Foo Bar'
Přidání souborů, prozkoumání repozitáře, nastavení editoru a aliasu:
$ git status $ git add JMENO-SOUBORU $ git diff --cached $ git commit $ git config --global core.editor 'vim' $ git log $ git show $ git log --oneline --graph --decorate --all
$ git config --global --add alias.logg 'log --oneline --graph --decorate --all' $ git logg
$ python3 -m unittest discover tests $ git show HEAD^ $ git commit -m'52 znaků dokončujících větu'
Přeskupení a oprava historie:
$ git rebase -i IDENTIFIKATOR-ZMENY $ git mv STARE-JMENO-SOUBORU NOVE-JMENO-SOUBORU $ git commit --amend
$ git add -p JMENO-SOUBORU $ git commit -m'F IDENTIFIKATOR-ZMENY'
Alternativní historie (branch):
$ git checkout IDENTIFIKATOR-ZMENY $ git branch JMENO-NOVE-VETVE $ git reset --hard IDENTIFIKATOR-ZMENY $ git checkout JMENO-VETVE $ git merge --no-ff JMENO-VETVE $ git branch -d JMENO-VETVE
Konfliktní historie:
$ git branch JMENO-NOVE-VETVE IDENTIFIKATOR-ZMENY $ git add -p $ git merge --no-ff JMENO-PRVNI-VETVE JMENO-DRUHE-VETVE $ git merge --continue $ git branch -d JMENO-PRVNI-VETVE JMENO-DRUHE-VETVE