lastlog.de/blog
  • timeline
  • about
  • draft
  • roadmap
  • websocket

git

27 feb 2026

What is this about?

Todays introduction into git features all you need for daily work.

Show solution If in doubt use AI to solve the questions or help you with context!

This lecture covers the most basic git usages like:

  • clone - copy a repository
  • blame - show last change info
  • commit - save changes
  • push - upload changes
  • pull - fetch and merge
  • rebase - integrate changes linearly
  • reset - undo changes
  • stash - save changes temporarily
  • tag - mark specific points
  • worktree - multiple working directories
  • bisect - find bugs via binary search
  • branch - create/manage branches
  • rm - remove files
  • mv - move/rename files
  • svn - interact with Subversion
  • revert - undo commits
  • diff - show differences
  • submodule - use nested repositories
  • cherry-pick - integrate a commit by commit hash

See https://git-scm.com/docs for detailed description.

Online resources:

  • https://git-scm.com/learn
  • https://gitimmersion.com/lab_12.html
  • https://learngitbranching.js.org/

Requirements

  • working internet connection & working email address for gh signup
  • git / git-svn
  • python 3
  • tig
  • AI tools like gpt 4o

links:

  • https://git-training.nixcloud.io/ttyd/
  • https://gemini.google.com/app
  • https://chatgpt.com

Lecture 1: Looking into existing git repositorries

Looking at commands which help you to get insight into repositories.

git clone / branch / log / blame / diff

Call this command:

git clone https://github.com/nixcloud/git-training
  • git status - Displays the state of the working directory and staging area.

    • What branch are you in?

      Show solution

      You are in main, this is the default branch set in this repo. The default branch can differ between repositories.

  • git branch

    • How to list remote branches?

      Show solution

      git branch -r will show remote branches, sometimes it requires a git fetch --all to update the local knowledge about the remotes.

    • Change into branch 1_branch_with_many_commits, what is the command to do so?

      Show solution

      git checkout -b 1_branch_with_many_commits origin/1_branch_with_many_commits

  • git log - Shows the commit history. Options: --oneline!

    • What is the commit hash of the commit with the message: “adding new_file”?

      Show solution

      d22e0c8 adding new_file 
  • git blame README.md - Shows the file and the respective editors per line.

    • The README.md had many changes, identify the user who added the top most fox in the README.md!

      Show solution

      a1389ad9 (Foxhunt         2026-03-18 14:27:44 +0000  8) 🦊 U+1F98A Fox Face Unicode Character
  • git diff - Shows changes between commits.

    Sometimes you have a branch with many commits but you need to see it as one change to understand the effect it has.

    • Figure out what happened between commit 1397c7 and 5c33c4 using git diff ...?..., what is the command?

      Show solution

      You can see all the changes as one change using git diff 1397c7..5c33c4.

      When you look at the change you realize this: The chicken army got erased by the fox! - oh no!

Lecture 2: github.com

Github is a very popular platform with 100 million developers both for open source and closed source projects. A lot of todays ‘best practices’ were created there so we’ll use it to learn them.

The diagram below shows a typical GH workflow for how to contribute to a project using git and pull requests (PR).

  1. Create a github account at https://github.com/signup

    Mine is https://github.com/qknight

  2. (or) login to GH if you already have an account

We create a Pull request

  1. fork https://github.com/nixcloud/git-training using the web UI (make it a public repository)
  2. create a branch “0_new_chick” from the “main” branch using the web UI
  3. edit the README.md and add a 🐔 to it and commit the change
  4. Create a PR with your “0_new_chick” to https://github.com/nixcloud/git-training branch “main”

Reflection time:

  • where does the PR appear?

    Show solution

    If you did it right it should appear at https://github.com/nixcloud/git-training/pulls

  • is your fork a private or public repo (this is specific to github, not git in general)?

    Show solution

    By default forking a repo inherits the public/private setting from the parent.

We create an issue

https://github.com/nixcloud/git-training/issues is currently empty but we need to create a “Cucco storm”!

  1. Create an issue with proper markdown and ask for some ultra-stupid request, feel free to use your ‘AI slop’ generator of choice.
  2. Wait for upstream to react to your request

