The International Simutrans Forum

 

Author Topic: Learning how to use Git  (Read 197 times)

0 Members and 1 Guest are viewing this topic.

Offline Matthew

  • *
  • Posts: 439
    • Japan Railway Journal
  • Languages: EN, some ZH, DE & SQ
Learning how to use Git
« on: January 14, 2020, 04:59:58 PM »
I find Git very difficult to use, so I've just asked a question on Stack Exchange about how to use Git and Github to mod Simutrans-Extended.If you have any corrections or suggestions, then please do contribute over there.

Hopefully the outcome will be a diagram that's a useful cheat sheet for me and anyone else who mods the game or paksets.

Offline jamespetts

  • Simutrans-Extended project coordinator
  • Administrator
  • *
  • Posts: 20350
  • Cake baker
    • Bridgewater-Brunel
  • Languages: EN
Re: Learning how to use Git
« Reply #1 on: January 14, 2020, 09:46:09 PM »
Let me give a brief conceptual overview of Git. I will not give exact commands, as you will find these easily.

Git involves making and synchronising copies of sets of files (such as the files containing the code needed to compile Simutrans-Extended or a pakset). The places where Git files are located are called repositories. A repository can be local (on your computer) or remote (on a server).

To copy all the files from a remote repository to your computer, you need to set up a folder on your computer as a Git repository, and then pull the contents of a remote repository into that folder. You can then modify the files in the usual way. Git will keep a track of the original state of the files when you pulled them from the repository.

Once you are happy with your changes, you can commit the changes. Git will always remember the state of all the files in the repository at each commit. This means that you can always reset your local repository to any earlier committed state.

Once you have committed your changes, you can then push the contents of your local repository (that is, the whole fileset, including the changed files and the commit history) to your own remote repository (or the original repository from which you pulled, if you have access rights).

Using Git, you can create branches. A branch is a series of commits from one starting point. More than one branch may start from the same point. By default, a Git repository contains one branch, the master branch.

Suppose that we have a Git repository containing one file, cat.txt. In the first commit, cat.txt is as follows:

Code: [Select]
The cat sat on the mat.

If you were then to edit cat.txt:

Code: [Select]
The cats sat on the mats.
and commit it, you would have two commits on your master branch, one with the file in the first state, and one with the file in the second state. The latest commit in any given repository is called the HEAD.

Now suppose that you were to create a branch from master called "kittens" and then switch to that branch. Initially, the state of cat.txt would still be

Code: [Select]
The cats sat on the mats.

If you were to modify cat.txt as follows:

Code: [Select]
The kittens sat on the mats.

and commit that, then the state of cat.txt in the HEAD commit of the kittens branch would be different to the state of cat.txt in the HEAD state of the master branch.

If you were to switch back to the master branch, the contents of cat.txt would be:

Code: [Select]
The cats sat on the mats.

If you were then to modify this further:

Code: [Select]
The cats sat on the mats.
The cats are furry.

the HEAD of the master branch would have cats.txt as:

Code: [Select]
The cats sat on the mats.
The cats are furry.

and of the kittens branch:

Code: [Select]
The kittens sat on the mats.

Now suppose that you were to switch to the master branch and merge the kittens branch into the master branch. Git would attempt to merge the two changes together. Because you had not changed the first line of cats.txt in any of the commits in the master branch after the kittens branch was created from the master branch, Git will assume that, by merging in the kittens branch, you want to apply the changes to this line to the master branch. Also, we have a new line from the master branch not present on the kittens branch, which will be added. Thus, cats.txt in the master branch after the merge will look like this:

Code: [Select]
The kittens sat on the mats.
The cats are furry.

If you were to switch back to the kittens branch, cats.txt would still be:

Code: [Select]
The kittens sat on the mats.

Some changes cannot be merged automatically. Suppose that, on the kittens branch, you changed cats.txt as follows:

Code: [Select]
The kittens wore mittens.

And, on the master branch, you changed cats.txt as follows:

Code: [Select]
The cats wore hats.
The cats are furry.

and then tried to merge the kittens branch into the cats branch, you would get a merge conflict, as Git would not know which change to the first line of cats.txt that you want to keep, as both changes were made after the last merge (or the first creation of the kittens branch, whichever was later). In this case, you will get something a bit like this:

Code: [Select]
<<<<<<<<<<<<<<< master
The cats wore hats .
================
The kittens wore mittens.
>>>>>>>>>>>>>>kittens
The cats are furry

and you would have to edit the file manually to resolve the conflict.

The same logic as applies to branches also applies to remote repositories, so the same results would obtain if, instead of you creating a branch called "kittens" in your own repository, you had forked somebody else's repository and changed the file, and the other person was then incorporating your changes back into the original repository.

I hope that this makes sense.