Git tips and tricks - rlsweeney/Sweeney_RA_Manual GitHub Wiki

If you get stuck, check this out.

Basic command line commands

Checkout remote branch

git fetch
git checkout <branch name>

Create new local branch and push to remote

First check the new branch out
git checkout -b <branch>
Edit files, add and commit. Then push with the -u (short for --set-upstream) option:
git push -u origin <branch>
[From Slack]

Discard all local changes made to a branch

git reset --hard HEAD^

Merging changes

From master in to a branch

Say you are working on the branch rich, which you created from master a while ago. In the meantime, someone else made changes to other files in the `master' branch. You'd like to get those changes, but aren't ready to submit a pull request yet.

This is one of those things that is easiest to do from the command line.
Steps:

  1. Make sure your local master branch is up to date.
    git checkout master
    git pull origin master

  2. Go back to your branch and merge to master
    git checkout rich
    git merge master

Note that this change only takes place locally, so need to git push origin to sync to GitHub.

From one branch into another

Sometimes two people are working on the same "issue" in separate branches. For example, at I am working on a branch 'issue52-DiD'. I notice a problem with one part of this code, and ask Sunny to look into it in a parallel branch, created from this issue called 'issue52-DiD-Sunny'. She updates the code and pushes to GH. Now I want to get the changes into the original branch.

  • First checkout Sunny's branch and make sure it's up to date locally.
    • git checkout issue52-DiD_sunny
    • git pull origin
  • Go back to branch you want to update and make sure its up to date with the remote
    • git checkout issue52-DiD
    • git pull origin
  • Now merge the two with `git merge issue-DiD_sunny'
  • If there are conflicts, you'll need to resolve them.
  • After that, you need to remember to
    • git add any changed files
    • commit with a message $ git commit -m "bringing in minor change from sunny"
    • git push origin to update the remote when ready

Resolving merge conflicts

These instructions are pretty good. This Stack post is probably the best description I've seen. Some additional notes in case parts are unclear.

  • There will likely be merge conflicts. For example, I got the message:
git merge issue52-DiD_sunny
Removing code/data_cleaning/appalachia/survival_rate.R
Removing code/data_cleaning/appalachia/diff_in_diff.R
Removing code/data_cleaning/appalachia/comp_pa_download.py
Auto-merging code/analysis/utils_grid_level_DiD.R
CONFLICT (content): Merge conflict in code/analysis/utils_grid_level_DiD.R
Automatic merge failed; fix conflicts and then commit the result.`
  • This is tell me that the file utils_grid_level_DiD.R is different across the two branches, and Git can't figure out how to merge them.
  • Resolving conflicts is not particularly clearly described (it can be complicated). But in most cases, all you need to do is open the file in a text editor in question and look for markers Git made to the file.
  • In this example, when I open up the file I see:
<<<<<<< HEAD
    select(API, Gas, Oil, ProdYear) %>%
    mutate(BOE = Oil + Gas / mcf_to_boe)
  
||||||| merged common ancestors
    select(API, Gas, Oil, ProdYear) %>%
    mutate(BOE = Oil + Gas / mcf_to_boe)

=======
    select(API, Gas, Oil, ProdYear) 

>>>>>>> issue52-DiD_sunny
  • If I just want to keep Sunny's changes, I delete everything except the line select(API, Gas, Oil, ProdYear) .
  • Now if I type git status, there are no conflicts.

Creating a pull request

After you've committed and pushed changes to your branch, we will often eventually want to incorporate these changes into the master branch. [Note: This definitely doesn't have to happen every time you commit. Just after you've got a bunch of changes you're happy with, or if you have some crucial change (say to the data prep code)]

Steps:

  1. Go to github and checkout your branch. Make sure the most recent commit you want to merge into master has been uploaded.

  2. Click on open pull request. Here you want to be pretty descriptive about what exactly is changing / being added.

  3. Github will tell you how different these edits are.

  • Often, you are just adding a file, and GH will say the changes can be merged automatically.
  • Other times, the files will differ with no obvious preferred version, and GH will call these "conflicts".
  • After the pull request is submitted, I will review any conflicts and accept. Then, all of the changes will be integrated into master.

What to do if your commit doesn't push for some reason

This happens to me mainly if I've accidentally tried to push a file that is above GitHub's size limit (100MB). In this case, what you want to do is save the files you do want to keep, reset head hard, and try again with the problematic file removed or ignored.

Steps:

  1. Checkout what commit you want to revert to: git reflog

  2. Reset to the one you want (probably 1) git reset HEAD@{1} --hard

Completely kill repository history

  • delete all commit history
    • this worked perfectly in gitbash

Remove local branches

See this stack post. The following worked for me, in powershell terminal.

git checkout master; git remote update origin --prune; git branch -vv | Select-String -Pattern ": gone]" | % { $_.toString().Trim().Split(" ")[0]} | % {git branch -d $_}

The most important thing is to make sure you're on master first. Also, may want to type git branch -vv and see what's gonna be deleted (everything with the word "gone" in it), just to make sure you don't want anything.

Kill repository history

See this Gist. Drawn from discussion in this Stack thread

Copy (some) files from one repo to another

  • This is useful if you have a private repo with lots of files (maybe some you can't share). But want to share other files, ie when submitting a paper.

See this Gist. Note: You may want to kill the repo histroy after (see above).

Reverting to a previous commit

  • Find the commit you want to revert to on GitHub
    • copy the commit number
  • Locally, check out that commit
    • git checkout <commit#>
  • Save as a new branch
    • git checkout -b reverted_branch_name
  • Push to GitHub, and pull back into master

Note that if you want to simply undo a recent commit, you can use git revert

Example: git revert --no-edit 96678387e4d8f794ac8350882b85c88a4a90dad7, where the number is the commit you want to undo. Can then push to origin master

Git LFS Issues

Someone committed a file without Git LFS installed

In most repos, we'll have Git LFS setup to track all files of a particular type, like .pdf or .png. If someone generates one of these file types locally without LFS installed, this may cause problems later when they are merged into master.

When someone else (likely with LFS installed) goes to checkout master, there will be an error saying something like "Encountered 1 file(s) that should have been pointers". This error is really annoying, because, in some cases, Git will not let you move on without fixing the file (ie you can't stash or checkout another branch without fixing the pointer).

I am not totally sure if this works in every situation, but for the following steps worked:

  1. git lfs uninstall
  2. git reset --hard
  3. git lfs install && git lfs pull

This apparently doesn't always work. More options people have tried are discussed here.

⚠️ **GitHub.com Fallback** ⚠️