Creating a PAT (for auth)

A Personal Access Token (PAT) is the recommended way to work with git from the command line.

  1. visit https://github.com/settings/personal-access-tokens
  2. create a ‘Fine-grained personal access tokens’
  • Repository access ‘All repositories’

  • Permissions

    • Add ‘Read and write’
    • For Contents (Repository contents, commits, branches, downloads, releases, and merges.
  • Expiration date: A few days

  • Write down the token:

    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

We’ll use the PAT later so note it down.

Using the PAT (token)

We already cloned git-training using https://github.com/nixcloud/git-training, we reuse this here.

  1. git switch main to go back to the main branch

  2. now we connect to ‘our’ newly crated forked repository on github

    git remote add qknightmt https://github.com/qknightMT/git-training

    instead of using git remote add ... you can also edit the .git/config with nano .git/config.

  3. check the configuration

    git remote -v
    origin          https://github.com/nixcloud/git-training  (fetch)
    origin          https://github.com/nixcloud/git-training  (push)
    qknightmt       https://github.com/qknightMT/git-training (fetch)
    qknightmt       https://github.com/qknightMT/git-training (push)
  4. create a new branch

    git checkout -b 0_push_test

    Does this create a local or remote branch? What is the difference?

    Show solution

    It creates a local branch and you need to push it so it becomes also a remote branch. The difference is where the branch ‘lives’.

  5. and push it to your your new remote using

    git push qknightmt 0_push_test

    Git will ask for your username and password, use your username you created. Mine is:

    • username: qknightmt
    • token: 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
    git push qknightmt 0_push_test
    Username for 'https://github.com': qknightmt
    Password for 'https://qknightmt@github.com': 
    Total 0 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)
    remote: 
    remote: Create a pull request for '0_push_test' on GitHub by visiting:
    remote:      https://github.com/qknightMT/git-training/pull/new/0_push_test
    remote: 
    To https://github.com/qknightMT/git-training
    * [new branch]      0_push_test -> 0_push_test
  6. do the same push again

    git push qknightmt 0_push_test

    You have to login again, oh no! Enter your credentials again and see this:

    git push qknightmt 1_branch_with_many_commits
    Everything up-to-date
  7. storing credentials

    We do not want to type the user / password each time, so type:

    git config --global credential.helper cache

    Now push again with user / password:

    git push qknightmt 1_branch_with_many_commits

    And then do it again, you should not be prompted for another password.

    Note: You can flush the credentials cache for testing:

    git credential-cache exit

Reflection time:

  • where else could you store the PAT other than it in the .git/config url parameter as we just did?

    Show solution

    The credential helper from git, commands like:

    git config --global credential.helper cache

  • Why are PATs better than username/password for login?

    Show solution

    You can use them on partially compromised environments and if stolen they only allow access to code and not automatically all your github settings.

    Ideally you have PATs for groups of code and not, as we did, one PAT for all the repositories.

A ‘gist’

Often you need to share a snippet of code or configuration with others. An easy and persistent way is to use github gits for this!

  1. when you open the git-training there is also a gist linked, open it and speculate what it is about!?

    Show solution

    The link https://gist.github.com/qknight/0231bce88b1b32b4efbcb8e44557cd8c is a documentation how to easily spin up such an environment.

  2. create a short snippet of text

  3. publish snippet as a ‘secret gist’. What makes a secret gist ‘secret’?

    Show solution

    The secret is basically the url part and if known everyone can read it.

    https://gist.github.com/qknight/f342fad470d30a036eb09d7b85c70146

  4. why does it make sense to fork a gist from someone? why does git forking in general make sense?

    Show solution

    A git repo, similar to a gist can disappear and a fork let’s you archive it for yourself. It helps upstream track popularity and community and you can make modifications to the code.

Permalink

In communication it is important to talk about the same things, obviously, so:

  1. visit https://github.com/nixcloud/cargo/blob/master-libnix/Cargo.lock

  2. create a link on line 13 (open it in a new tab)

    Show solution

    https://github.com/nixcloud/cargo/blob/master-libnix/Cargo.lock#L13

  3. now create a perma link on line 13 (open it in a new tab)

    Show solution

    https://github.com/nixcloud/cargo/blob/8ca2cffb58c09ff186c5746be794f482af3f221f/Cargo.lock#L13

Lecture 3: Initializes a new Git repository

Creating git-repositories is easy and you gonna do this a lot. This section introduces a few different concepts.

There are a few ways to do this:

  1. You create a new repository on the server, then with your client you usually type:

    git clone https://github.com/nixcloud/git-training

    But we already have a clone of this.

  2. You create a local git repository, then you initialize an empty server with it:

    • create a new directory mkdir my_git_repo and cd my_git_repo into it

    • git init - Initializes a new Git repository

    • Next create an new empty git repo on your server

    • Finally add the remote (we skip this for now)

      git branch -M master
      git remote add origin git@github.com:qknight/test.git
      git push -u origin master
  3. From SVN: git svn clone <repository-url> - Imports an SVN repository into a new git repository with full history.

    git svn clone https://svn.code.sf.net/p/svnexample/code/trunk svnexample

    Do this checkout now! How many commits does it have in git, also explain the number?

    Show solution

    the answer is: it is 6 git commits and the other SVN revisions are probably used for SVN branches.

Lecture 4: git commit, add, unadd, push, push -f and reset

Git introduces more flexible and granular commit handling compared to SVN, allowing selective commits and easy reordering of changes. However, it also necessitates careful management to avoid complex history and conflicts, which can be more challenging than SVN’s straightforward commit system.

Command git add a_file

Adds a file into the staging area. A following git commit converts it into git object, see Git-Objects.

Now do this in branch main:

  1. modify the README.md, add some section with a duck 🦆 or 🐤

  2. call git add README.md

  3. call git commit -m 'Updated README.md'

    use tig or git log --oneline to see you change

  4. next add another section to README.md

  5. call git add README.md and then you notic that we actually don’t want that section in there!

  6. finally figure out how to undo a git add a_file (sadly not git unadd). what is the command?

    Show solution

    • git restore --staged a_file is recommended new default
    • git reset a_file is what i learnt

    afterwards check that git status still shows changes and that your lines edited are still there. again - we do not want to get rid of the change but we want it in a different commit.

  7. (optional) if you feel adventurous, try this:

    1. in the README.md add a top section and a bottom section

    2. use git add -p README.md (only add the top section)

    3. use git commit README.md, what just happened with the bottom section?

      Show solution

      git add -p can be used to only commit parts of a file into the staging area, the not selected parts remain in the working area.

Command git push -f

Sometimes, after a commit & push you find out that you forgot something. You can now add another commit but … sometimes a correct history is important.

Typical scenario:

  • forgot fmt
  • test execution fails

There are two options now:

  • you can make the change and use git commit --amend and git push -f afterwards

    When is this a good idea and when to not do it? Research using google or AI!

    Show solution

    git push -f breaks history. Say you pushed your code and someone is already working with it you can’t use a force push. Most often force push is a bad idea.

  • you can undo your commit and return to the previous commit

    Find out how to do this, assume you made just one commit.

    Show solution

    git reset --hard HEAD^ and then git log and if happy git push -f. YOU USUALLY NEVER WANT TO DO THAT

Finally figure out what the difference between git reset HEAD --hard vs. git reset HEAD --soft.

Note: If you are smart, a better command than git push -f is git push --force-with-lease. Why?

Show solution It force-pushes only if the remote branch hasn’t changed since you last fetched it, preventing you from accidentally overwriting others’ work. If the remote was updated independently, the push is rejected, prompting you to fetch and reconcile changes before pushing again.

Command git pull

A traditional ‘git pull’ uses the merge strategy, which works remarkably well but renders the commit history hard to read, makes rebasing a nightmere.

  1. first clone https://github.com/sumantabose/git-playground

    git clone https://github.com/sumantabose/git-playground

  2. cd git-playground

  3. tig

    How many merge(s) do you see?

    Show solution

    With top commit 38922f it should be 6 M merge commits

    Are merges commits easy to read?

    Show solution

    A merge commit (vs. a fast forward) commit adds an additional commit and the interwinding of branches it is hard to follow what is going on.

    If possible try to keep git history without merges.

