⬅️ **[[$-Tools|Tools]]** *** # Git - Version Control System ![[Git-Data-Transport.png]] [Git Guide 01](https://rogerdudler.github.io/git-guide/index.de.html) [Git Guide 02](https://de.atlassian.com/git/tutorials/setting-up-a-repository) [Visual Git Guide](https://marklodato.github.io/visual-git-guide/index-de.html) ``` sudo apt-get install git gitk ``` ## FUC - Frequently Used Commands - [Atlassian - Git Merge vs. Rebase](https://www.atlassian.com/git/articles/git-team-workflows-merge-or-rebase) | Command | Comment | |:-------------------------------------------------------------------------------------- |:----------------------------------------------------------------------------- | | **Configuration:** | | | `git config --global user.name "Tobias Mauritz"` | Global Git user.name in `~/.gitconfig` | | `git config --global user.email "[email protected]"` | Global Git user.email in `~/.gitconfig` | | **Daily Process:** | | | `git pull` | Update local repo | | `git status` | Show status of local changes | | `git diff` | Show diff of file | | `git log` | Show log of previous commits | | `git add <file(s)>` | Add changed one or more files to stage for commits | | `git add *` | Add all changed files to stage for commit | | `git checkout <file>` | Reload file and overwrite local changes. | | `git reset <file>` | Remove an added file from stage (unstage) | | `git rm <file-name>` | Delete file in Git and file system | | `git commit -m "<comment>"` | Commit your changes locally | | `git push origin master` | Push your commit(s) to the remote repository | | **Branching:** | | | `git branch <branch name>` | Create a new Branch on your localy repository | | `git checkout <branch name>` | Checkout the specified branch to work with it. | | `git merge <branch name>` | Merges `<branch name>` to currently checked out branch e.g. master. | | `git push origin <branch name>` | Push your local branch to the remote repository | | `git branch -d <branch name>` | Delete a local Branch on your localy repository | | `git push origin --delete <branch name>` | Delete branch on the remote repository | | **Tags:** | | | `git tag` | Show all tags | | `git tag -a RC19.2.00.c000 -m "RC19.2.00.c000 containing XY"` | Add new with a message in local repository | | `git tag -a RC19.2.00.c000 9fceb02 -m "Message here"` | Add tag to specific commit | | `git push origin RC19.2.00.c000` | Push tag to remote repository | | **Advanced:** | | | `git reset --soft HEAD^` | Move one commit back in local repository | | `git init --bare <RepoName>.git` | Create a new Git repository | | `git clone https://github.com/tobi/project.git` | git Clone | | `ssh-agent bash -c 'ssh-add ~/.ssh/id_rsa; git clone [email protected]:tobi/project.git'` | git clone with specific SSH Key and ssh-agent | | `git show COMMIT` | Shows Diff and commit message of specific Commit | | **Clean-up** | | | `git reset --hard` | Checkout and reset whole Repository. Reverts all changes on any managed file. | | `git clean -fdx` | Cleans also not-Git-managed files that `git reset --hard` does not delete. | ### GitHub Fork 1. Fork directly on GitHub. Rename and make some config changes there. 2. Pull your own fork 3. Maybe create a new branch to have this clear. `git branch <new-Branch-Name>` 4. Setup your Fork to be synced with the original a. Show your current remotes with `git remote -v` b. Copy the Git Clone Address from the Original Repository on GitHub c. Add a new remote with `git remote add upstream [email protected]:<username>/<repo>` 5. Check your current branches with `git branch -a` 6. Sync your fork with the original using the new upstream branch a. `git fetch upstream` b. `git merge remotes/upstream/<OriginalBranch>` 7. Now your fork is in sync with the Original Repository. ### --deprecated-- Eclipse Git: See [[Eclipse]]. - Status Git Perspective --> Git Staging Tab - Pull: Rechtsklick --> Pull - Add/remove Angepasste Dateien lokal für einen Commit in die Staging Area geben. - Git Perspective --> Git Staging Tab --> jeweilige Datei in von "Unstaged Changes" zu "Staged Changes" ziehen - Commit Lokal einen Zustand festsetzen - Git Perspective --> Git Staging Tab --> in "Commit Message" eintragen --> auf "Commit" klicken - Push Lokale Änderungen in das Remote Repository hochladen. - Git Perspective --> Git Staging Tab --> in "Commit Message" eintragen --> auf "Commit and Push" klicken - Branches ### Move Repository ``` pull git branch -a git checkout branch-name git fetch --tags git remote rm origin git remote add origin <url to NEW repo> git remote add origin [email protected]:/reaver1202/life.git git push origin --all git push --tags ``` ### Issue: File empty ```ad-failure - `git clone` or `git fsck --full` bring error - Error Log ```sh > Gogs: Internal error remote: error: object file ./objects/aa/b96b8dc7f354c72d9429799a0c3f5f6c34952b is empty remote: fatal: loose object aab96b8dc7f354c72d9429799a0c3f5f6c34952b (stored in ./objects/aa/b96b8dc7f354c72d9429799a0c3f5f6c34952b) is corrupt remote: aborting due to possible repository corruption on the remote side. ``` ``` - Copy the contents of the `.git` directory from the good local repo to the server's file space (replacing all contents under the `repo.git/` directory). - Then ran `git fsck --full` to confirm the problem was gone. ## Git Concepts ### Tagging - [Git Guide - Tagging](https://git-scm.com/book/en/v2/Git-Basics-Tagging) - **Git Tag** - Tags are mainly used for future reference to the specific version of the project, by tagging a commit. You can always use branches of course, but if you change versions a lot, you will end up with lots of unused or rarely used branches. - Practically, tags are branches without branches anyway, just adding a way to reference a specific version of the project to reduce complexity. - **Git Tag vs. GitHub Release** - A `tag` is a pointer to a specific commit. This pointer can be super charged with some additional information (identity of the creator of the tag, a description, a GPG signature, ...). - A `tag` is a git concept whereas a `Release` is GitHub higher level concept. - As stated in the official announcement post from the GitHub blog: "Releases are first-class objects with changelogs and binary assets that present a full project history beyond Git artifacts." - A `Release` is created from an existing `tag` and exposes release notes and links to download the software or source code from GitHub. ### Rebasing - [Git Guide - Git-Branching-Rebasing](https://git-scm.com/book/en/v2/Git-Branching-Rebasing) - [Stack Overvflow - git-commits-are-duplicated-in-the-same-branch-after-doing-a-rebase](https://stackoverflow.com/questions/9264314/git-commits-are-duplicated-in-the-same-branch-after-doing-a-rebase) - [Stack Overvflow - whats-the-difference-between-git-merge-and-git-rebase](https://stackoverflow.com/questions/16666089/whats-the-difference-between-git-merge-and-git-rebase/16666418#16666418) - [git-when-to-merge-vs-when-to-rebase](https://derekgourlay.com/blog/git-when-to-merge-vs-when-to-rebase/) **Pro Git rule:** never rebase commits that have ever existed anywhere but your local repository. Use merge instead. - `git pull` = `git fetch` + `git merge` against tracking upstream branch - `git pull --rebase` = `git fetch` + `git rebase` against tracking upstream branch **Ablauf:** 1. Änderungen vornehmen (lokal) 2. Commit (kein Push) (lokal) 3. Pull mit Rebase (remote Änderungen holen, anwenden, nun auch lokal) (evtl. merge Konflikte auflösen (wären auch bei normalem Pull vorhanden und würde einen merge commit verursachen), dadurch wird der eigentliche Commit verändert und an die neue Basis angepast) 4. Commit ist nun in der History (lokal) 5. Push (lokale Änderung nun remote) ### Commit number as Hash Bernd hat mir auch erklärt warum das Hashes sind und nicht eine fortlaufende Nummer. Eig recht "simpel". Bei SVN ist das Repository ja Zentral und ein commit pushed ja auch direkt in diese zentrale Repository. Bei Git hat jeder das gesamt Repository lokal. und jeder kann lokale Commits machen, sie verwerfen und mehrere später zu einem großen commit zusammenfügen. Dadurch sieht bei jedem von uns das Repository intern für Git immer etwas "anders aus". Auch hier nun beim cherry-pick sehen wir das wir mit dem Hash einen einzigartigen Commit uns aus einem anderen branch herholen. Eine vernüftige aufsteigende Nummerierung ist da eher verwirrend, aber auch undenkbar wegen der lokalen commits die irgendwann erst evtl. gepushed werden. ### Verwendung von .gitignore - Gloables .gitignore und `.DS_Store` files ignorieren ```bash git config --global core.excludesfile ~/.gitignore echo .DS_Store >> ~/.gitignore ``` - Example: ```bash *.aux *.lof *.log *.out SLAQuickstart.pdf *.toc ``` ### Detached HEAD [Git Head detached](http://www.it3.be/2014/05/07/git-head-detached/) # *** Related: - [[$-Automatisierung]] - [[$-Software|Software]]