Skip to content

Instantly share code, notes, and snippets.

@rustymagnet3000
Last active December 13, 2023 06:50
Show Gist options
  • Save rustymagnet3000/b6d286a066ea08ee3bd9f9130b8be81e to your computer and use it in GitHub Desktop.
Save rustymagnet3000/b6d286a066ea08ee3bd9f9130b8be81e to your computer and use it in GitHub Desktop.
Github tips

git and GitHub tips

merge into Staging

git checkout staging
git pull origin staging
git merge foo_branch
git push origin staging

Remove a changed file from a Pull Request

git checkout HEAD^ -- README.md

assume-unchanged vs skip-worktree

--assume-unchanged flag -> the user promises not to change the file.

--skip-worktree flag -> instruct git not to touch a specific file ever because the file is going to be changed locally and you don't want to accidentally commit the changes.

skip-worktree takes precedence over assume-unchanged when both are set.

Clone

Only latest code from Master

git clone --depth=1 --branch=master git@github.com:myrepo.iosdemo.git

Configuration

List

git config -l

Difference

Short summary of difference

git diff --shortstat

View each line of change

git diff

Details of what files changed

git whatchanged

Details of files changed with commit

git diff-tree --no-commit-id --name-only -r 88bbbb

Commit stats

git log --stat

GitHub Actions

Verify locally

brew install act

Dry run

act -n

