GIT Exercises

From Lazarus wiki
Revision as of 18:55, 24 June 2021 by Martin (talk | contribs) (→‎Merge)
Jump to navigationJump to search

This page will has some exercises, so you can experience different solutions/outcome to a given task yourself.

By giving those (partly trivial) examples, the page ensures that you will not miss any of the scenarios while discovering yourself.

Preface

Some of the examples are about how to deal with your work, when other people pushed in between.

For this you need a 2nd clone. See setup.

Setup

The following steps should be performed before going to any of the below items.

Initial setup and clone

SVN_to_GIT_Cheatsheet#Setup

Second clone

To simulate what someone else would have done, while you where working. This can use the same user, the effect will be the same.

You can either "git clone" again, or just make a copy of the entire directory into which you have cloned.

You can then in that 2nd clone alter your username

   git config user.name  martin_2

Each example setup

In your first git folders, create a new branch

  git switch -c martins-test-1
  git push --set-upstream origin martins-test-1  ## tell the server there is a new branch

In your 2nd git folder

  git remote update
  git switch martins-test-1

Thus both your folders are an the same branch, and are up to date with the remote

Light bulb  Note: In the example you work on "martins-test-1". But it is setup the same as your trunk branch would be. Therefore the same will apply when you work on trunk

Pushing your commit, if someone else made changes

Rebase

In Folder1

Edit the file lcl/forms.pp

   git commit -m 'test changes' lcl/forms.pp
   git log --oneline --graph --all -n 2
      * 3b007fdc38 (HEAD -> martins-test-1) test changes
      * c739dd68a7 (origin/master, origin/HEAD) Revert "Test a change in forms"

Your commit, follows the previous commit


In Folder2 -- Simulate the other user

Edit the file ide/main.pp

   git commit -m 'test other' ide/main.pp
   git push
In Folder1
   git push
       ! [rejected]              martins-test-1 -> martins-test-1 (fetch first)
      error: failed to push some refs to 'https://gitlab.com/freepascal.org/lazarus_testconversion.git'


Instead of the normal pull, we do a fetch. This will not resolve the problem, and we can see what it looks like.

   git fetch
      fatal: Not possible to fast-forward, aborting.


   git log --oneline --graph --all -n 3
      * 46a817b6b3 (origin/martins-test-1) test other
      | * 3b007fdc38 (HEAD -> martins-test-1) test changes
      |/
      | * c739dd68a7 (origin/master, origin/HEAD) Revert "Test a change in forms"


You can see your commit still follows the same commit as before.

But on the server (origin/martins-test-1) there is the other commit, and it too has the same parent. The history on the server is fixed. We do not allow for it to be changed. So that commit will keep its parent.

In order to get your commit to the server, your local commit must change it's parent to "test other" (that is called "rebase")

   git pull --rebase
      Successfully rebased and updated refs/heads/martins-test-1.
   git log --oneline --graph --all -n 3
      * 2cbe840e7e (HEAD -> martins-test-1) test changes
      * 46a817b6b3 (origin/martins-test-1) test changes
      * c739dd68a7 (origin/master, origin/HEAD) Revert "Test a change in forms"

Now your commit is on top, and we have a flat line of commits (like svn)

    git push

Merge

Warning-icon.png

Warning: This example is what we want to avoid. This creates a diverged history (sub-branches). The log is no longer linear.

Setup new branches #Each example setup Repeat the steps above until you done "git fetch"

Now run

   git pull --no-ff --no-rebase
      Merge made by the 'recursive' strategy.
       ide/main.pp | 3 ---
       1 file changed, 3 deletions(-)

The --no-ff --no-rebase override any configs you may have made, and get you the default behaviour of merging. Git will open an editor for you, and ask for a commit message for the merge. The merge creates a new commit.

   git log --oneline --graph --all -n 4
      *   044d9288b7 (HEAD -> martins-test-2) Merge branch 'martins-test-2' of https://gitlab.com/freepascal.org/lazarus_testconversion into martins-test-2
      |\
      | * 379b633c88 (origin/martins-test-2) test other
      * | cfa3def67c test changes
      |/
      * 2cbe840e7e foo bar

As you can see the two commits are in different sub-branches (they are actually side by side). And a new merge commit has been added.

You can push this.

But this creates a commit log, like you would never see in svn.

Fast Forward

Pulling someone else changes into your ongoing work