Here are the commands you need to do the same as in the UI part of the how-to:

TODO: Windows: Git Bash Here

For example we want to clone wboe-artikel from https://gitlab.oeaw.ac.at/acdh-ch/wboe. The data at this location, in this repository, is marked as private. So you need to log into gitlab.oeaw.ac.at with the account you set up to see the contents.

On the command line, in the terminal this looks like:

git clone https://gitlab.oeaw.ac.at/acdh-ch/wboe/wboe-artikel

We are prompted for our username and password. They are also saved if possible in the background. If this is not possible git will ask as again with any other command that involves the repository on the gitlab server.

We change README.md using any editor we see fit.

The command line equivalent would be:

git add README.md

Every project snapshot we commit to history should include a semantically meaningful set of changes, and this may involve edits to different documents. git add allows to granularly choose which changes, to which files should be part of the next snapshot, while git commit will label that set of changes, and actually save a new snapshot.

On the command line this looks like:

git commit -m "Add new test document needed for texting x"

On the command line this looks like:

git push
git pull
git fetch

We can only use our editor here to find all the occurrences of the conflicts marker and edit those parts of the files with conflicts. Be sure to remove the markers. The conflict is solved. Hopefully.

Use git add and git commit to finish the merge. git commit will suggest a specifically looking message. It does not make much sense to change it.

We can always check what Git knows about the state of our project with:

git status

Note that Git informs us that changes have been made to a file called my-document.txt, but that file is currently “untracked”, which means it is not currently managed by Git’s versioning. Git also tells us that in order to tell it to keep track of changes to that file, we should “use git add to track”. Generally, if you find yourself in situations where you’re unsure how to proceed, git status will most of the time show helpful hints. It’s probably the Git command you’ll be using most often.

First, we need to tell Git that it should start to manage a project directory and keep an eye on changes to documents there. Navigate to your project folder in your terminal of choice, and type:

git init

This will initially set up Git’s internal bookkeeping metadata, which is stored in a hidden .git folder.

Let’s also create some new content. In a real research project this would mean editing or adding an XML/TEI document or similar. To demonstrate the mechanics we’ll keep it basic here and use the terminal to create a simple text file (don’t worry how this works, this has nothing to do with Git):

echo "This is my text document." > my-document.txt

Getting into the habit of assigning descriptive commit messages is especially helpful when viewing the history of changes. Git will print a changelog with:

git log --oneline

Note that we have one entry in our version history, and that Git has assigned the commit message we have provided, as well as an internal identifier to that entry. That identifier consists of 40 alphanumeric characters, but usually the first few characters are enough to uniquely address a commit in a project.

Git will display the exact changes which were made in a commit snapshot with:

git show 7f733ac

That last bit is the unique identifier which is assigned to every commit in Git’s version history. We’ve seen above how we can figure out these ids from inspecting the changelog displayed with git log. Note that when you have followed the steps in this introduction on your own computer, the unique identifier you see will be different from the one above. This is because identifiers are calculated from filename and content, author, commit message, and commit date.

It is also possible to show changes between two specific commit snapshots. Let’s first add another change, so there are actually two separate entries in our commit history (again, how creating and editing a document on the terminal works is unimportant here, but the two-step process of creating a snapshot with git add and git commit should already be familiar):

echo "This is another document." > another-document.txt # creates a new document
sed -i s/text/test/ my-document.txt # changes "text" to "test" in `my-document.txt`
git add -A
git commit -m "Add new document and change initial document"

To list the difference between two commit snapshots we’ll first find out their respective unique identifiers, and then tell Git to compare those:

git log --oneline
git diff 7f733ac ab9b27f

The format in which the changes are displayed can be a bit hard to read in the terminal, especially for larger changesets, so it’s best to view them in a real text editor.

Alternatively, Git allows to “time travel” to a specific point in a project’s history. You can inspect how each document looked like at that point in time, without losing any subsequent changes:

git checkout 7f733ac

Once you’re done looking around, don’t forget to return to the present! The easiest way is with:

git checkout main

The main identifier is just a shortcut way to refer to the default timeline (it’s actually the default branch of the timeline, because there can be multiple parallel timelines 🤯, we’ll have a look at these branches in the second part of this introduction).

Finally, Git also allows to undo changes. Even though Git forces us to be very intentional about which changes end up in the changelog (we needed to go through the two-step git add and git commit process after all), sometimes you’ll still want to discard some of them.

There are three possible ways to do this.

git revert ab9b27f

Reverting a commit will keep that snapshot in the version history, and create a new snapshot with the changes removed. This is useful when you want to keep a record of the initial changes, and the fact that they have been reverted.

git reset 7f733ac

Reseting history allows to “rewind the clock” to a specific point im time (addressed via unique identifier), without losing the changes that have been made to documents in subsequent changes. It’s mostly useful as a way to “rewrite” history.

git reset --hard 7f733ac

The most brute-force way to undo changes is with a “hard reset”. Be aware that this will not only “rewind the clock” to a specific commit, but nuke any changes that have been make in the project since that point in time. Those changes will be lost.

Lastly, if you only want to quickly change the message of the last commit, for example because you made a typo, you can:

git commit --amend

Phew, that was quite a lot. Let’s summarize the local Git workflow for change tracking:

bash
$ git init
Initialized empty Git repository in /home/users/git-tutorial/.git/
Start by initialising a repository.

When I am working on our shared project on my own computer, and you are working on the same project on your computer - how can we tell Git about our respective local project copies? By configuring a so-called “remote repository” which points to the URL of that copy:

git remote add my-colleagues-version-of-the-project https://example.com/our-shared-project.git

Now, while this could work in principle, it would require a bit of server configuration on your part, and it would get pretty complicated very quickly with teams of more than two members. This is why we will usually use a Git hosting provider like GitHub or GitLab to store a primary copy of our project, with which all team members can synchronize their local project copies. These Git hosting providers take care of all the complicated server-side stuff involved.

First, let’s create a new empty remote repository called my-test-project on GitHub’s servers:

gh repo create my-test-project

To connect a local Git project with the newly created remote repository, type:

git remote add origin https://github.com/my-git-username/my-test-project

By convention, the remote repository which holds the primary copy of a project is called “origin”.

TODO: ok to leave steps out here?

You can now copy the ssh URLs provided in the Web UI and use them instead of https