So a typical scenario:

  • Two devs clone the same commit in main and start working.
  • Dev A commits first with git add files and git commit -m 'change' and git push.

However, dev B needs to do something before pushing:

  1. git fetch --all
  2. git rebase
  3. git push

An alternative to these 3 commands is:

git config --global pull.rebase true

And call git pull or even better, just always use:

  1. git pull --ff

    What does –ff do?

    Show solution

    Compare to Default

    • Default git pull (without –ff): If a fast-forward is not possible, Git creates a merge commit.
    • With git pull --ff, it strictly avoids merge commits and only fast-forwards if possible.
  2. or

  3. git rebase origin/main

Lecture 5: git branches

Git provides flexible mechanisms like branching and stashing that allow for non-linear workflows, which is a contrast to SVN’s more linear approach. While these features enhance workflow versatility, they also require more attention and understanding to manage effectively compared to SVN.

Switch to a different local branch:

git switch <branch-name>

How to list local branches?

Show solution git branch -l

Command git stash 1/2

Sometimes we made many changes but don’t feel it is good enough for a commit YET we have to checkout something for a collegue.

We similate this now:

  1. git status should show it is an git branch main with no modifications
  2. Modify a file like README.md, add a few lines
  3. Now type git status to verify changed files!
  4. Next type git stash
  5. Again type git status, what changed?
Show solution git stash memorized the changes on a stack for later recovery but leaft a clean branch (no changes).

Next find out how to get the files back!

Show solution git stash apply on a clean git repo will reapply the changes.

Try the same command again but this time make a little change to README.md and then try to get your files back. What happened?

Show solution A git stash apply on a branch with changes errors out so you don’t clutter your workspace.

Git stash is your friend, if in doubt you can also commit to a working branch and store it on the remote so in case you laptop gets stolen the code it still safe.

Command git remote -v

Compare git remote -v with the content of cat .git/config. What do you see?

Show solution git remote -v only lists remote branches while .git/config lists all branches and the repo configuration.

A fairly common problem is this: You forked a git repository, someone else did the same and now you need his commits locally:

  1. visit https://github.com/qknight/git-training
  2. see the branch 4_a_new_feature
  3. add the github.com/qknight/git-training as a new remote, what is the command?
    Show solution
      git remote add qknight https://github.com/qknight/git-training.git
      git fetch qknight
      git checkout -b flu qknight/4_a_new_feature
  4. finally you want this change in your “main” branch, how to do that?
    Show solution to be done

Command git stash 2/2

Sometimes one starts to work on the wrong branch, makes changes, even stages files and then realizes that some patch is missing. Then the changes need to be moved to the other branch with git stash.

  1. git status should show it is an git branch main with no modifications
  2. create a new file “new_file”
  3. modify README.md, for example with echo "appending to the end, since the end is near 🐤" >> README.md
  4. type git stash
  5. use git switch 1_branch_with_many_commits

That didn’t work! What do you have to fix in order to make the git stash work?

Show solution

The git stash is missing the new_file since it was never ever commited before it is ignored by git stash, we can simply do a git add new_file and then run git stash.

After switching to the new branch and after running git stash apply we have to solve a merge conflict on README.md, depending where you made your change.

Command git tag

A git tag is applied to a commit and not a branch, so do this:

  1. add a tag ‘v0.1.1’ to the ‘main’ branch
  2. since we forgot it figure out how to add a tag one a previous commit with ‘v0.0.9’

How to upload the tags?

Show solution git push --tags.

Note: If you ever set a tag, never, NEVER change it, just add a new one with an increased version number.

Lecture 6: The git bisect command

In this section, the process of pinpointing a fault using git bisect is discussed, which involves marking commits as “good” or “bad” while running python main.py to determine which commit introduced an issue.

We have a branch with many commits but weeks later a fault was detected running python main.py. For some reason it stopped working but we don’t know when nor why. We need to find the commit which caused the issue!

  1. checkout the branch: git checkout 2_bisect
  2. run the command: python main.py and see if it is working

We use git bisect for this. It is controlled with a few helper commands start, good, bad and reset.

Which commit introduced the issue? Verify the source code with python main.py, it must always show Success, then it is good. Otherwise it is bad!

Show solution The problem started with commit 49f23ea3df2bd04a4ff323c63a2849907c0a30bb

What needs to be done if one of the commits does not compile and we can’t decided if it is good or bad?

Show solution We can use git bisect skip and this will select a commit next to the one we skipped so we can continue.

Lecture 7: git history & rewrite

In this section, it is explained how Git allows history rewriting, but it should be done cautiously since it can disrupt others’ work. Key actions like amending the latest commit, merging, squashing, cherry-picking, and reverting commits are demonstrated, with a focus on handling conflicts and making clear and concise commit histories, which are different from SVN practices.

History in git can be rewritten when:

  • The branch you work on belongs to you and you are the only one working with it.
  • You are forced to do the breaking change for legal reasons, like removing a customer name or a password which git into the repo somehow.

A change like this means that everyone else who works on the same base will have huge trouble pushing his changes later one so use with care.

Changing the top most commit

git checkout -b tests origin/main  
git add next.py
git commit --amend

Use tig to see the history, use git diff tests..origin/main to see what is going on?

Show solution You created a new branch on top of origin/main and changed the top-most commit thus you need to force push because your local branch can’t be merged anymore since there is no common base anymore.

Rearranging commits

We need to cleanup a few things in this branch:

  • The LICENSE file has two commits, this should be merged
  • We leaked a password, nobody noticed it yet so we have to act fast!
  1. checkout branch: 3_rebase_commits

  2. see the logs with tig

    [nix-shell:~/git-training]$ git log --oneline
    00d29f0 (HEAD -> 3_rebase_commits, origin/3_rebase_commits) Updated sensitive_script.py to use environment variables
    3f569e0 Adding sensitive_script.py
    5b57df2 Adding LICENSE file to repo since i forgot it
    3b4586e Updated legal README.md notice
    e731eea (origin/main, origin/HEAD, main) Update README.md
    5c33c42 Initial commit

    What is the meaning of origin/main, origin/HEAD, main and HEAD?

    Show solution

    Reference Description
    origin/main the main branch on the ‘origin’ points to commit e731eea
    main the local main branch points to the same commit!
    origin/HEAD default branch (like main or master)
    HEAD a pointer to the current branch’s latest commit. Used to track branch/commit
  3. call git rebase -i e731ee

    What is e731ee and why does it make sense to call this?

    Show solution

    e731ee is the commit on the main branch which is the common base to this branch

    • merge 5b57df2 and 3b4586e
    • merge 00d29f0 and 3f569e0 (this will kill the secret from the file)
  4. final push

    normally you would do a git push -f and be done with it

    we just store the result like this:

    git checkout -b 3_rebase_commits_yourname
    git push

Squashing commits

Squashing multiple commits into one commit can be very helpful. But when is commit smashing safe?

Yes, using git rebase we loose history but gain clearity!

git rebase -i ...some-hash...

So do this:

  1. checkout branch 3_wild_merges
  2. check the content of the new branch!
  • What do you see?

    Show solution

    There are many merges between 3 users: UserA, UserB and Joachim. everything is on top of branch ‘main’ which is good!

    It looks ugly…

  1. First, we’ll work on a copy on top of that branch so we can always go back easily, how to do this?

    Show solution

    git checkout 3_wild_merges; git checkout -b 3_wild_merges_rebase

  2. Next, the rebase! Use git rebase -i e731eea7db433dd7371d54c6b676191f308bd6a8, smash all the 20 commits into one with “s”:

    # s, squash <commit> = use commit, but meld into previous commit
    # f, fixup [-C | -c] 

    But you get an error, what is this error about?

    Show solution

    git rebase -i e731eea7db433dd7371d54c6b676191f308bd6a8 returns an error.

    You can now resolve all these conflicts manually or use a different strategy.

  3. First let’s recap, why did the rebase fail?

    Show solution

    GPT5: Short answer: rebase replays every commit one-by-one on a new base (and drops/linearizes merges), so conflicts that were previously resolved inside old merge commits reappear during the replay. merge –squash computes one combined tree diff from the branch tip (vs merge-base) and applies it once, so it often avoids those per-commit conflicts.

    Ways to achieve your goal and avoid the pain:

    If you just want “one commit that equals the branch’s final state on top of main”: git checkout main git merge –squash your-branch git commit -m “squash: your-branch” If you must rebase but want to auto-resolve conflicts by preferring the branch’s changes: git checkout your-branch git rebase -X theirs main then merge or push as needed If merges matter and you want to preserve them during rebase: git rebase –rebase-merges -X theirs main Enable rerere to auto-reuse recorded conflict resolutions across attempts: git config –global rerere.enabled true git config –global rerere.autoupdate true Rule of thumb: for “final tree = tip-of-branch, single commit,” prefer merge –squash (or a soft-reset-based squash). Use rebase only if you need a linearized history of individual commits.

    See https://www.reddit.com/r/git/comments/p9x33m/linearize_a_git_history_wo_merge_conflicts_to/!

  4. This is the easy and recommended alternative to the problem above:

    git checkout main
    git checkout -b 3_wild_merges_rebase_squashed
    git merge --squash 3_wild_merges_rebase

    is the better option.

    Main lecture: Don’t use traditional merges, use rebases on pull. It makes history reading easier, it makes git bisect easier. It sometimes makes merges harder though…

Command git cherry-pick

  1. find out what commit fb8cb9 is all about

    Show solution

    git show fb8cb9 displays the change which updates the LICENSE file content.

  2. checkout the branch: 3_revert_cherry_pick

    Show solution

    git checkout origin/3_revert_cherry_pick -b 3_revert_cherry_pick

  3. git cherry-pick fb8cb9

    This resulted in an error. What is this about and how to resolve it?

    Show solution

    We don’t have a LICENSE file yet and the commit is a ‘change’ thus it fails. As a solution we have to add it.

  4. How to add it? git status shows we are still in a cherry-pick state, we could exit using git cherry-pick --abort but we don’t want to! fix the cherry pick. what are the commands?

    Show solution

    We have to continue and finish the cherry-pick. Don’t just do a git commit! git add LICENSE git cherry-pick --continue

Command git revert

  1. create a new branch 3_revert_commit from origin/3_wild_merges

    git checkout -b 3_revert_commit origin/3_wild_merges

  2. use git revert on revert commit 5c33c4. What is the problem and how did you solve it?

    Show solution

    The initial commit 5c33c4 added the README.md and running git revert 5c33c4 results in the conflict that the next commit modifies the README.md. Since we don’t want the README.md to ever have existed, we do a git rm README.md and then a git revert --continue to finish the operation.

Compare the git log --oneline to git log origin/3_wild_merges --oneline, what is the difference?

Show solution You see there is one more commit in the local branch on top of 3_revert_commit which reverted the initial commit.

Lecture 8: git submodule

This section discusses the use of git submodule for managing dependencies in projects lacking package managers, such as C/C++ projects, whereas modern languages like Rust use dependency files such as Cargo.toml.

