Skip to content

Instantly share code, notes, and snippets.

@fluteds
Last active April 10, 2022 16:23
Show Gist options
  • Save fluteds/61245137630f2dcb93eaf0eef96947de to your computer and use it in GitHub Desktop.
Save fluteds/61245137630f2dcb93eaf0eef96947de to your computer and use it in GitHub Desktop.
A pack of Gists that contain a range of useful Git commands for the cmd line.

Useful Git Commands for the cmd line

This Gist 'pack' contains some of the most useful commands that I use on a day to day bases or need to use when I've pushed a mistake! These are also useful if you aren't using GitHub desktop.

Contents

  • Change Author and Email on Commits
  • Revert Pull Requests & Rebasing/Squashing Their Commits
  • Updating Forked Repos
  • Rebasing Pushed Commits
  • Creating Private Forks
  • Changing the very first Commit Message

Change Author and Email used on Commits

To change the author and email only for the last commit:

git commit --amend --author 'Author Name <author.name@mail.com>' --no-edit

Suppose you only want to change the author and email for the last N commits:

git rebase -i HEAD~4 -x "git commit --amend --author 'Author Name <author.name@mail.com>' --no-edit"

Notes

The --no-edit flag makes sure the git commit --amend doesn't ask an extra confirmation when you use git rebase -i, you can manually select the commits where to change the author, the file you edit will look like this:

pick 897fe9e simplify code a little
pick abb60f9 add new feature
exec git commit --amend --author 'Author Name <author.name@mail.com>' --no-edit
pick dc18f70 bugfix

To change your username and email in git use the following commands

git config --global user.name "John Doe"
git config --global user.email "author.name@mail.com"

To check you've set the right email and author name run the command git config --list the command will list all your config settings. In the list you should also find user.name and user.email. If you can't see it press Enter to expand the list.

Change the First Commit Message

Do git rebase -i --root

(point to root instead of pointing to a specific commit)

This way, the first commit is also included and you can just reword it like any other commit.

The --root option was introduced in Git v1.7.12 (2012). Before then the only option was to use filter-branch or --amend, which is typically harder to do

Private Forks

Input the following into your terminal

Note:

  • exampleuser : GitHub username of the public repo you want to fork
  • yourname : Your GitHub username
git clone --bare https://github.com/exampleuser/public-repo.git
cd public-repo.git
git push --mirror https://github.com/yourname/private-repo.git
cd ..
rm -rf public-repo.git

Clone and cd to the private repo so you can work on it

git clone https://github.com/yourname/private-repo.git
cd private-repo
make some changes
git commit
git push origin master

To pull new commits from the public repo

cd private-repo
git remote add public https://github.com/exampleuser/public-repo.git
git pull public master # Creates a merge commit
git push origin master

Awesome, your private repo now has the latest code from the public repo plus your changes.

Finally, create a pull request from private repo -> public repo

The only way to create a pull request is to have push access to the public repo. This is because you need to push to a branch there (here’s why).

git clone https://github.com/exampleuser/public-repo.git
cd public-repo
git remote add private_repo_yourname https://github.com/yourname/private-repo.git
git checkout -b pull_request_yourname
git pull private_repo_yourname master
git push origin pull_request_yourname

Now simply create a pull request via the Github UI for public-repo, as described here. Once project owners review your pull request, they can merge it. Of course the whole process can be repeated, just leave out the steps where you add remotes. Info taken from Stack Overflow.

Rebasing Commits

Rebasing is useful if you want to change a commit message, squash commits together or merge with other commits. A good rule of thumb is not to rebase when others are working on the same project as you as it can cause merge conflicts. I use this primarily to squash my smaller commits into larger commits.

Step 1
Run the following command:

git rebase -i HEAD~X

  • X is the number of commits you want to change.
  • -i means interactive. You can also use -interactive instead of -i.

Step 2
After running you will see the interactive git page in your terminal looking something like this:

pick fda59df Delete CNAME
pick x536897 Better README
pick c01a668 Change the commit message but push the same commit.

# Rebase 49687a0..d426a8a onto 49687a0

# # Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell

# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#

Step 3
Editing your commits:

Your terminal should look like this after if you want to only reword commits.

pick fda59df Delete CNAME
reword x536897 Better README
reword c01a668 Change the commit message but push the same commit.

You don't need to replace each commit as unchanged commits will be ignored.

To save your edits press :wq (save and quit), your editor will open once more to ask for a new commit message for the edited commit if you selected anything other than pick.

Note: Putting a # infront of the commit message if you are squashing removes it from git. This only works for squashing as you cannot commit an empty commit.

Step 4
Push the changes to your repo. By using the following

git push --force

Use --force or --f if you've already pushed the commits.

You only need to force a push once until you need to rebase after pushing multiple commits remotely.

If you get an error message like this:

fatal: It seems that there is already a rebase-merge directory, and
I wonder if you are in the middle of another rebase.  If that is the
case, please try
        git rebase (--continue | --abort | --skip)
If that is not the case, please
        rm -fr ".git/rebase-merge"
and run me again.  I am stopping in case you still have something
valuable there.

You can cancel rebase any time by running:

git rebase --abort

Revert Pull Request Commits & Rebasing

So you find yourself accidentally rebasing your fork that's been added/opened as a pull request.
You see that you've now added over 1000 new commits to your branch.
What do you do?

Copy the following into your terminal without the <>

git checkout <BRANCH NAME>

git reset --hard <COMMIT HASH YOU WANT TO REVERT TO>

  • You can find your commit hashes at github.com/USER/REPONAME/commits/BRANCHNAME
  • Or use this git command git log --reflog or git reflog The latter opens a condensed version.
  • Confirm that you're on the right branch and commit with the following. (Opens a new window)

gitk

  • Once you're ready, force push the branch. Using the following. Do not use standard pushing. There will be errors.

git push -f origin <BRANCH NAME>

What if it doesn't work?
Don't panic. Try again with the previous commit hash.

Updating a Branch Name Change

Let's say you updated your branch name remotely, how would you change the local branch to reflect the changes?

Changing the branch from master to main.

git branch -m master main
git fetch origin
git branch -u origin/main main
git remote set-head origin -a

Keeping your forks up to date

It's good practice to keep your forked branch/repo up to date before you submit a pull request.

To keep your forks up to date use the following (without the <>)

Add the remote, call it "upstream":

git remote add upstream https://github.com/user/reponame.git

Fetch all the branches of that remote into remote-tracking branches

git fetch upstream

Make sure that you're on the right branch with:

git checkout <branchname>

Rewrite your master branch so that any commits of yours that aren't already in upstream/<branchname> are replayed on top of that other branch:

git rebase upstream/<branchname>

Notes

If you don't want to rewrite the history of your master branch, (for example because other people may have cloned it) then you should replace the last command with git merge upstream/<branchname>. However, for making further pull requests that are as clean as possible, it's probably better to rebase.

If you've rebased your branch onto upstream/<branchname> you may need to force the push in order to push it to your own forked repository on GitHub. You'd do that with:

git push -f origin <branchname>

You only need to use the -f the first time after you've rebased.

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