Skip to content

Instantly share code, notes, and snippets.

@percyvega
Last active December 27, 2022 22:59
Show Gist options
  • Save percyvega/5fd720cc1a92f78ddbeaf6061eec67b7 to your computer and use it in GitHub Desktop.
Save percyvega/5fd720cc1a92f78ddbeaf6061eec67b7 to your computer and use it in GitHub Desktop.

CONCEPTS

Take a clone of a remote repository and run git branch -a (to show all the branches git knows about). It will probably look something like this:
	* master
	  remotes/origin/HEAD -> origin/master
	  remotes/origin/master
Here, master is a branch in the local repository. remotes/origin/master is a branch named master on the remote named origin. You can refer to this as either origin/master, as in:
	git diff origin/master..master
You can also refer to it as remotes/origin/master:
	git diff remotes/origin/master..master
These are just two different ways of referring to the same thing (incidentally, both of these commands mean "show me the changes between the remote master branch and my master branch").
remotes/origin/HEAD is the default branch for the remote named origin. This lets you simply say origin instead of origin/master.

Technically there aren't actually any "remote" things at all in your git repo, there are just local names that should correspond to the names on another, different repo. The ones named origin/whatever will initially match up with those on the repository you cloned-from:
	git clone ssh://some.where.out.there/some/path/to/repository # or git://some.where...
makes a local copy of the other repo. Along the way it notes all the branches that were there, and the commits those refer-to, and sticks those into your local repository under the directory .git/refs/remotes/origin/.

