Git: Testing Someone Else’s Pull Request on your local dev machine

You do not have to clone every developer’s fork or repository  and then checkout their respective branch in order to test the pull request locally on your dev box 😉

This tutorial will show you how to checkout a pull request on your own computer. This can be very helpful when you want to find bugs and test out new features before they get merged into the main project.

That gist does describe the config changes required in .git/config of the project.

Basically you need to add this line in config

fetch = +refs/pull/*/head:refs/remotes/origin/pr/*

which will allow you to checkout pr locally

Obviously, change the github url to match your project’s URL. It ends up looking like this:

[remote "origin"]
    fetch = +refs/heads/*:refs/remotes/origin/*
    url = git@github.com:joyent/node.git
    fetch = +refs/pull/*/head:refs/remotes/origin/pr/*

Now fetch all the pull requests:

$ git fetch origin
From github.com:joyent/node
 * [new ref]         refs/pull/1000/head -> origin/pr/1000
 * [new ref]         refs/pull/1002/head -> origin/pr/1002
 * [new ref]         refs/pull/1004/head -> origin/pr/1004
 * [new ref]         refs/pull/1009/head -> origin/pr/1009
...

To check out a particular pull request:

$git checkout <pr-id>

$ git checkout pr/999
Branch pr/999 set up to track remote branch pr/999 from origin.
Switched to a new branch 'pr/999'

git : pushing a new project to you github repo

Its a good practice to push your pet project to github repository. Below commands will help you.

First, you need to create a project in github repo and copy its repository url which will act has your remote origin, then you need to init you local repository and link them. so that you can push them once its all set.

git init
git add -A
git commit -m 'Added my project'
git remote add origin git@github.com:premaseem/my-new-project.git
git push -u -f origin master

With this, there are a few things to note. The -f flag stands for force. This will automatically overwrite everything in the remote directory. We’re only using it here to overwrite the README that GitHub automatically initialized. If you skipped that, the -f flag isn’t really necessary.

The -u flag sets the remote origin as the default. This lets you later easily just do git push and git pull without having to specifying an origin since we always want GitHub in this case

 

Git: Pushing to other fork

Objective:

You clone someone else fork and wants to push in your fork

I created a fork (let’s call it myrepo) of another repository (let’s call it orirepo) on GitHub. Later, I cloned orirepo.

git clone https://github.com/original/orirepo.git

I modified about 20 files, then I staged my change and made a commit

git add
git commit

However, when I tried to push

git push

I got this error:

remote: Permission to original/orirepo.git denied to mylogin.
fatal: unable to access 'https://github.com/original/orirepo.git/': The requested URL returned error: 403

 

Solution:

By default, when you clone a repository

  • that resides at https://github.com/original/orirepo.git,
  • whose current branch is called master,

then

  • the local config of the resulting clone lists only one remote called origin, which is associated with the URL of the repository you cloned;
  • the local master branch in your clone is set to track origin/master.

Therefore, if you don’t modify the config of your clone, Git interprets

git push

as

git push origin master:origin/master

In other words, git push attempts to push your local master branch to the master branch that resides on the remote repository (known by your clone as origin). However, you’re not allowed to do that, because you don’t have write access to that remote repository.

You need to

  1. either redefine the origin remote to be associated with your fork, by running
    git remote set-url origin https://github.com/RemiB/myrepo.git
    
  2. or, if you want to preserve the original definition of the origin remote, define a new remote (called myrepo, here) that is associated to your fork:
    git remote add myrepo https://github.com/RemiB/myrepo.git
    

    Then you should be able to push your local master branch to your fork by running

    git push myrepo master
    

    And if you want to tell Git that git push should push to myrepo instead of origin from now on, you should run

    git push -u myrepo master
    

instead.

 

Git: Combining the commits

To squash the last 3 commits into one:

git reset --soft HEAD~3
git commit -m "New message for the combined commit"

Pushing the squashed commit

If the commits have been pushed to the remote:

git push origin +name-of-branch

The plus sign forces the remote branch to accept your rewritten history, otherwise you will end up with divergent branches

If the commits have NOT yet been pushed to the remote:

git push origin name-of-branch

GIT : Generate git Ignore file using online tool -> gitignore.io

Hi Friends,

When we create project using IDE like eclipse, web storm, intellij, a lot of additional files shows up other then required code base. Best practice is to add “.gitignore” file, mention the pattern of (non required) files and commit it. That way git will ignore those file and will not track any changes for those file.

To generate the pattern, you can take help of below online tool, this will give you .gitignore file which can be added and used.

https://www.gitignore.io

GitHub : How to Sync from Forked repoit

Hi Friends,

Fork is not a git concept, its a github concept (github is a git repository host / provider). Fork mean a your personalized copy of base repository in the github account/host. The work flow is

  1. Create a Fork (copy of base repo)
  2. Clone the Forked (your personalized) repo to local box
  3. Commit changes in local and push to origin.
  4. Sync local from Fork upstream
  5. Create Pull request.

githubFork

 

Here is the hands on exercise and explanation on youtube

Usually in git there is only origin and local, in git hub as we have origin and upstream, we can sync by follow below commands.

premaseem$ git remote -v 

premaseem$ git remote add upstream git@remoteURL.github.com

premaseem$ git remote -v 

premaseem$git fetch upstream

premaseem$ git merge upstream/master

premaseem$ git push origin master

 

Git : Making the main branch identical to other branch

Problem : Some how your main branch got polluted (few bad commits) and you want to fix it ?

Solution : You can create a single commit that will make the current branch identical in contents (and implicitly in sync) with another branch.

Explanation : Roll back your branch to the commit you feel it was working fine and create/spun another branch off from there. Now cherry pick can be done for few good commits and new branch can be tested. Once that is fine, follow below commands which will eventually create a big merge commit to make your main (polluted branch) identical to fixed branch. The merge commit will remove all un-necessary files.

$ git reset --hard <another branch>
$ git reset --soft HEAD@{1}
$ git commit

Note : Please make sure that default rebase option is configured to false
command : git config –edit

The first (hard) reset grabs the contents of the other branch into your working directory. The second (soft) reset puts your commit pointer back at the tip of your original branch, but doesn’t change the files in your index at all, thus leaving them as they were in the other branch. You can then commit that state on top of your current branch’s latest commit.

GIT: Using the stash

Best use case to use / apply stash: I have made some change in the pom.xml which are local to my dev box, whenever I take the pull, they gets washed away (over written) by the remote version. Now I have to put entire thing again after taking pull which consumes lot of time.

Solution – apply stash : Instead of doing the commit I create the local changes stash and apply them whenever I need those changes. I can discart them before taking the pull and apply them to get my local changes again.

stash

I will upload a you tube video soon Smile to explain this better.

 

Detailed explanation :

Often, when you’ve been working on part of your project, things are in a messy state and you want to switch branches for a bit to work on something else. The problem is, you don’t want to do a commit of half-done work just so you can get back to this point later. The answer to this issue is the git stashcommand.

Stashing takes the dirty state of your working directory — that is, your modified tracked files and staged changes — and saves it on a stack of unfinished changes that you can reapply at any time.

 
 
Stashing Your Work

To demonstrate, you’ll go into your project and start working on a couple of files and possibly stage one of the changes. If you run git status, you can see your dirty state:

$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#      modified:   index.html
#
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#
#      modified:   lib/simplegit.rb
#

Now you want to switch branches, but you don’t want to commit what you’ve been working on yet; so you’ll
stash the changes. To push a new stash onto your stack, run git stash:

$ git stash
Saved working directory and index state \
  "WIP on master: 049d078 added the index file"
HEAD is now at 049d078 added the index file
(To restore them type "git stash apply")

Your working directory is clean:

$ git status
# On branch master
nothing to commit, working directory clean

At this point, you can easily switch branches and do work elsewhere; your changes are stored on your stack. To see which stashes you’ve stored, you can use git stash list:

$ git stash list
stash@{0}: WIP on master: 049d078 added the index file
stash@{1}: WIP on master: c264051 Revert "added file_size"
stash@{2}: WIP on master: 21d80a5 added number to log

In this case, two stashes were done previously, so you have access to three different stashed works.
You can reapply the one you just stashed by using the command shown in the help output of the original stash command: git stash apply. If you want to apply one of the older stashes, you can specify it by naming it, like this: git stash apply stash@{2}. If you don’t specify a stash, Git assumes the most recent stash and tries to apply it:

$ git stash apply
# On branch master
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#
#      modified:   index.html
#      modified:   lib/simplegit.rb
#

You can see that Git re-modifies the files you uncommitted when you saved the stash.
In this case, you had a clean working directory when you tried to apply the stash, and you tried to apply it on the same branch you saved it from; but having a clean working directory and applying it on the same branch aren’t necessary to successfully apply a stash. You can save a stash on one branch, switch to another branch later, and try to reapply the changes. You can also have modified and uncommitted files in your working directory when you apply a stash — Git gives you merge conflicts if anything no longer applies cleanly.

The changes to your files were reapplied, but the file you staged before wasn’t restaged. To do that, you must run the git stash apply command with a --index option to tell the command to try to reapply the staged changes. If you had run that instead, you’d have gotten back to your original position:

$ git stash apply --index
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#      modified:   index.html
#
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#
#      modified:   lib/simplegit.rb
#

The apply option only tries to apply the stashed work — you continue to have it on your stack.
To remove it, you can run git stash drop with the name of the stash to remove:

$ git stash list
stash@{0}: WIP on master: 049d078 added the index file
stash@{1}: WIP on master: c264051 Revert "added file_size"
stash@{2}: WIP on master: 21d80a5 added number to log
$ git stash drop stash@{0}
Dropped stash@{0} (364e91f3f268f0900bc3ee613f9f733e82aaed43)