The command “git submodule” is used for languages which don’t have a package manager like c / c++ / qt. In modern languages like rust (cargo) this is not used anymore and modified dependencies are integrated using Cargo.toml instead on the source code level with ‘git submodule’.

  1. checkout branch 7_submodule, type git branch, what does it show?

    Show solution

    7_submodule is green as you are in that branch

  2. run the program: python main.py, what do you see?

    Show solution

     python main.py
     Error: submodule/README.md does not exist
  3. next we need to add the required submodule, please add https://github.com/nixcloud/git-training with branch main into the folder ./submodule! What is the command?

    Show solution

    git submodule add https://github.com/nixcloud/git-training submodule

  4. after adding the submodule, run it again, what does it say now?

    Show solution

     python main.py
     Number of chickens: 1
  5. it added the branch main but we want 1_branch_with_many_commits! how do we get that?

    Show solution

    We need to go into the ./submodule directory and checkout a different revision…

     pushd submodule
     git branch -r
     git fetch --all
     git checkout origin/1_branch_with_many_commits
     popd
     git add submodule
    
     git status
     [nix-shell:~/git-training]$ git status
     On branch 7_submodule
     Your branch is up to date with 'origin/7_submodule'.
    
     Changes to be committed:
     (use "git restore --staged <file>..." to unstage)
             new file:   .gitmodules
             new file:   submodule

    In essence we have a git repository inside a git repository where the outer manages the inner on with commands like git submodule update --init.

  6. observe the difference between git status in directory git-training/ and git-training/submodule

    Show solution

    You see that the git program in both directories returns different results. This is unusual! If git is called from a subdirectory inside a git repository it usually traverses upwards to the first .git/config directory and assumes this is the parent. Git submodules break with this assumption, see .gitmodules in the main repo for instance.

     [nix-shell:~/git-training]$ git status
     On branch 7_submodule
     Your branch is up to date with 'origin/7_submodule'.
    
     Changes to be committed:
     (use "git restore --staged <file>..." to unstage)
             new file:   .gitmodules
             new file:   submodule
    
     [nix-shell:~/git-training/submodule]$ git status
     HEAD detached at origin/1_branch_with_many_commits
     nothing to commit, working tree clean
  7. Finally, after we added branch 7_submodule in the step before, run python main.py again, what does it say now?

    Show solution

     python main.py
     Number of chickens: 4
     Congratulations, you made it!

Note: The example uses ./submodule as folder-name but you can use whatever you like.

Do you like to work with git submodules?

Show solution

The correct answer is NO.

Yet we have to, but it makes everything a pain. Try to use HTTPS urls over SSH urls as the build nodes might only have access to the HTTPS checkout.

Complicated git merges/rebases sometimes make you pick the wrong git submodule update resulting in adventurous scenarios.

Lecture 9: azure devops training

This section highlights the lack of structured namespaces or organizational structures in certain Git workflows compared to platforms like GitHub. Consequently, pull requests (PRs) are handled differently, focusing purely on repositories and branches without the typical user-centric organization.

  • There are no ego-centric namespaces like github.com/qknight nor are there organizations
  • All we are left with is git repositories and branches
  • As a consequence, PRs look very differently from most workflows

Lecture 10: Typical git workflows

This section enumerates key elements of modern version control practices, including forking and creating pull requests (PRs), managing issues using markdown, maintaining documentation with README.md and LICENSE files, and the different branching models such as Gitflow, GitHub Flow, and GitLab Flow.

  1. fork & PRs (Pull Requests)
  2. issues (markdown) https://github.com/nixcloud/cargo/issues
  3. documentation (README.md/LICENSE)
  4. Gitflow|GitHub|GitLab Flow https://nvie.com/posts/a-successful-git-branching-model/

Lecture 11: misc

This section provides insights into useful tools and settings for version control. It suggests using tig for staging files with specific keystrokes, recommends IntelliJ for its robust Git integration, especially for complex rebases, and mentions meld as a great open-source 3-way merge tool. Additionally, it advises on proper line-ending settings during Git installation on Windows to maintain consistency with Unix-style line endings.

  • tig how to use this tool to add files from the working area into the staging area (like git add a_file)?

    Show solution

      Commands
    
      's' to get into staging area
      'u' to toggle selected file between 'modified' and 'staged for commit'

    https://devhints.io/tig

  • intellij best git integration, see https://www.jetbrains.com/idea/

    if you have to do complex rebases, this is the editor! the 3-way-merge is excellent.

  • meld best open source 3-way merger, see https://meldmerge.org/

    integrates into GIT using the command git mergetool but is much harder to integrate.

  • Line endings encoding Windows vs. Linux

    When installing git-scm on windows, select this:

      [x] Checkout Windows-style, commit Unix-stle line endings
      [ ] Checkout as-is, commit Unix-style line endings
      [ ] Checkout as-is, commit as-is

Summary

With all these lectures done you have a solid education how to work with GIT and replace SVN where possible.

Questions

article source