Github: Difference between revisions
Line 961: | Line 961: | ||
git difftools <revision_1> <revision_2> # ask to go each file separately | git difftools <revision_1> <revision_2> # ask to go each file separately | ||
git diff --name-only SHA1 SHA2 # show only file names | |||
git diff --name-only HEAD~10 HEAD~5 # between the tenth latest commit and the fifth latest | |||
</syntaxhighlight> | </syntaxhighlight> | ||
Revision as of 16:45, 7 May 2016
Git
- Github & Git Foundations Training from youtube.
- git/github guide a minimal tutorial from Karl Broman
- Some examples of projects hosted in github: RHadloop, shiny, Qt.
- https://help.github.com/articles/fork-a-repo
- http://www.atlassian.com/git/tutorial/undoing-changes
- Git reference (5 pages of summary) and Pro Git book
- Distributed Version Control with Git (nice tutorial including Github, BitBucket. )
- Cheat sheet:
- github.com (2 pages)
- byte.kde.org (font too small)
- git-tower.com (1 page as an image)
- atlassian.com (immediate download)
- jan-krueger.net (cool too)
- patrickzahnd.ch (visual cheat sheet)
- https://www.kernel.org/pub/software/scm/git/docs/everyday.html
- http://haacked.com/archive/2012/05/21/introducing-github-for-windows.aspx
- Delete a repository
- git commit will ask username/password if we have not logged in. The identity will be saved under ~/.gitconfig.
- Under Windows, we need to provide username/password when we install Git program provided by Github. Even that, when we use powershell program to commit codes to github, the username was not yet shown on the github website. We need to run
git config --global user.name "Your Name Here" git config --global user.email [email protected]
OR to have a project specific git identity (this will write your identify in .git/config file)
git config user.name "Your Name Here" git config user.email [email protected]
- When I commit (git commit) a directory containing resource file, it shows warning: LF will be replaced by CRLF in xxxx.qrc.
- Password cache
- github tutorial (for statistician)
- git add -A
git config --global credential.helper cache
My example of working on a new repository called 'network'.
- Follow https://help.github.com/articles/create-a-repo to create a new repository. For convenience, I also check the button to create README file.
- Click 'GitHub' icon on Windows Desktop. Look at the LHS and click on the word 'github'. Click 'clone' button (This can be accomplished by git clone https://github.com/arraytools/network.git). The new repository will appear under C:\Users\USERNAME\Documents\Github\ directory. Now Click 'Git Shell' icon on the Windows Desktop and go to C:\Users\USERNAME\Documents\Github\network directory where 'network' is my repository's name.
git config --global color.ui auto # colorize the output of git git init git add client.c git add server.c git add server2.c git commit -m 'first commit' git status # On branch master # Your branch is ahead of 'origin/master' by 1 commit. # git remote add origin https://github.com/arraytools/network.git # git push <remote> <branch> git push origin master # If we modify any file, we need to go through git add, git commit and git push 3 commands. # get commit_id git log # get a specific version git checkout commit_id # after an examination, we want to get the latest version git pull origin master # If you do not want to merge the upstream changes wit your local repository, run git fetch to # fetch the changes and then git merge to merge the changes. # git pull is just a combination of fetch and merge. # To rename a file git mv originafile newfile git commit -m "rename orginalfile" git push # To remove a file rm myfile git add . -A git commit -m "remove a file" git push # Revert to origin's master branch's version of file # http://stackoverflow.com/questions/1817766/revert-to-origins-master-branchs-version-of-file # 1. Assuming you did not commit the file, or add it to the index, then: git checkout filename # 2. Assuming you added it to the index, but did not commit it, then: git reset HEAD filename git checkout filename
Check the https://github.com/arraytools/network. The commit goes to the repository!
In summary: add and commit are local operations, push, pull and fetch are operations that interact with a remote.
If we want to checkout a specific commit on a new computer, we can use (here we use Qt repository as an example)
git clone https://xxxxxx/xxxxxx/Qt.git cd Qt git log --oneline git checkout SHA1 (7 digits obtained from git log --oneline commandis enough)
After that we can run
# move HEAD to origin git checkout origin/master # Visualize using text mode git log --graph --oneline --date-order --decorate --color --all
Using GUI client: gitg
sudo apt-get install gitg
To switch among different branch (eg. github project page is located in gh-pages branch of a repository),
git checkout gh-pages git checkout master
Tip: To avoid being asking the username each time when you use 'git push', you can modify the .git/config file of your local repository. This file contains a section called 'remote' with an entry called 'url'. The 'url' entry should contains the https link of repository you're talking about. When you prefix the host url with your username, git shouldn't be asking for your username anymore. Here's an example: url = https://[email protected]
GUI version of Git software
Windows
Go to http://git-scm.com/download. The Windows version contain 'Git Bash', 'Git CMD', and 'Git GUI'. The 'Git GUI' software (based on Tcl/Tk) works pretty cool. It can 'Rescan' the project, compare the changed filefs and visualize the master's history too. The Git comes with 2 built-in tools: Git-gui is for committing and gitk is for browsing. Screenshots of gitk can be found below.
Note that Git-gui cannot run git pull directly. We have to go through two steps: Fetch and merge. See this message.
Linux
Use gitk or gitg. For example,
gitk --all
Set up a new local/remote repository
mkdir /path/to/your/project cd /path/to/your/project git init git remote add origin https://[email protected]/arraytools/REPOSITORYNAME.git # git remote add origin ssh://[email protected]/home/git/REPOSITORYNAME.git # git clone ssh://[email protected]/home/git/REPOSITORYNAME.git git config --global user.name "YOUR NAME" git config --global user.email "YOUR EMAIL ADDRESS" git config --list # confirm echo "arraytools" >> contributors.txt git add contributors.txt git commit -m 'Initial commit with contributors' git push -u origin master
Already has a git repository on my computer
cd /path/to/my/repo git remote add origin https://[email protected]/arraytools/REPOSITORYNAME.git git push -u origin --all # pushes up the repo and its refs for the first time git push -u origin --tags # pushes up any tags
'master' and 'origin'
- master is a branch name. You can use git branch to find out all branches. The current branch has a asterisk in the command line output and has a bold font in the gitk program.
- origin is a repository name. You are free to create a new one and delete origin especially in situation that you are working with multiple remotes.
https://lostechies.com/joshuaflanagan/2010/09/03/use-gitk-to-understand-git/
“git push -u origin master” vs “git push origin master”
The key is "argument-less git-pull". When you do a git pull from a branch, without specifying a source remote or branch, git looks at the branch.<name>.merge setting to know where to pull from. git push -u sets this information for the upstreaming branch you're pushing.
Setup editor
See man git-commit.
git config --global core.editor "nano" # OR export GIT_EDITOR=nano # OR for other programs to use too export EDITOR=nano
.gitignore file
git help gitignore # or man gitignore
A leading slash indicates that the ignore entry is only to be valid with respect to the directory in which the .gitignore file resides. Specifying *.o would ignore all .o files in this directory and all subdirs, while /*.o would just ignore them in that dir, while again, /foo/*.o would only ignore them in /foo/*.o.
Undo
https://git-scm.com/book/en/v2/Git-Basics-Undoing-Things
git commit --amend
If you commit too early and possibly forget to add some files, or you mess up your commit message.
Assumption: Commit has not been pushed online
$ git commit -m 'initial commit' $ git add forgotten_file $ git commit --amend # In your text editor, edit the commit message and save the commit.
You end up with a single commit.
If the commit has been pushed online, see https://help.github.com/articles/changing-a-commit-message/.
Unmodifying a Modified File (not staged)
$ git checkout -- Filename $ git checkout -- . # All unstaged files $ git stash save --keep-index # http://stackoverflow.com/questions/52704/how-do-you-discard-unstaged-changes-in-git/52713#52713
Unstaging a Staged File
$ git reset HEAD Filename
Undo git pull or merge
http://stackoverflow.com/questions/101752/i-ran-into-a-merge-conflict-how-can-i-abort-the-merge
$ git reset --hard HEAD
Undo git commit
http://stackoverflow.com/questions/927358/how-do-you-undo-the-last-commit
$ git reset --soft HEAD~
git fetch vs git push
branch - not the same as in CVS
https://lostechies.com/joshuaflanagan/2010/09/03/use-gitk-to-understand-git/
Gitk shows all of the commits as a single straight line. In git, a branch is a label for a commit. The label moves to new commits as they are created. When you create a git branch, you are not changing anything in the structure of the repository or the source tree. You are just creating a new label.
Below are some info borrowed from Pro Git.
master branch
When you clone a repository, it generally automatically creates a master branch that tracks origin/master.
To set up other tracking branches, see Remote branches.
git checkout --track origin/serverfix
Create a new branch
git branch testing git log --oneline --decorate
Pay attention to the keywords 'HEAD', 'master' and 'testing' in this case.
Switch branches
git checkout testing nano test.rb git commit -a -m 'made a change' git checkout master nano test.rb git commit -a -m 'made other changes' git log --oneline --decorate --graph --all
Basic merging and conflicts
git checkout -b iss53 # shorthand for # git branch iss53 # git checkout iss53 nano index.html git commit -a -m 'added a new footer [issue 53]' git checkout master git checkout -b hotfix nano index.html git commit -a -m 'fixed the broken email address' git checkout master git merge hotfix git branch -d hotfix git checkout iss53 nano index.html git commit -a -m 'finished the new footer [issue 53]'
Basic Merging:
git checkout master git merge iss53
Basic merge conflicts:
git merge iss53 git status # Look at the standard conflict-resolution markers to the top of files git mergetool git status
Branch management
git branch git branch -v # see the last commit on each branch git branch -vv # see the last commit and what remote branch a local branch is tracking? git branch --merged # Filter the list to branches that you have merged into the branch you're currently on git branch --no-merged # See the branches that contain work you haven't yet merged in git branch -d testing
Branch workflows
NA
Inspect a Remote
https://git-scm.com/book/ch2-5.html
brb@brb-P45T-A:~/github/SIK$ git remote origin brb@brb-P45T-A:~/github/SIK$ git remote -v origin https://[email protected]/arraytools/SIK.git (fetch) origin https://[email protected]/arraytools/SIK.git (push) brb@brb-P45T-A:~/github/SIK$ git remote add pb https://github.com/paulboone/ticgit brb@brb-P45T-A:~/github/SIK$ git remote -v origin https://[email protected]/arraytools/SIK.git (fetch) origin https://[email protected]/arraytools/SIK.git (push) pb https://github.com/paulboone/ticgit (fetch) pb https://github.com/paulboone/ticgit (push) brb@brb-P45T-A:~/github/SIK$ git fetch [remote-name] brb@brb-P45T-A:~/github/SIK$ git fetch pb warning: no common commits remote: Counting objects: 634, done. remote: Total 634 (delta 0), reused 0 (delta 0), pack-reused 634 Receiving objects: 100% (634/634), 109.18 KiB | 0 bytes/s, done. Resolving deltas: 100% (231/231), done. From https://github.com/paulboone/ticgit * [new branch] master -> pb/master * [new branch] ticgit -> pb/ticgit brb@brb-P45T-A:~/github/SIK$ git remote show origin * remote origin Fetch URL: https://[email protected]/arraytools/SIK.git Push URL: https://[email protected]/arraytools/SIK.git HEAD branch: master Remote branch: master tracked Local branch configured for 'git pull': master merges with remote master Local ref configured for 'git push': master pushes to master (up to date) brb@brb-P45T-A:~/github/SIK$ git remote show pb * remote pb Fetch URL: https://github.com/paulboone/ticgit Push URL: https://github.com/paulboone/ticgit HEAD branch: master Remote branches: master tracked ticgit tracked Local ref configured for 'git push': master pushes to master (local out of date) brb@brb-P45T-A:~/github/SIK$ git remote rm pb brb@brb-P45T-A:~/github/SIK$ git remote -v origin https://[email protected]/arraytools/SIK.git (fetch) origin https://[email protected]/arraytools/SIK.git (push)
So if we use gitg program, we will see there are following branches
- origin/master
- pb/master
- pb/ticgit
brb@brb-P45T-A:~/github/SIK$ git remote rm pb brb@brb-P45T-A:~/github/SIK$ git remote -v origin https://[email protected]/arraytools/SIK.git (fetch) origin https://[email protected]/arraytools/SIK.git (push)
Remote branches
Remote references are references (pointers) in your remote repositories, including branches, tags, and so on.
Pushing:
git ls-remote (remoteName) git remote show (remoteName) git push origin serverfix # serverfix is a branch name
Do not type your password every time: you can set up a credential cache. The simplest is to keep it in memory for a few minutes, which you can set up by running
git config --global credential.helper cache
One collaborator fetches from the server. They will get a reference to where the server's version of serverfix is under the remote branch origin/serverfix:
git fetch origin git checkout -b serverfix origin/serverfix
Tracking Branches:
Note: Tracking means that a local branch has its upstream set to a remote branch. Tracking can occur when we use clone or checkout commands.
FAQ: git checkout --track origin/branch VS git checkout -b branch origin/branch. Basically '-b' allows a different branch name.
git checkout --track origin/serverfix git checkout -b sf origin/serverfix git branch -u origin/serverfix
Pulling:
git pull # Equivalent to two actions git fetch origin # get the contents of the remote repository (origin), but keep them under origin/branch branch # requires the password git merge origin/master # merge the master branch of the remote repository (origin) with your current branch # no password required
Deleting Remote Branches:
git push origin --delete serverfix
Rebasing - integrate changes from 2 branches
In Git, there are two main ways to integrate changes from one branch into another: the merge and the rebase.
Detached head/HEAD detached from xxxxxxx
I got the above message when I run
- Gitgui -> checkout -> Revision Expression (some previous version)
- Gitgui -> checkout -> Revision Expression (the latest version)
- Git Bash -> git status
At this time, I cannot continue as usual to make changes to files and do commits.
The solution is run
git checkout master
See this post from stackoverflow.com.
git merge
See an example of merging a temporary branch with the master branch in the local repository.
This is another example. It teaches how to make sure my master branch is in synch with the central repository on github (which I refer to using the remote “origin”) before I merge my changes into master.
Merge conflict 1
Your branch is ahead of 'origin/master'
Merge conflict 2
Your branch and 'origin/master' have diverged
Manual merge and auto merge
If a file looks like
line1 line2 line3 line4
(Manual merge) Then suppose machine 1 modifies line3 and push to the remote. Machine 2 at the same time modifies line4 and tries to run git fetch & git merge from the remote. Then machine 2 will need to do merge manually (git mergetool) because line 3 and line 4 are next to each other. After fixing the conflict by git mergetool, we can run git commit & git push. A temporary file called FILENAME.orig will be created.
(Auto merge) On the other hand, if machine modifies line 2 and push to the remote. Machine 2 at the same time modifies line 4 and tries to run git fetch & git merge to the remote. Then auto merge will be done because line 2 and line 4 are separated. Machine 2 only needs to provide the commit message.
Whether there are conflicts or not, the practice is to run git fetch, git diff master origin/master, git merge origin/master (or unfavorably run git pull), and git push (Note that after git pull, we will be directed to the nano editor to enter a commit message; however, after git fetch, we will NOT be directed to nano editor). If we directly run git push (even on non-conflict file), we will be welcome with the message
brb@brb-P45T-A:~/github/toy$ git add . brb@brb-P45T-A:~/github/toy$ git commit -m "add a line from p45t-a" [master 3b69283] add a line from p45t-a 1 file changed, 1 insertion(+) brb@brb-P45T-A:~/github/toy$ git push To https://[email protected]/arraytools/toy.git ! [rejected] master -> master (fetch first) error: failed to push some refs to 'https://[email protected]/arraytools/toy.git' hint: Updates were rejected because the remote contains work that you do hint: not have locally. This is usually caused by another repository pushing hint: to the same ref. You may want to first integrate the remote changes hint: (e.g., 'git pull ...') before pushing again. hint: See the 'Note about fast-forwards' in 'git push --help' for details. brb@brb-P45T-A:~/github/toy$ git status On branch master Your branch is ahead of 'origin/master' by 1 commit. (use "git push" to publish your local commits) nothing to commit, working directory clean
This goes back to the same problem mentioned above in Merge conflict 2.
Summary:
- When we run git pull, if there is a conflict and that conflict can be resolved automatically, we will be directed to the text editor to enter the commit message.
- When we run git fetch, we will NOT be directed to the text editor regardless of conflicts. We need to enter the commit message when we run git merge origin/master. Also gitk will NOT show origin/master on graph BEFORE we run git merge origin/master for some reason.
Take home message:
- Before going to run git merge, run git checkout master first.
- Instead of running git pull, we'd better run git fetch & git merge origin/master if the bash code was run in a background.
See also http://www.gitguys.com/topics/merging-branches-without-a-conflict/
git rebase
https://lostechies.com/joshuaflanagan/2010/09/03/use-gitk-to-understand-git-merge-and-rebase/
The simple git merge method can make the history very complicated; see and the following cons.
- Branching paths in the history can be unnecessarily complicated
- The extra merge commit.
- Your branch is now no longer a private, local concern. Everyone now knows that you worked in an issue123 branch. Why should they care?
git rebase can be used to avoid these issues.
The good approach (as in that example) is
git checkout issue123 git rebase master git checkout master git merge issue123 git branch -d issue123 git push origin master
.ref directory
brb@brb-P45T-A:~/github/toy$ ls -l .git total 60 drwxrwxr-x 2 brb brb 4096 May 6 11:55 branches -rw-rw-r-- 1 brb brb 13 May 7 16:12 COMMIT_EDITMSG -rw-rw-r-- 1 brb brb 273 May 6 11:55 config -rw-rw-r-- 1 brb brb 73 May 6 11:55 description -rw-rw-r-- 1 brb brb 95 May 7 16:32 FETCH_HEAD -rw-rw-r-- 1 brb brb 3676 May 6 21:44 gitk.cache -rw-rw-r-- 1 brb brb 23 May 6 11:55 HEAD drwxrwxr-x 2 brb brb 4096 May 6 11:55 hooks -rw-rw-r-- 1 brb brb 176 May 7 16:32 index drwxrwxr-x 2 brb brb 4096 May 6 11:55 info drwxrwxr-x 3 brb brb 4096 May 6 11:55 logs drwxrwxr-x 85 brb brb 4096 May 7 16:12 objects -rw-rw-r-- 1 brb brb 41 May 7 16:32 ORIG_HEAD -rw-rw-r-- 1 brb brb 107 May 6 11:55 packed-refs drwxrwxr-x 5 brb brb 4096 May 6 11:55 refs brb@brb-P45T-A:~/github/toy$ tree .git/refs .git/refs ├── heads │ └── master ├── remotes │ └── origin │ ├── HEAD │ └── master └── tags brb@brb-P45T-A:~/github/toy$ ls .git/objects/ 03 0f 28 39 47 52 5f 65 6e 8c ad b7 ce da e5 f2 ff 07 12 29 3b 49 53 60 67 6f 9a b1 bb cf dc e9 f5 info 08 13 2c 3d 4d 56 61 68 84 9e b2 bc d0 de ea f6 pack 09 16 36 43 4e 57 63 6c 89 a9 b3 c0 d5 e1 ef fc 0c 1b 37 45 51 58 64 6d 8a aa b5 c8 d6 e2 f1 fe brb@brb-P45T-A:~/github/toy$ ls .git/branches/ brb@brb-P45T-A:~/github/toy$ ls .git/info/ exclude brb@brb-P45T-A:~/github/toy$ ls .git/logs HEAD refs
Tagging
https://git-scm.com/book/en/v2/Git-Basics-Tagging
$ git tag # Create annotated tags $ git tag -a v1.4 -m "my version 1.4" $ git tag v1.4 $ git show v1.4 # Tagging Later $ git log --pretty=online $ git tag -a v1.2 9fceb02
By default, the git push command does not transfer tags to remote servers. You have to explicitly push tags to a shared server after you have created them.
$ git push origin v1.5 $ git push origin --tags # push up all tags at once
Rename a repository
- Go to github.com, open the project and click Settings button on the left-bottom corner. Change the repository name on top.
- On local machine, rename the directory. Go to the directory. Issue
git remote -v
to get the ULR for the current working copy. Suppose the url is [email protected]:someuser/someproject.git. Now issue the following command to change to the new repository
git remote set-url origin [email protected]:someuser/newprojectname.git
Create a git server (command line only)
Follow the instruction on git-scm.com. It works.
I tested it by
- create a git account (called 'git') on my host machine.
- sudo to create a directory called /opt/git/project.git. Change the owner to 'git'. Cd to the directory and initialize it.
- Create two virtual machines (vb1 and vb2). Creating a username 'david' on vb1 and a user name 'joseph' on vb2.
- Create ssh key for both 'david' and 'joseph'. Ssh to copy their ssh keys to git account.
- Create a new directory on vb1 and initialize it. Run git commands to commit & push files to the server (no password is needed). Note that when we use 'git commit', git will ask to create a username and email by first running 'git config' command.
- Switch to vb2 and run git clone (no password is needed). The user can modify the code and commit & push files to the server.
- Run 'git log' to check if each user's name/email are shown on the log.
Some important points:
- There is no daemon to be installed. We only need to install the 'git' program on the server.
- When a client uses the 'git' command to communicate with the server, it is actually using the 'ssh' to access the server.
- We still need to create a user for this git server. Then the developers' rsa keys can be saved to the git user's <.ssh/authorized_keys> file.
- The instruction asks to chmod 700 (rwx------) for the .ssh directory and chmod 600 (-rw------) for the <.ssh/authorized_keys> file.
- If the git repository directory is not saved under the user's directory, we need to make sure the owner of the directory is the git user.
Another way to create a git server: gitolite (favored by Ubuntu)
- https://help.ubuntu.com/lts/serverguide/git.html#git-installing-gitolite
- https://www.digitalocean.com/community/tutorials/how-to-use-gitolite-to-control-access-to-a-git-server-on-an-ubuntu-12-04-vps
This approach involves the following steps
- Installing a gitolite server
- Gitolite configuration
- Managing gitolite users and repositories
- Using your server
Not sure about any advantages of this approach?
Create a git server (github like w/ web interface)
If we like to create a github-like web interface, check out GitLab.
Below is my note
- https://about.gitlab.com/downloads/ contains steps of setting up Gitlab.
- By default, the domain name you have entered in setting up gitlab will be the URL you will use to access gitlab.
- Use the recommended method to install gitlab. Nginx will be installed as an http server.
- The root username and password is root and 5iveL!fe.
- When new users are created by root, we can put a faked email there (eg [email protected]). The root account can create password for the user.
- User's password is used to access GitLab web interface only. It is not used for pushing commits.
- After a new user is created, log out of root account and log in using the new user account. Click 'Profile setting' icon and then select SSH > Add SSH key. Copy your <id_rsa.pub> content there. To create your ssh key, use the command line "ssh-keygen -t rsa". The <id_rsa.pub> is located under ~/.ssh directory. The title should be auto populated. If ssh key is added successfully to gitLab, we won't get a pop-up asking password when we run 'git push'.
- A new project should be created by users (not root). If I create a project by root, I keep getting a permission issue when I run 'git push'.
- The username will affect path to all personal projects; e.g. [email protected]:newuser/test2.git.
How to Install Gitlab with PostgreSQL and Nginx on Ubuntu 15.04 from howtoforge.com.
Graphical tool
Command line approach
$ git log --oneline --decorate --graph --all * 63af56a (HEAD, origin/master, origin/HEAD, mybranch, master) merged in vm |\ | * 67d5aad modify linux by mint 4th line * | 5f3267a modify linuxfile by vm 4th line |/ * adf545a new modify linux by mint * f22932b resolve the conflict in vm |\ | * b2f1ee4 modify linuxfile by mint * | fe50c32 modify linuxfile by vm |/ * a95258a add linuxfile * b1a71a8 commit from linux * d02b570 2nd commit * 3700939 first commit
gitk and git-gui
- http://lostechies.com/joshuaflanagan/2010/09/03/use-gitk-to-understand-git/
- http://git-scm.com/download/gui/linux
sudo apt-get update; sudo apt-get install gitk git clone [email protected]:joshuaflanagan/gitk-demo.git cd gitk-demo gitk --all # show all refs (branches, tags, etc.)
What I find is gitk will take a little time to rebuild something because after I run git pull, it will show several files (if not all) are uncommitted.
Gitk worked with git-gui program (sudo apt-get install git-gui) which is a gui program to run rescan/stage/commit/push. You launch git-gui from gitk-File-Start git-gui.
It looks these 2 gui tools are sufficient enough.
Others
- QGit - QGit is a git GUI viewer built on Qt/C++.
- git-cola ???
- gitg
- Giggle - Similar to gitk
- SmartGit - Support push, pull, fetch
Git Tips
git log message is too long
Normally when we use 'git log' command, long log messages get truncated.
Use the following to view the complete log messages instead of truncated log messages.
git log | less
Common standard is 78 characters. See this and this posts.
git push error (file is created by Windows but edited by Linux), Your branch is ahead of 'origin/master'
Suppose there are two users A & B (that me). A modified something, commits and pushes to the remote. I modified the same file, commit (so far OK since the actions are all local) and try to push to the remote.
If I forget to run git pull and after running git push, we will get something like if there is a conflict.
C:\Users\XXX\Documents\GitHub\toy [master]> git push To https://github.com/arraytools/toy.git ! [rejected] master -> master (non-fast-forward) error: failed to push some refs to 'https://github.com/arraytools/toy.git' hint: Updates were rejected because the tip of your current branch is behind hint: its remote counterpart. Merge the remote changes (e.g. 'git pull') hint: before pushing again. hint: See the 'Note about fast-forwards' in 'git push --help' for details. C:\Users\XXX\Documents\GitHub\toy [master]> git status # On branch master # Your branch is ahead of 'origin/master' by 1 commit. # nothing to commit, working directory clean
Follow the suggestion from this post to use git pull for git to do merge. It does not work in this case.
C:\Users\XXX\Documents\GitHub\toy [master]> git pull origin master remote: Counting objects: 3, done. remote: Compressing objects: 100% (2/2), done. remote: Total 3 (delta 0), reused 3 (delta 0), pack-reused 0 Unpacking objects: 100% (3/3), done. From https://github.com/arraytools/toy * branch master -> FETCH_HEAD warning: Cannot merge binary files: README.md (HEAD vs. b1a71a846e17416a3b248dfd5829547f74fd812c) Auto-merging README.md CONFLICT (content): Merge conflict in README.md Automatic merge failed; fix conflicts and then commit the result. C:\Users\XXX\Documents\GitHub\toy [master +0 ~0 -0 !1 | +0 ~0 -0 !1]> dir Directory: C:\Users\XXX\Documents\GitHub\toy Mode LastWriteTime Length Name ---- ------------- ------ ---- -a--- 5/3/2016 4:33 PM 102 README.md C:\Users\XXX\Documents\GitHub\toy [master +0 ~0 -0 !1 | +0 ~0 -0 !1]> git status # On branch master # Your branch is ahead of 'origin/master' by 1 commit. # # You have unmerged paths. # (fix conflicts and run "git commit") # # Unmerged paths: # (use "git add <file>..." to mark resolution) # # both modified: README.md # no changes added to commit (use "git add" and/or "git commit -a")
The README.md file was created on Windows/DOS. For some reason, it is recognized as binary files by git. If I look at the file on Linux, it shows the file is ASCII text but with CR line terminators.
$ file README.md README.md: ASCII text, with CR line terminators.
Since we already run git pull, it won't work to run git reset --soft HEAD~ to undo a commit. Two solutions
- git fetch origin; git reset --hard origin/master to throw away my local modified file OR
- git reset --hard HEAD to undo git pull; see this post. After that, we can run git reset --soft HEAD~ to undo a commit. See below.
C:\Users\XXX\Documents\GitHub\toy [master +0 ~0 -0 !1 | +0 ~0 -0 !1]> git reset --hard HEAD HEAD is now at cd2d105 commit from Windows C:\Users\XXX\Documents\GitHub\toy [master]> git status # On branch master # Your branch is ahead of 'origin/master' by 1 commit. # nothing to commit, working directory clean C:\Users\XXX\Documents\GitHub\toy [master]> git reset --soft HEAD~ C:\Users\XXX\Documents\GitHub\toy [master +0 ~1 -0]> git status # On branch master # Changes to be committed: # (use "git reset HEAD <file>..." to unstage) # # modified: README.md C:\Users\XXX\Documents\GitHub\toy [master +0 ~1 -0]> cat README.md # toy second commit 3rd commit (Windows MACHINE) C:\Users\XXX\Documents\GitHub\toy [master +0 ~1 -0]> git reset HEAD README.md Unstaged changes after reset: M README.md C:\Users\XXX\Documents\GitHub\toy [master +0 ~1 -0]> git status # On branch master # Changes not staged for commit: # (use "git add <file>..." to update what will be committed) # (use "git checkout -- <file>..." to discard changes in working directory) # # modified: README.md # no changes added to commit (use "git add" and/or "git commit -a") C:\Users\XXX\Documents\GitHub\toy [master +0 ~1 -0]> git checkout -- README.md C:\Users\XXX\Documents\GitHub\toy [master]> cat README.md # toy second commit C:\Users\XXX\Documents\GitHub\toy [master]> git status # On branch master nothing to commit, working directory clean
Now the README.md file is the original one. If we want, we can make a copy of the modified file before unmodifying a modified file (git checkout -- Filename).
Summary
- (undo git pull) git fetch; git reset --hard origin/master # OR git reset --hard HEAD
- (undo commit) git reset --soft HEAD~
- (undo stage) git reset HEAD Filename
- (undo change) git checkout -- Filename
git push error (both clients are linux), Your branch and 'origin/master' have diverged
Two clients (mint and vm) running on Linux. The following is coming from vm machine.
brb@ubuntu:~/toy$ git push ! [rejected] master -> master (fetch first) error: failed to push some refs to 'https://[email protected]/arraytools/toy.git' hint: Updates were rejected because the remote contains work that you do hint: not have locally. This is usually caused by another repository pushing hint: to the same ref. You may want to first integrate the remote changes hint: (e.g., 'git pull ...') before pushing again. hint: See the 'Note about fast-forwards' in 'git push --help' for details. brb@ubuntu:~/toy$ git pull remote: Counting objects: 3, done. remote: Compressing objects: 100% (2/2), done. remote: Total 3 (delta 0), reused 3 (delta 0), pack-reused 0 Unpacking objects: 100% (3/3), done. From https://github.com/arraytools/toy a95258a..b2f1ee4 master -> origin/master Auto-merging linuxfile CONFLICT (content): Merge conflict in linuxfile Automatic merge failed; fix conflicts and then commit the result. brb@ubuntu:~/toy$ cat linuxfile first line <<<<<<< HEAD second line edited by vm ======= second line edited by mint >>>>>>> b2f1ee4b1f9c2a428a1af061c7b40316a8f85d3d brb@ubuntu:~/toy$ git status On branch master Your branch and 'origin/master' have diverged, and have 1 and 1 different commit each, respectively. (use "git pull" to merge the remote branch into yours) You have unmerged paths. (fix conflicts and run "git commit") Unmerged paths: (use "git add <file>..." to mark resolution) both modified: linuxfile no changes added to commit (use "git add" and/or "git commit -a")
master branch and 'origin/master' have diverged, how to 'undiverge' branches'?
The solution now is to run git mergetool (assume we have install something like meld, opendiff, kdiff3, tkdiff, or xxdiff). See Git Mergetool – Merging With a GUI from gitguys.com.
After we edit the file in the middle of meld, we save it and quit meld. Go back to the terminal. Strangely, git knows the conflict has been resolved (shown from git status).
brb@ubuntu:~/toy$ cat linuxfile first line second line. conflict resolved in vm brb@ubuntu:~/toy$ git status On branch master Your branch and 'origin/master' have diverged, and have 1 and 1 different commit each, respectively. (use "git pull" to merge the remote branch into yours) All conflicts fixed but you are still merging. (use "git commit" to conclude merge) Changes to be committed: modified: linuxfile Untracked files: (use "git add <file>..." to include in what will be committed) linuxfile.orig brb@ubuntu:~/toy$ git commit -m "resolve the conflict in vm" [master f22932b] resolve the conflict in vm brb@ubuntu:~/toy$ git status On branch master Your branch is ahead of 'origin/master' by 2 commits. (use "git push" to publish your local commits) Untracked files: (use "git add <file>..." to include in what will be committed) linuxfile.orig nothing added to commit but untracked files present (use "git add" to track) brb@ubuntu:~/toy$ git push
The repository now looks like:
warning: push.default is unset
Git 2.0 from 'matching' to 'simple'. To squelch this message ...
See stackoverflow.
It only affects what happens when you don't specify which branches you want to push; e.g. 'git push' instead of 'git push -u origin master'.
I guess 'simple' (the default) is what we/beginners usually want. Run
git config --global push.default simple
git difftool & meld
git diff can only show the differences on the terminal. git difftool will show the difference on the GUI program.
git difftool FILENAME -y will launch 'meld' (if it has been installed before) to compare the file between revisions by using custom tools. It has to be run before we call git add. This is quite convenient since you can double check before running git commit. The '-y' argument is used to launch a diff tool without a prompt. See the documentation here.
To compare two revisions (sha1sum, branch name)
git difftools <revision_1> <revision_2>
To create a (temporary) branch, use git branch -b BRANCHNAME. To delete a (temporary) branch, use git branch -D BRANCHNAME.
It may be helpful to run the following too
git config --global diff.tool meld
diff between two revisions
git diff <revision_1>:<file_1> <revision_2>:<file_2> git difftools <revision_1> <revision_2> # ask to go each file separately git diff --name-only SHA1 SHA2 # show only file names git diff --name-only HEAD~10 HEAD~5 # between the tenth latest commit and the fifth latest
Monitor/find files that have been changed since last pull
git branch git fetch origin/master # or git fetch on Windows git diff --name-only origin/master git log # local git log origin/master # remote repository $ git status On branch master Your branch is behind 'origin/master' by 2 commits, and can be fast-forwarded. (use "git pull" to update your local branch) nothing to commit, working directory clean
We can also use the gitk to view the log. The following is a screenshot from Window's git gui (Windows Start > Git > Git Gui. Then Repository > Visualize All Branch History). As you can see the local repository (master w/ yellow circle) is 2 commits behind the remote repository (remotes/origin/master w/ blue circle).
Pull and overwrite local files
If we want to run git pull and also overwrite possibly changed local file, we use (see stackoverflow)
git fetch --all git reset --hard origin/master
Your branch is ahead by X commits after running git pull
git status shows Your branch is Ahead by X commits after running git pull. See this post. The solution is to run git fetch after git pull.
This repository currently has approximately XXXX loose objects
git gc --aggressive
git commit -am
works only for simple edits. It does not work for renaming files, etc.
git diff --staged
git checkout -- FileName
to recover a modified/deleted file where -- is related to branches
rm FileName git pull # do nothing git status # still miss 'FileName' git checkout FileName
git reset HEAD FileName
to un-stage a file
Rewrite a commit
ps. This is different from the case of Pull and overwrite local files
Suppose someone made a stupid commit. We want to get a previous version of the code and commit that one.
git checkout XXXXXX -- FileName git commit -am CommitMessage
origin and nickname
git remote add NickName https://XXX git remote git push -u NickName master
Import from CVS
- http://git-scm.com/docs/gitcvs-migration
- http://stackoverflow.com/questions/20869710/migrate-from-cvs-to-git-without-losing-history (see also comments after the suggestion using git-cvsimport)
sudo apt-get install git-cvs # cvsimport command tar xzvf tmp.tar.gz cd DirectoryName # The next command requires a connection to the CVS server even we have a copy of CVS in the local pc git cvsimport -C ~/Downloads/tmp ModuleName # SLOW & give up
General resources
- https://www.atlassian.com/git/tutorial/remote-repositories
- http://www.sbf5.com/~cduan/technical/git/git-4.shtml
- http://www.acquia.com/blog/getting-started-collaborative-development-git
- http://documentup.com/skwp/git-workflows-book
- http://www.eqqon.com/index.php/Collaborative_Github_Workflow
Git hosting services
Gitlab
- gitlabr R package
Compared to Github, Gitlab can
- host private projects for free
- host static web pages on http://pages.gitlab.io/.
Host web site
Bitbucket
Github
Create a new repository
After we use the web interface to create a new empty repository, we are instructed to do one of the following
- create a new repository on the command line
echo "# toy" >> README.md git init git add README.md git commit -m "first commit" git remote add origin https://github.com/arraytools/toy.git git push -u origin master
- push an existing repository from the command line
git remote add origin https://github.com/arraytools/toy.git git push -u origin master
- import code from another repository. You can initialize this repository with code from a Subversion, Mercurial, or TFS project.
Host web site
- Using GitHub Pages To Host Your Website using a Custom Domain. The IP address information for Github is changed to new ones.
Some Examples:
- PiScope
- dygraphs for R
- networkD3 for R
- BRB-DGE
- read depth calculator It can run some script!!!
Jekyll
Install Jekyll
on Ubuntu 14.04 I use (the second command will take a while to start),
sudo apt-get install ruby1.9.1-dev sudo gem install jekyll
Example 1
cd /tmp jekyll new MyNewSite # It will create a new folder 'MyNewSite' with about.md, _config.yml, css (folder), # _includes (folder), index.html, _layouts (folder), _posts (folder) and _sass (folder). cd MyNewSite jekyll serve --watch # It'll say the Server Address: http://127.0.0.1:4000/ # We can open a browser to see a template of html page created by '''jekyll new''' command.
hexo
Hexo is a fast, simple and powerful blog framework. You write posts in Markdown (or other languages) and Hexo generates static files with a beautiful theme in seconds.
Example
Sphinx
Examples
Markdown
- Editor/viewer on Ubuntu. See this discussion. Retext
- Multiple platforms.
- Haroopad free, not opensource
- Windows:
- Markdownpad nonfree.
- Texts notfree
- Python solution. Grip
- Online StackEdit