Will run entire file ( but won't build Win or macOS)

act

List the default actions

act -l

List actions for a specific event

act workflow_dispatch -l

Find data

Inside of github.com

org:foobiz "string to find"
org:foobiz "string" language:yaml

In cloned repo

git grep

local filename searches

find . -size +2M
find . -name '*.lock'
find . -name '*\<*'     // search for filename using a Windows reserved character '<'

list files in branch

git ls-tree -r master --name-only

list files

git ls-files

List folders

git ls-files | xargs -n 1 dirname | uniq

Personal Access Tokens

Remove PAT from Keychain

git credential-osxkeychain erase
host=github.com
protocol=https

Generate PAT

https://docs.github.com/en/github/authenticating-to-github/creating-a-personal-access-token

Store PAT in KeyChain

export PAT=xxx
export NAME=rustyrobot

echo "\
protocol=https
host=github.com
username=${NAME}
password=${PAT}" | git credential-osxkeychain store

Branch

Create

git branch foobar

Create new branch and switch to it

git checkout -b new_fix

Create new branch from a PR that is pending merge

git checkout -b new_fix_2 new_fix_1

Create alias for recent branches

git config --global alias.recent 'branch --sort=-committerdate --format="%(committerdate:relative)%09%(refname:short)"'
git recent | head -20

show commit branch is pointing toward

git log -1

view all branch names

ls .git/refs/heads

view

git branch

move to branch

git checkout foobar

delete

git branch -d foobar

gitignore

# delete gitignore from commits
# if you created a gitignore file when you created a repo
# then wanted to remove it from version control:

git rm --cached .gitignore

# Then add `.gitignore` inside the .gitignore file.

# Remove Cached Python files from a Pull Request
find . -name '*.pyc' | xargs -n 1 git rm --cached

#### Remove .DS_Store files ( macOS )
echo '*.DS_Store' > ~/.gitignore
git config --global core.excludesfile ~/.gitignore

History

Blame

git blame config.yml

A single file

git log --follow -p -- myapp/dumpClasses.m

blame

Remote

Check remote

git remote -v

Check origin

git remote show origin

Update ( to check difference from local code )

git remote update

Delete remote branch

git push origin --delete deadBranch

Status, after remote update

git status
Your branch is behind 'origin/master' by 1 commit, and can be fast-forwarded.

Release / Tag

List remote tags

git ls-remote --tags origin
git tag                         # list them locally, after ls-remote

Create new tag

git checkout master
git pull
git tag -a 0.1.3 -m 'version 0.1.3'
git push origin --tags

Merge

Manual merge into Staging

This if for cases where you can manually merge into a pre-master branch which doesn't expect a full Pull Request.

git checkout staging
git pull origin staging
git merge foo_branch
git push origin staging

Worked on Master by mistake

// works if you have not committed any code to Master branch
git checkout -b foobar-branch
git add .
git commit -m "Moved all work to foobar branch"
git push --set-upstream origin foobar-branch

git checkout master
git pull    // if Master is behind

git merge foobar-branch
git push

Avoid Merge Conflict

git merge BranchA
// lots of merge conflicts.

git reset --merge
git checkout BranchA
git log
git merge -s ours master
git checkout master
git merge BranchA
git push

This is only good for this use-case: BranchA was taken from Master. Both were updated for several weeks / months. You don't want any of the new commits from Master. You just want BranchA to be copied to Master [ and to throw away any of the recent commits to Master ].

Detached Head

A beautiful example in this answer of how to recover from a detached head.

Git Push missed Deleted files

Changes not staged for commit:
 deleted:    ../15_folder/README.md

git add -u
git commit -m "Removing old files that were missed when I changed folder names and file names"
git push

Remove files

git rm -r --cached .
git rm -r --cached foobar.xcodeproj/project.xcworkspace/

Rebase - update branch with remote

Another dev has made a push to the origin on which your local branch is based. To get updated:

< inside of branch >
# Pull the changes to the origin of the Branch
git fetch origin

# Rebase. Write the name of the branch where you did "git checkout -b my_branch"
git rebase origin/sandbox

# --force-with-lease is safer way to push, in case another developer has made an update
git push origin my_branch --force-with-lease

Fix a bad push

Pushed file to PR that you don't want

#remove file from PR
git checkout origin/master -- Brewfile.lock.json
git checkout origin/master -- app/foo.go

Committed to Master without a PR

If Branch Protection is off or something else ( like admins can push to Master that is Protected ) and you want the code back to where it was before the commits that pushed to Master in error, use git revert.

git revert requires the id of the commit you want to remove keeping it into your history git reset requires the commit you want to keep, and will consequentially remove anything after that from history.

git revert [hash of commit to remove]
git reset [hash of commit to keep. All subsequent commits will be erased from history]

Force

git push -f

Amend Commit Message after git push

git commit --amend
// ensure nobody else pulled the code
git push --force

Amend Commit Message before git push

 Commit message does not pattern BLAH|FOO|BAR|BLAHBLAH

! [remote rejected]     (pre-receive hook declined)

git commit --amend . Then add the Pattern required for the commit message

Mistake in the commit BEFORE push

If you added files by mistake to a commit - or the gitignore had not yet taken affect, you get them back to staged area: $ git reset --soft HEAD^

This applies BEFORE you did a git push.

Once you are here, run to clear up the staged commit.

git rm --cached -r myapp/not_on_repo/
rm 'myapp/not_on_repo/logs.txt'
rm 'myapp/not_on_repo/terms.json'

Mistake in the commit AFTER push

https://stackoverflow.com/questions/8225125/remove-last-commit-from-remote-git-repository

git reset HEAD^ # remove commit locally
git push origin +HEAD # force-push the new HEAD commit

This did not work in a small test project I used as Master was protected by default with gitlab. First I had to remove the Protected Branch so my git push origin +HEAD worked.

https://stackoverflow.com/questions/32246503/fix-gilab-error-you-are-not-allowed-to-push-code-to-protected-branches-on-this

This was not a perfect solution as it create issues for other collaborators.

git pull

https://stackoverflow.com/questions/1125968/how-do-i-force-git-pull-to-overwrite-local-files

If you don't want to merge the existing branch changes, use:

git fetch --all
git reset --hard HEAD
git pull

But a better way is..

git stash
git pull
git stash pop

If you still hit problems, clear untracked local files: git clean -d -f .

Dangling Commits

If you have local commits and a remote master, if you are too quick with a git reset --hard origin/master you can create a Dangling Commit. Where the local commit is not known to the remote master but is it "dangling" in the local git commit history. The good news is you can recover the files you created locally:

List dangling commits

git fsck --lost-found

Inspect each dangling commit

git reset --hard <commit id>

My files reappeared when I moved to the dangling commit.

git status for the reason:

“HEAD detached from <commit id where it detached>”

Delete hidden folders you don't require

git rm -r --cached scripts/.idea/

Large files

If your git push is rejected due to some overly large file, you can locally installed git-lfs.

brew install git-lfs
git lfs install
git lfs track MyBigFile.a
git add .
git commit -m "Foo"

Change git history authors

git filter-branch -f --env-filter "GIT_AUTHOR_NAME='Rusty Robot'; GIT_AUTHOR_EMAIL='rusty@robot.com'; GIT_COMMITTER_NAME='Rusty Robot'; GIT_COMMITTER_EMAIL='rusty@robot.com';" HEAD

git pull origin master --allow-unrelated-histories

git push --set-upstream origin first_commits

Set Author globally

If you don't like the default author name and author email you can change then globally on a specific machine.

$ cat ~/.gitconfig
$ sudo nano ~/.gitconfig

[user]
    name = Your Name
    email = your@email.com

Now go back to your repo and test it worked:

$ git config user.name
Rusty Robot

$ git config user.email
rustyrobot@robot.com

Amend Author and Email

Best way

If you have committed with the wrong username and email, you can correct it with:

git config user.name "Rusty RoboLocal"
git config user.email "Rusty.RoboLocal@abc.com"

Then make a fresh commit. Then, when you merge with master select Squash Commits. Then all of the incorrect username and emails are lost.

Rewrite history

Get your local code in sync with the remote master $ git push. Then follow this script:

https://help.github.com/en/articles/changing-author-info

Make sure you push the tidied up log to the remote repo: git push --force --tags origin 'refs/heads/*'

Afterwards, to avoid having duplicate git log entries, make sure to do a git pull --rebase.

Keep email private

Stop command line pushes exposing my email

Inside of Github\Settings\email select:

[+] Keep my email addresses private [+] Block command line pushes that expose my email

This can generate error: GH007: Your push would publish a private email address.. To avoid exposing a private email address, use the GitHub supplied public address:

git config --global user.email 2222+rustyrobot@users.noreply.github.com
git config --global user.name ustyrobot
git commit --amend --reset-author               // OPTIONAL. Amend last commit, that caused GH007.
git push

Verify it worked

Go to latest commit in repo. Add .patch at the end. For example:

https://github.com/myuser/example-repo/commit/yyyyy.patch

Change many repos

microplane

Get out of mess

https://code.dblock.org/2015/08/31/getting-out-of-your-first-git-mess.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment