--- title: Project management 1. Git basics marp: true paginate: true math: mathjax theme: buutti --- # Project management 1. Git basics ## Basic Git workflow * You have to tell everything you want to happen to Git ***explicitly*** by using ***Git commands*** * A common Git workflow consists of these four steps: 1) ***Edit:*** You make changes in some code file 2) ***Stage:*** You tell Git what files you've changed ([`git add`](#git-add)) 3) ***Commit:*** You tell Git what changes you made in that file ([`git commit`](#git-commit)) 4) ***Push:*** You upload those changes to a remote repository ([`git push`](#git-push)) ## Repositories * ***Repository*** is essentially a place to store code files in * Usually, we are dealing with ***two*** repositories: a ***local*** and a ***remote*** one * A local repository is the one on your computer * A remote repository is stored in a cloud service like GitHub * [Here](https://github.com/borbware/unity-basics-course) is the remote repository for the materials of this course * Changes are synced between these two repositories ***manually*** ## `git init` * Initialization needs to be done for every new Git repository * There are two ways to initialize a repo: * a) Creating the local repository first: * Use `git init` to make your current folder a new Git repository * b) Creating the remote repository first **/** continuing an existing project: * *Clone* a remote repository into your computer (See: [`git clone`](#git-clone)) * ***Note:*** Never initialize a Git repository in a cloud storage folder! ## `.git` folder * Initialization adds a hidden `.git` folder inside a directory * This is where Git stores all its repository data. * ***Do not touch it!*** * The .git folder ONLY appears in the root directory of the repository * If you see the `.git` folder in any of the subdirectories of the repository, something has gone wrong! * You have initialized a repository inside repository ## `git status` * Using the command `git status` shows your current situation. * If you're unsure what to do, it's never a bad idea to run `git status` ![bg right width: 80%](imgs/git-status.png) ## `git add` * Uploading changes to GitHub from your local machine takes three steps (see [Basic Git workflow](1-git-basics#basic-git-workflow) from earlier) * The first phase is ***staging*** with `git add`: * The command `git add readme.md` stages the file `readme.md` * After doing it, `git status` tells this: ``` Changes to be committed: (use "git restore --staged ..." to unstage) modified: readme.md ``` --- * Basically, with `git add file` you tell Git that you want to do *something* with `file`. * ***Note:*** If you just want to push all the changes you've made, you can use `git add .` to stage all the files in your current folder and its subfolders * Be careful! Only do this after checking what changes have been made with `git status` * ***Note 2:*** Use `git add -p` if you only want to stage **some** lines from a file you've worked on. * ***Note 3:*** The counterpart to `git add` is `git rm`, which removes previously added files from Git's perspective ## `git commit` * After you have staged all the files you want, the second step is to ***commit*** your changes * In the commit, you will explain what changes you've made * This message will be visible in GitHub * `git commit -m "add new enemy"` * Every new commit creates a new point in the project timeline. * You can always jump back between different points (See `git checkout`) * Commit message should clearly, concisely tell what kind of changes you have made ## `git push` * The third step is ***pushing*** the changes to GitHub * The previously-made commit action is **local** * No changes have gone to the remote repository yet! * To upload changes to the remote repository, use `git push` * Then you're done! --- * ***Note:*** When pushing for the first time, Git might nag you: ``` fatal: The current branch master has no upstream branch. To push the current branch and set the remote as upstream, use git push --set-upstream origin main ``` * You can just follow its orders (see the command on the third line!) and you're good to go * Generally, when Git gives you a warning, error, or some other message, it's a good idea to ***read it and follow the orders***. ## `git remote` * If you have initialized a Git repo already with `git init`, don't use `git clone`! * Instead, run `git remote add origin ` * Here, the name `origin` refers to the remote repository * `origin` is just the default name for a remote: other names can be used instead! * To check which remote repository the current local repository is linked to, use * `git remote -v` ## Exercise 1a. Initializing a repo * Initialize a new repository locally. * Create a new file `GitTest.md` with some lines of text in it. * Commit changes. * Create a new empty repository on GitHub. * Use `git remote add origin ` to connect your local repo to the GitHub repo. * Push changes to GitHub. Go to GitHub and see that `GitTest.md` is there! ## `git pull` * `git pull` applies changes from the remote repository into the local repository * Counterpart to `push` * Very common when working in a team * **Note**: During teamwork it's a good idea to ***always pull before pushing*** * If you only work alone on a single computer, seldom needed ## `git clone` * Remote repositories have an URL address that can be used to download the code to your machine * The address can be found under the *Clone* button in the repository webpage * Use the URL to download a remote repository: * Run `git clone ` * Example: `git clone https://github.com/borbware/unity-basics-course.git` * Remember: this initializes the repo, so `git init` not needed. * Simplest way to create a new, empty repository: * 1 - Initialize the repo in the Github/Gitlab/etc website * 2 - Clone the repo. ## Exercise 1b. Cloning a repo * Create a new repository on GitHub and clone it with HTTPS to your machine. * Then, create a new file `GitTest.md` with some lines of text in it. * Commit and push changes to GitHub. * Go to GitHub and see that the file is there! ## Extra: HTTPS vs SSH * There are two ways to communicate with GitHub, ***HTTPS*** and ***SSH*** * HTTPS: `https://github.com/borbware/unity-basics-course.git` * the easier way * you log in with your GitHub credentials that get stored in the Git Credential Manager * SSH: `git@github.com:borbware/unity-basics-course.git` * [Connecting to GitHub with SSH](https://docs.github.com/en/authentication/connecting-to-github-with-ssh) * You need to generate a computer-specific SSH key and add it to your GitHub settings ## `.gitignore` * Sometimes your project has local files that should ***NOT*** be uploaded to GitHub * List those files in a `.gitignore` file in your Git project folder * You can create it by yourself and define file names or folders which Git will then ignore in the commits, e.g., ``` someScript.cs /folder *.html ``` * ***Note:*** If you add a file to `.gitignore` that was committed earlier, Git doesn't "forget" it automatically. * You can make Git forget it with `git rm --cached filename` ## VS code: Source control * The ***source control*** tab is very useful for managing your Git workflow * Unstaged changes are shown under ***Changes*** * Press "$+$" to stage a file * Staged files are shown under ***Staged changes*** * Press "$-$" to unstage a file * Press "$\curvearrowright$ 📄" to open the file * Click the filename to see what changes you've made in a side-by-side comparison view (see the next slide!) * Press "$\curvearrowleft$" to discard the changes made to the file (be careful!) ![bg left:33% width: 80%](imgs/vscode-source-control.png) --- ![bg height:90%](imgs/vscode-working-tree.png) ## Exercise 2. Git collaboration * Work on this exercise with your group. * Choose someone's test repository from Exercise 1b to use in this exercise. * While others clone the repo to their machine, the owner should add other group members as collaborators of the repo in the repository's settings on GitHub. * Then, everyone should make changes to the markdown file in the repository! What happens if you make changes to the same line simultaneously? ## Troubleshooting: master vs. main ``` error: failed to push some refs to [your-url] ``` * Possible reason: GitHub has a `main` branch, while your local repository has `master` * ***Fix:*** Run `git branch -m main` to rename your local `master` to `main` ## Note about longer `push` and `pull` commands * After initialization, why do I have to use longer `push` and `pull` commands? * Short answer: because we didn't clone the repo, but rather added the remote into an empty one with `git remote add origin`. * `git pull origin main`: After adding a remote, we don't yet know which ***branch*** to pull from. `main` (or `master`!) is the default branch * `git push --set-upstream origin main`: In the first `push`, we decide which branch to link our current branch into. * Afterwards, we can just use `git push` and `git pull`. ## Reading * [Using version control in VS code](https://code.visualstudio.com/docs/sourcecontrol/overview)