%%{init: {'theme': 'neutral', 'look': 'handDrawn'}}%%
flowchart LR
A[Message] -->|encrypt| B[Encrypted message]
B -->|decrypt| C[Original Message]
2024-10-30
0x... or just numbers and abcdef/ABCDEF combined|, one can pipe from one command to anotherdiff generates a diff-file between two files, patch applies that diff-file %%{init: {'theme': 'neutral', 'look': 'handDrawn'}}%%
flowchart LR
A[Message] -->|encrypt| B[Encrypted message]
B -->|decrypt| C[Original Message]
(Ultimate) design goal for Cryptography
Additional goals:
(Quantum Cryptography: guarantee that only one party has received message)
Encryption (encoding) and decryption (decoding) happens with keys.
Only 100% secure (non-quantum) encryption: truly random one-time pads (iff pads themselves are not compromised).
In practice: pseudo-random keys, lots of maths trying to make things as safe as possible.
Breaking this code will take 100 times the age of the universe***
Cryptography is a field in itself (within mathematics)
Like a safe with a limited number of keys (typically: two). When you open the safe and it contains a message that is not from you, it has to be put in there by the other key owner.
Problem:
Used in two ways:
In practice (often):
Asymmetric encryption (non)problems:
Public Key Infrastructure (PKI) helps a bit:
“A hash function is any function that can be used to map data of arbitrary size to fixed-size values” (wikipedia)
f(byte[16]) -> byte[16]
f(byte[32]) -> byte[16]
f(byte[1000]) -> byte[16]
f(byte[0xffffffff]) -> byte[16]
f(byte[1]) -> byte[16]
f(byte[0]) -> byte[16]Note: if we are to hash 4GB into 16 bytes, we obviously loose data; so a “reverse hash function” doesn’t exist (unless input is a limited list)
Some examples (to use on The Raven)?
A hashing function takes (an arbitrary number of, incl 0) bytes as input and returns (a predefined number of) bytes as output.
A file on the computer (and any data in memory) are just bytes, so you can hash anything on your computer:
.docx word document.pdf fileYou can also hash multiple files (with some tricks) into a single hash.
In practice a “good” hash function:
If you choose the right function:
Some examples: CRC-32, MD5, SHA1, SHA2, SHA3, SHA256, SHA512
These hash functions are open source and determinate; every (correct) implementation has the same output for the same input
Secure hashing is a field in itself (within mathematics; NIST)
For “practical (non security) use”, you can take any of these and assume the following:
Take away: a hash is a “proxy” that points to (one unique; or more) item. Git uses hashing (SHA) extensively
Base16:▕ 1 ▕ c ▕ 6 ▕ 1 ▕ 7 ▕ a ▕ 0 ▕ f ▕ c ▕ 0 ▕ 1 ▕ c ▕ 0 ▕ 8 ▕ 9 ▕ 6 ▕
Memory: 0001110001100001011110100000111111000000000111000000100001100000
Bytes: ▕ ▕ ▕ ▕ ▕ ▕ ▕ ▕ ▕
Bytes: (28) (61) (122) (15) (192) (28) (8) (96)
Bytes: (0x1c) (0x61) (0x7a) (0x0f) (0xc0) (0x1c) (0x08) (0x60)
Ascii: {FS} = z {SI} {?} {FS} {BS} `
Ascii: ".=z....`"
Latin_1: ".=z.À..`"
Latin_2: ".=z.Ŕ..`"
Hex: 0x1c617a0fc01c0860 (or 0x1C617A0FC01C0860)
Decimal: 2045049913869076576</code></pre>Normally length is in bits or bytes. Therefore a if the hash is 0x1c 61 7a 0f c0 1c 08 60, it’s of length 8 bytes, or 64 bits.
Hashing + encryption can be used to create digital signatures:
md5sum program to calculate MD5 hash of different Raven versions.hello worldhello world againhello world1hello world2hello worldhello worldHistory:
git was developed as decentralised (+local) VCS, for the linux kernel| Ver | Content | Change | Sem Changes |
|---|---|---|---|
| 1 | We are going to Bergen | ** | new plan |
| 2 | We are flying to Bergen | going -> flying | Go by airplane |
| 3 | We are flying to Gdansk | Bergen -> Gdansk | Go to Gdansk after all |
| 4 | You are flying to Gdansk | We -> You | Actually I’m not going |
sequenceDiagram
VCS->>working directory: checkout
working directory->>editor: load file(s)
editor->>working directory: save file(s)
working directory->>VCS: commit
You never edit files directly in the VCS. You always get files from the VCS into your local directory (checkout). There you edit the files, and then send the changes back to the CVS (commit).
| term | def |
|---|---|
| respository | the git database you work on; usually 1 project |
| revision | development version |
checkout |
Bring the working directory in line with certain revision |
| local change | diff between latest checked-out version and version in working directory |
commit |
Make a new revision (of currently checked-out revision + local changes) |
| a commit | the changes between two subsequent revisions |
| commit msg | Log-message for your commit, not part of the code |
| parent | if at revision A, the parent is that revision that came just before revision A |
| id/sha | a “number” for your commit / revision |
| term | def |
|---|---|
| a tag | A manually placed (but movable) label to a revision. E.g. a concrete version. |
| a branch | All commits from the root to a named branch-tip (like tag but moves on commit) |
merge |
Combine all commits in two branches, to create a new revision (with 2 parents) |
fetch |
get new revisions + tags + branch-tips from “remote location” |
pull |
fetch + merge |
push |
push new commits to “remote location” |
| id/sha | revision | a commit | commit message |
|---|---|---|---|
| Main | |||
| 1 | We are going to Bergen | ** | new plan |
| 1-2 | We are flying to Bergen | going -> flying | Go by airplane |
| 1-3 | We are flying to Gdansk | Bergen -> Gdansk | Go to Gdansk after all |
| 1-4 | You are flying to Gdansk | We -> You | Actually I’m not going |
| branch: past (from rev 1) | |||
| 2-2 | We were going to Bergen | are -> were | Story is better in the past |
| Merged (in main) | |||
| M-2 | You were flying to Gdansk | Merge 1-4 & 2-2 | *All changes* |
gitGraph
checkout main
commit id: "1"
branch past
checkout main
commit id: "1-2"
commit id: "1-3"
checkout past
commit id: "2-2"
checkout main
commit id: "1-4"
merge past id: "1-4 & 2-2"
main (or master)1 a branch past is made, to work on a version of the story in the past tensecommits 1-2 and 1-3 are madecommit 2-2 is madecommit 1-4 is madepast branch should be merged (all changes from this branch should be pulled in) into main.Note: how to choose a branch name?
It’s essential to understand git local mode before moving on to non-local.
It’s essential to (sort of) understand git non-local mode before moving to GitHub.
For now, forget about pull, fetch and push
Many devs (incl myself) have local gits on Dropbox for backup (less these days)
/
- .vcs/
- commits/
- 1/
- message.txt
- parents.txt (=none)
- diffs/
- raven.txt.patch
- dove.txt.patch
- 2/
- message.txt
- parents.txt (=1)
- diffs/
- raven.txt.patch
- 3/
- message.txt
- parents.txt (=2)
- diffs/
- sparrow.txt.patch
- dove.txt.patch
- branches/
- main.txt (=3)
- tags/
- v1.0.txt (=2)
- HEAD.txt (=3)
- CURRENT_BRANCH.txt (=main)
- dove.txt
- sparrow.txt
- raven.txtExample VCS system (not git) with 3 revisions, and revision 3 checked out.
commit:
commitsHEAD and working directorymessage.txt (based on message from user) and parents.txtHEAD.txt to point to new commitbranches/#CURRENT_BRANCH.txt#.txt (so branches/main.txt) to point to new commitmessage.txt + parents.txt + diffs/*)? That is almost exactly what git does.vcs checkout 2, we just apply diffs for commits 1 and 2 and have version 2.git directorysha as commit/revision numbergitGraph
commit id: "d025a921"
commit id: "2ad61971"
commit id: "4ff7dd4e"
commit id: "6760bd27"
branch reveal.js
checkout reveal.js
commit id: "62b927b8"
branch typos
commit id: "91347842"
commit id: "10031726"
commit id: "c881ce59"
checkout main
merge typos
commit id: "56ac0a73"
checkout reveal.js
commit id: "2b494976"
commit id: "a8420eba"
checkout main
commit id: "f42f95c9"
branch crazy-idea
checkout crazy-idea
commit id: "541d5c05"
commit id: "e573f21b"
checkout main
commit id: "ba88d9ef"
commit id: "aa1b0e8f"
checkout reveal.js
commit id: "d2659292"
branch mermaid-plugin
checkout mermaid-plugin
commit id: "34418e7d"
checkout main
merge reveal.js
checkout mermaid-plugin
commit id: "282a1b9b"
checkout main
commit id: "9e5caa28"
merge mermaid-plugin
commit id: "f1a8a41b"
commit id: "b8df9f45"
checkout crazy-idea
commit id: "8db12eed"
8db12ee); Larger projects need more.Thus, an organic SHA-1 collision is less likely than every member of your programming team being attacked and killed by wolves in unrelated incidents on the same night.
A tag is a unique (semantic) label that points to a sha. It can be chosen by the user, and can be moved. Typ: version number
A branch (act. branch-tag) is like a tag; it points to the latest sha on a branch (and moves when a new commit is made to the branch).
gitGraph
commit id: "d025a921"
commit id: "2ad61971"
commit id: "4ff7dd4e" tag: "v0.1"
commit id: "6760bd27"
commit id: "f42f95c9" tag: "v0.2"
commit id: "541d5c05"
commit id: "ba88d9ef"
commit id: "aa1b0e8f" tag: "main"
gitGraph
commit id: "d025a921"
commit id: "2ad61971"
commit id: "4ff7dd4e" tag: "v0.1"
commit id: "6760bd27"
commit id: "f42f95c9" tag: "v0.2"
commit id: "541d5c05"
commit id: "ba88d9ef"
commit id: "aa1b0e8f"
commit id: "c881ce59"
commit id: "56ac0a73" tag: "main"
gitGraph
commit id: "d025a921"
commit id: "2ad61971"
commit id: "4ff7dd4e" tag: "v0.1"
commit id: "6760bd27"
commit id: "f42f95c9" tag: "v0.2"
commit id: "541d5c05"
commit id: "ba88d9ef"
commit id: "aa1b0e8f"
commit id: "c881ce59"
commit id: "56ac0a73"
commit id: "22339b36" tag: "v0.3"
commit id: "b0944c21"
commit id: "cbd67e23" tag: "main"
With commit you move changes from your working directory to git. But which changes?
To solve this problem, committing is a two-stage operation.
First you stage changes into the index
Then when you’re ready, you commit the index
The index is therefore a subset of the changes between latest checked out version, and your working directory.
sequenceDiagram
current revision-)index: git checkout
index->>working directory: git checkout
working directory->>index: git add
index->>current revision: commit (makes new revision)
When you commit something, git will ask for a commit message. In order to do so, git will open an editor.
By default this editor is vim, the one and only absolute best editor in the world, but with a quite steep learning curve.
So we will need to switch this for nano.
First, confirm that nano is installed on your system: nano somefile.txt. It should open an editor and allow you to edit and then save a file.
If not, do brew install nano (on Mac).
Now, we need to make sure git uses nano instead of vim:
git config --global --list shows the current global (=not repository specific) git configuration.git config --global --list | grep editor shows if there is anything about an editorgit config --global core.editor nano sets the editor (check with the command above)git subcommand subcommand-options -- general way to interact with git
git help -- show all subcommands
git help subcommand -- show help for certain subcommand| subcommand | action |
|---|---|
status |
Shows what files differ between “current revision” |
init |
Start a new (empty) git respository in the current directory |
checkout |
Make a certain revision the “current revision” and apply to working directory |
add |
Stage changes (Move changes into the index) |
restore |
Restore files (staged on in WD) from repo |
commit |
Commit the (changes in the) index into the respository (as a new commit) |
diff |
Run a diff between different commits, or a commit and your local files |
log |
See a list, starting at the current commit and showing all parents |