Depending on how long you go before you git fetch or equivalent to update "my copy of what's some.where.out.there", they may change their branches around, create new ones, and delete some.
	When you do your git fetch (or git pull which is really fetch plus merge), your repository will make copies of their new work and change all the refs/remotes/origin/<name> entries as needed.
	It`s that moment of fetching that makes everything match up (well, that, and the initial clone, and some cases of pushing too?asically whenever git gets a chance to check).
Git normally has you refer to your own refs/heads/<name> as just <name>, and the remote ones as origin/<name>, and it all just works because it's obvious which one is which. It's sometimes possible to create your own branch names that make it not obvious, but don't worry about that until it happens.
	Just give git the shortest name that makes it obvious, and it will go from there: origin/master is "where master was over there last time I checked", and master is "where master is over here based on what I have been doing".
	Run git fetch to update git on "where master is over there" as needed.

WORKSPACE (a.k.a. work tree, working directory): red
INDEX/STAGING AREA: green
GIT REPOSITORY/DIRECTORY:
	LOCAL REPOSITORY: a local copy of the remote since last pull
	REMOTE REPOSITORY: a remote and updated copy of the directory on origin

origin/master: local master copy of HEAD on origin

Create SSH Key

ls -ltr ~/.ssh/											// go to the SSH key folder
ssh-keygen -t rsa -b 4096 -C "percyvega@gmail.com"		// enter your email
	Enter id_rsa
	Enter your password
eval `ssh-agent -s`										// verify the ssh agent is present
ssh-add ~/.ssh/id_rsa 									// add key to ssh agent
clip < ~/.ssh/id_rsa.pub								// copy key contents
ssh -T git@github.com 									// authenticate
Verify that the [project]/.git/config file has something like https://percyvega@github.com... instead of https://github.com...

Manage your remote repo

List your existing remotes (fetch and push)
	$ git remote -v (or $ git config -l | grep remote.origin.url)
Overwrite remote's URL
	$ git remote set-url origin git@github.com:USERNAME/REPOSITORY2.git
Remove remote repo
	git remote rm origin
Add remote repo
	git remote add origin git@github…
Set upstream repo
	git branch --set-upstream-to=origin/main [main]

INITIALIZE LOCALLY (immediately after a repository has been initialized remotely)

Create a project in GitHub.com:
	{Go to GitHub.com and use web UI to create new repository}

Initialize the folder to make it a git repository
	mkdir /path/to/your/project													// if folder doesn't exist
	cd /path/to/your/project
	git init																	// will create the .git/ folder
Add your (red) local changes to the (green) INDEX/STAGING AREA:
	git add .gitignore															// git add --all .
Commit your (green) INDEXed/STAGEd/registered changes to (white) repo
	git commit -m 'My initial commit'
Associate to its remote counterpart
	Using ssh:
		git remote add origin git@bitbucket.org:percyvega/project-name.git
	Using https:
		git remote add origin https://github.com/percyvega/project-name.git
Verify the remote URL
	git remote -v
Pushes the (white) repository and its refs to (not shown) origin for the first time
	git push -u origin master

BRANCHES

List branches:
	git branch -l or git branch												// list local
	git branch -r															// list remote
	git branch -a															// list all (local + remote)

Switch branch:
	git checkout <branch_name>												// checkout a branch
	git checkout <hash>														// checkout a hash

Create (based on current changes):
	git checkout -b <new_branch_name>										// create and switch to branch
		then
	git push --set-upstream origin <branch_name>							// after creating the branch locally, persist remotely
	
	git branch <new_branch_name>
		then
			git checkout <branch_name>
		and
			git push --set-upstream origin <new_branch_name>				// push newly created branch to remote whether commits were made or not
		or
			git push origin/<new_branch_name> <new_branch_name>				(or git push origin <new_branch_name> <new_branch_name>)
		or
			git branch -u upstream/<new_branch_name> [<new_branch_name>]	// track remote branch from origin
		of
			git push origin [<new_branch_name>]								// push newly created branch to remote when no commits yet made

Rename branch:
	git branch -m [<old_branch_name>] <new_branch_name>						// change local but not remote
	git push origin --delete [old_branch_name]								// delete remote
	git push origin <new_branch_name>										// re-create remote branch with new name
	git branch -u origin/<new_branch_name>									// rename remote/upstream tracking

Delete a local branch
	git branch -D [branch_name]
Delete a remote branch
	git push origin --delete [branch_name]

Remove an element just excluded in .gitignore, element must be untracked
	git rm --cached [filename]												// untrack a file
	git rm -r --cached [directory]											// untrack a folder structure

Exclude in [project_path]/.git/info/exclude
	echo [file_path_relative_to_project] >> .git/info/exclude
	git update-index --assume-unchanged [file_path_relative_to_project]

Merge branch_with_changes into destination_branch
	git checkout <destination_branch>
	git pull
	git merge origin/<source_branch>										// e.g. git merge origin/master
	if conflicts found:
		git mergetool
	git push																// don't forget to push after merging!
To pull changes from the origin remote, master branch and merge them to the local checked-out branch
	git merge origin master
	git push
To pull changes from the locally stored branch origin/master and merge that to the local checked-out branch. The origin/master branch is essentially a "cached copy" of what was last pulled from origin, which is why it's called a remote branch in git parlance. This might be somewhat confusing.
	git pull origin/master

FILES

INCOMING
	Update local repository branches with remote repository changes without modifying WORKSPACE files.
		git fetch [remote]
			e.g. git fetch origin main:main
	Update local repository and WORKSPACE branches with remote repository changes, modifying WORKSPACE files.
		git pull [remote] [branch]

OUTGOING
	Add your local additions (in red) to the INDEX/STAGING AREA (in green):
		git add .
	Add your local changes (in red) to the INDEX/STAGING AREA (in green):
		git add *.java
		git add README
		git add .															// add to INDEX/STAGING AREA those created
		git add . +
		git add -u															// remove from INDEX/STAGING AREA those deleted
		git add --all .														// add your local changes (+, - and ~)
	Commit your INDEXed/STAGEd/registered changes (in green):
		git commit -m <message>												// specify message log here
		git commit -a														// specify message log in a window file
	Push changes to origin:
		git push

COMPARE
	List local file changes and additions (except additions are inside folders not yet checked-in):
		git status
	List visually file changes:
		git gui
	List the commits of a branch or a of specific file:
		git log [specific_file]
		git log --raw
			Shows the files that changed per commit
		git log --oneline
			Show one line per commit
		git log --graph
		git log --oneline --graph
		git log --oneline --graph --all --decorate

	List differences between local branch and remote (origin) version:
		git fetch origin
			then
		git difftool --name-only master origin/master

	List visually a tree of differences in branches or specific file:
		gitk [specific_file]												// uses git tool
		git difftool [specific_file]										// uses whatever difftool was defined
	List local file differences:
		git diff[tool] <file>												// folder and branches too???
	Show file's content differences between branches
		git diff[tool] <branch1> [<branch2>]					// if branch2 is not specified, local branch will be compared with branch1
		git diff[tool] <branch1> [<branch2>] -- <file>
	List differing files between the workspaces of branch1 and branch2 (use master..my_branch to see branch changes):
		git diff --name-status [<branch1>]..[<branch2>]						// specify at least one of the two branches
	List the files changed at a specific commit (gotten from git log):
		git diff-tree --no-commit-id --name-only -r 2437e0330494441a72f65e336f09a7b95e795ea1
	Compare the committed changes of a branch against main
		git difftool main..[branch_name]
	Compare any difference between your local code and that of main
		git difftool main

DISCARD
	Discard NEW elements (files and directories):
		git clean -fd
	Discard NEW files (in ALREADY registered directories):
		git clean -f [absolute_path]
	Discard CHANGED elements (deletions and modifications):
		git checkout <file_folder_path>										// specific file or everything under folder
		git reset --hard													// restore to local repository (last commit)

REBASE

git rebase -i main
	fixup with an f all following commits
If there are conflicts
	You can either use
		mergetool
			git mergetool
			Fix all conflicts
		Or fix manually
			For each file with conflicts
				Using IntelliJ, resolve each of the conflicts.
			End
	Immediately after this
		git add --all .
		git rebase --continue
			The file will open only with the commit of main. Don't touch anything. Save and close.
mcis
git push -f

STASH

Git stash stores the changes you made to the working directory locally (inside your project's .git directory; /.git/refs/stash, to be precise) and allows you to retrieve the changes when you need them.
$ git stash
	Saves your changes
$ git stash save "Message that describes your changes"
	Saves your changes and assigns a description to your stash
$ git stash pop
	Apply the changes stashed in the latest stash (i.e. stash@{0}) and remove that stash
	Optionally, you can specify a stash_id e.g. $ git stash pop stash@{2}
$ git stash apply
	Apply the changes stashed in the latest stash (i.e. stash@{0}) but keep the stash
	Optionally, you can specify a stash_id e.g. $ git stash apply stash@{2}
$ git stash -u (or $ git stash --include-untracked)
	Stash untracked files
$ git stash -a (or $ git stash --all)
	Stash untracked files and ignored files
$ git stash -p (or $ git stash –patch)
	Stash specific hunks (file changes)
$ git stash list
	List your stashes
$ git stash drop <stash_id>
	Drops a specific stash from the list
$ git stash clear
	Clears the stash list
$ git stash show
	Show a diff of the latest stash
	Optionally, you can specify a stash_id e.g. $ git stash show stash@{2}
	Optionally, you can see the file changes e.g. $ git stash show stash@{2} --patch

PROBLEMS/SOLUTIONS

Problem
	fatal: Authentication failed for
Solution
	Go to the repo and run
	1) git config --global credential.helper store
	2) git push
	3) Enter your percyv credentials

Problem
	fatal: Not possible to fast-forward, aborting
Solution
	git pull --rebase
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment