Setting up SSH Authentication

Generate an ssh key: ssh-keygen -C "username@example.com"
SSH Key will be generated at: "~/.ssh"
Copy contents of public key then upload it to Git hosting service: cat ~/.ssh/id_rsa.pub
Start up the SSH agent which supplies Git with the credentials: eval "$(ssh-agent -s)"
Add the private key to the SSH agent: ssh-add ~/.ssh/id_rsa

Setting up multiple SSH keys

Useful when needing to work with multiple git accounts like for personal and for work. Open the file ~/.ssh/config and add the different SSH keys like this:

# foo account
Host github.com-foo
	HostName github.com
	User git
	IdentityFile ~/.ssh/id_rsa_foo

# foo-bar account
Host github.com-foo-bar
	HostName github.com
	User git
	IdentityFile ~/.ssh/id_rsa_foobar

When cloning the repository, make sure to clone it with the corresponding host name: git clone git@github.com-foo:kumorikuma/kumorikuma.dev.git or git clone git@github.com-foo-bar:kumorikuma/kumorikuma.dev.git

This sets up the remote url. So if you have an existing git repo, you can change the remote url: git remote set-url origin git@github.com-myNewIdentity:kumorikuma/kumorikuma.dev.git

Thanks to https://gist.github.com/jexchan/2351996

Initializing repository

Initialize a new repository

  • First need to create a new empty repository on the Git hosting service, and obtain the ssh Git url for the repository.
  • In a local directory running git init creates a .git subdirectory that contains all the git metadata for your repository.
  • Now link the repository url to the hosting service by adding the url as a remote: git remote add origin [git_url] (origin is actually just a name and it can be anything)
  • Verify that it’s added by using: git remote -v
  • Can unlink it and add a different remote by using: git remote rm [remote_name]

Initialize from an existing repository

git clone [ssh_url]

Retrieving Files

Get changes from server (aka fetch / pull)

git pull --rebase

Git will first fetch all remote changes from the server, then the –rebase flag will attempt to move your changes onto the most recent commit.

If you leave out this flag, git will instead attempt to “merge” your changes into the most recent commit and create an additional, unnecessary commit.

Handling Merge Conflicts

If you don’t want it and it’s staged…

If you don’t want it and not staged…

When merging a file that’s difficult to merge, like a 3D scene…

Commiting Files (aka saving changes)

Whenever any changes to files are made, these are detected and known as uncommited changes.

uncommited changes -> staged changes -> committed changes

Specify files to be committed (aka “stage”)

git add . for adding everything

git add "path/to/file" for a specific file

Remove files that are about to be committed (aka “unstage”)

git restore

Undo-ing a commit

git reset --soft HEAD~1

“Reset will rewind your current HEAD branch to the specified revision. In our example above, we’d like to return to the one before the current revision - effectively making our last commit undone.

Note the –soft flag: this makes sure that the changes in undone revisions are preserved. After running the command, you’ll find the changes as uncommitted local modifications in your working copy.

If you don’t want to keep these changes, simply use the –hard flag. Be sure to only do this when you’re sure you don’t need these changes anymore.” - git-tower

Combining Commits (squashing them)

You can combine your current commit with the previous one using an interactive rebase. Run the following command to start an interactive rebase for the last two commits (can do more than two):

git rebase -i HEAD~2

You’ll see a text editor open with a list of commits (in this case, the last two). The first word on each line will be “pick”. Change the “pick” for the second commit (your current commit) to “squash” or “s” (which is a shorthand for “squash”). It should look like this:

pick abcdef1 First commit message
squash abcdef2 Second commit message (your current commit)

Save and close the editor. Git will now squash the second commit into the first one. Another editor window will open, allowing you to edit the commit message for the combined commit. Modify the message as needed, save, and close the editor.

Now your current commit has been combined with the previous one. Keep in mind that this operation rewrites the commit history, so if you’ve already pushed these commits to a remote repository, you’ll need to force-push the changes with git push --force (use this with caution as it can cause issues for other collaborators).

Uploading Changes to Server

git push

Force pushing

[DANGEROUS] git push --force

Completely overrides what’s in the server with local git repository.

Using Git with large binary files (Git LFS)

Install Git LFS

  • On Ubuntu, run the following to install LFS:
    $ curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | sudo bash
    $ sudo apt-get install git-lfs
    $ git lfs install
    
  • Configure Git LFS for the repository by setting up a .gitattributes file. Here is an example file setup for use with Unity.
  • To ensure that no one pushes big files to the repository accidentally without using LFS, you can use a Git hook to run a check on filesizes before pushing. Here is an example of such a pre-push hook. By default, Git hooks are installed to [Repo]/.git/hooks. However, this directory is not inside the repo and managed under source control. You can instead move the hooks to a different folder in the repo and set the path in the git config: git config core.hooksPath hooks.

:warning: Git LFS may not work with SSH out of the box. It worked with Github but not Azure DevOps. Try using HTTPS authentication instead. Error might look like “batch request: unexpected end of JSON input” and “error: failed to push some reds to […]”

Migrate tool

git lfs migrate is base command with three options: info, import, export

info is helpful to use to debug what is happening as it will not actually performing the migration

import will convert files that are not tracked under LFS into LFS. By default it will REWRITE GIT HISTORY to remove the files from the commit history since they inflate the repository size. Therefore you should ideally be in a position where you can do a force push and make sure everyone on the team knows you are doing this.

git lfs checkout if all you see are file pointers and not actual files, can run this to download the files. Migrate can sometimes just leave only LFS pointers around.

git lfs migrate import --include-ref=main --include="*.zip"

Convert all zip files in every local branch git lfs migrate import --everything --include="*.zip"

Convert all files over 100K in every local branch git lfs migrate import --everything --above=1000Kb

Git Diff

For a list of files to be pushed, run: git diff --stat --cached [remote/branch]
Example: git diff --stat --cached origin/master

For the code diff of the files to be pushed, run: git diff [remote repo/branch]

To see full file paths of the files that will change, run: git diff --numstat [remote repo/branch]

Helpful Commands

git log

Leave a comment