Github: Difference between revisions

From 太極
Jump to navigation Jump to search
(295 intermediate revisions by the same user not shown)
Line 3: Line 3:
* [https://schacon.github.io/gitbook/index.html Git Community Book]
* [https://schacon.github.io/gitbook/index.html Git Community Book]
* [https://git-scm.com/doc Git Documentation] & [http://git-scm.com/book/en/Git-Basics-Working-with-Remotes Pro Git book]
* [https://git-scm.com/doc Git Documentation] & [http://git-scm.com/book/en/Git-Basics-Working-with-Remotes Pro Git book]
* [https://help.github.com/en/github GitHub.com Help Documentation]
* [https://www.youtube.com/playlist?list=PLg7s6cbtAD15G8lNyoaYDuKZSKyJrgwB- Github & Git Foundations Training] from youtube.
* [https://www.youtube.com/playlist?list=PLg7s6cbtAD15G8lNyoaYDuKZSKyJrgwB- Github & Git Foundations Training] from youtube.
* [http://kbroman.org/github_tutorial/ git/github guide a minimal tutorial] from Karl Broman
* [http://kbroman.org/github_tutorial/ git/github guide a minimal tutorial] from Karl Broman
Line 20: Line 21:
* http://haacked.com/archive/2012/05/21/introducing-github-for-windows.aspx
* http://haacked.com/archive/2012/05/21/introducing-github-for-windows.aspx
* [https://help.github.com/articles/deleting-a-repository Delete a repository]
* [https://help.github.com/articles/deleting-a-repository Delete a repository]
* [https://journals.plos.org/ploscompbiol/article?id=10.1371/journal.pcbi.1004668 A Quick Introduction to Version Control with Git and GitHub]
== Github profile ==
[https://www.makeuseof.com/customize-your-github-profile-with-a-readme/ Customize Your GitHub Profile With a ReadMe]


== git config ==
== git config ==
[https://opensource.com/article/22/9/git-configuration-linux 5 Git configurations I make on Linux]
This has been run the very first time you use ''git commit''.
This has been run the very first time you use ''git commit''.


Line 40: Line 47:
</syntaxhighlight>
</syntaxhighlight>
to confirm the configuration.
to confirm the configuration.
Another way: [https://opensource.com/article/20/10/git-config Tweak your Git config for multiple user IDs]
=== ssh key ===
<ul>
<li>[https://www.cloudsavvyit.com/14914/how-to-fix-git-using-the-wrong-ssh-key-account/ How to Fix Git Using the Wrong SSH Key and Account]. nano ~/.ssh/config (modify the IdentityFile location as needed)
<pre>
Host github
  Hostname github.com
  IdentityFile ~/.ssh/id_rsa
  IdentitiesOnly yes
</pre>
</li>
<li>[https://docs.github.com/en/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent Generating a new SSH key and adding it to the ssh-agent]
</li>
</ul>
=== Privacy email ===
* [https://docs.github.com/en/github/setting-up-and-managing-your-github-user-account/setting-your-commit-email-address Setting your commit email address]
* [https://github.blog/2017-04-11-private-emails-now-more-private/ Private emails, now more private]
* [https://codelovingyogi.medium.com/using-githubs-noreply-email-address-48aa2a16ba42 using github’s noreply email address]. <username>@users.noreply.github.com
== github ==
[https://github.com/MalikaIhle/Introduction-RStudio-Git-GitHub Introduction to version Control in R with RStudio, Git, and Github]
* create a new repo on github. '''Skip creating License or README''' since if the new repository is not empty we will have a trouble to do an initial "git push". We can set the new repository private initially until everything is working. If a new repository was created, github will give us an instruction.
* create a new project folder locally. Make sure ".gitignore" is created/checked in RStudio
** create new files/directories locally.
** run "git init".
** run "git config user.name"
** run "git config user.email"
** run "git remote add origin [email protected]:arraytools/heatmap.git" for example where heatmap is my repository's name. The link is under the green Code -> '''SSH''' button.
** run "git branch -M main"
** run "git push -u origin main"
* Change the github repository to public if we want to use services like [https://htmlpreview.github.io/ html preview].
=== R: usethis ===
[https://www.r-bloggers.com/2023/01/git-and-github-in-r-for-the-casual-user/ git and GitHub in R for the casual user]
== Most common commands ==
# git config
# git init
# git clone
# git checkout
# git add
# git commit
# git status
# git push
# git pull
# git branch
# git merge
# git rebase


== git stage area ==
== git stage area ==
Line 48: Line 106:
For example, if your IDE accidentally deletes a file for you, you can run '''git reset HEAD FILENAME''' and '''git checkout FILENAME''' to recover the file.
For example, if your IDE accidentally deletes a file for you, you can run '''git reset HEAD FILENAME''' and '''git checkout FILENAME''' to recover the file.


== git push, git clone and remote repository ==
=== 'git mv' vs 'mv' ===
If we use 'git mv SOMEFILE NEWILE', we will not be able to use 'git checkout SOMEFILE'.
 
If we try to do that, we will get a message "error: pathspec 'SOMEFILE' did not match any file(s) known to git".
 
== git remote, git push, git clone and remote repository ==
For a new repository, use '''git remote add origin''' (not '''git remote set-url''') before calling '''git push'''.
For a new repository, use '''git remote add origin''' (not '''git remote set-url''') before calling '''git push'''.
<syntaxhighlight lang='bash'>
<syntaxhighlight lang='bash'>
git remote add origin https://github.com/USERNAME/REPOSITORY.git
git remote add origin https://github.com/USERNAME/REPOSITORY.git # 'origin' is an alias of the long URL
git remote add origin [email protected]:USERNAME/REPOSITORY.git
git remote add origin [email protected]:USERNAME/REPOSITORY.git  
</syntaxhighlight>
</syntaxhighlight>


Line 60: Line 123:
git remote set-url origin https://[email protected]/name/repo.git # skip password for security
git remote set-url origin https://[email protected]/name/repo.git # skip password for security
git remote -v
git remote -v
cat .git/config
</syntaxhighlight>
</syntaxhighlight>
OR when you run git clone, use the format
OR when you run git clone, use the format
<syntaxhighlight lang='bash'>
<syntaxhighlight lang='bash'>
git clone https://[email protected]/name/repos.git
git clone https://[email protected]/name/repos.git
git clone https://[email protected]/name/repos.git repos2 # use 'repos2' as the directory name
# git clone [email protected]:username/repos.git
# git clone [email protected]:username/repos.git
git remote -v
git remote -v
Line 82: Line 148:
git clone ssh://[email protected]/home/git/seqtoolsweb.git --branch gh-pages --single-branch seqtoolsweb
git clone ssh://[email protected]/home/git/seqtoolsweb.git --branch gh-pages --single-branch seqtoolsweb
</pre>
</pre>
=== A local copy of origin/master ===
When we do 'git push', git will automatically create a copy of origin/branchName on our local computer. So origin/branchName is a branch on our local machine that references the remote server branch.
Use 'git fetch' to sync our local copy of origin/branchName with remote's branchName.
=== Github wiki pages ===
[https://help.github.com/en/github/building-a-strong-community/adding-or-editing-wiki-pages Documenting your project with wikis] from the official Github Help website.
See [https://stackoverflow.com/a/24797660 here] for git clone the wiki repository.
<pre>
git clone https://[email protected]/myusername/foobar.wiki.git
git checkout $(git rev-list -n 1 HEAD -- yourPage)^ -- yourPage
</pre>
It works on the [https://github.com/ccrisan/motioneye/wiki/Install-On-Raspbian motionEye wiki] page. git clone https://github.com/ccrisan/motioneye.wiki.git
== git clone --depth=1 ==
只克隆某个指定分支的最近一次commit. [https://www.theserverside.com/blog/Coffee-Talk-Java-News-Stories-and-Opinions/How-and-when-to-perform-a-depth-1-git-clone Why use a git clone depth 1?]


== git fork ==
== git fork ==
* https://help.github.com/articles/fork-a-repo  
* https://help.github.com/articles/fork-a-repo
* [https://stackoverflow.com/a/70648577 How can I tell who forked my repository on GitHub?]. You can check the forks in Insights -> Forks.


== First example ==
== First example ==
Line 114: Line 199:
git log
git log
# get a specific version
# get a specific version
git checkout commit_id
git checkout commit_id # You are in 'detached HEAD' state


# after an examination, we want to get the latest version
# after an examination, we want to get the latest version
Line 155: Line 240:
<syntaxhighlight lang='bash'>
<syntaxhighlight lang='bash'>
# move HEAD to origin
# move HEAD to origin
git checkout origin/master
git checkout origin/master   # You are in 'detached HEAD' state
 
                            # I should use "git checkout master" to go back to my local master
                            # OR
                            # use something like "git checkout -b test origin/master"
# Visualize using text mode
# Visualize using text mode
git log --graph --oneline --date-order --decorate --color --all   
git log --graph --oneline --date-order --decorate --color --all   
Line 173: Line 260:


== [http://www.git-scm.com/downloads/guis GUI version of Git software] ==
== [http://www.git-scm.com/downloads/guis GUI version of Git software] ==
[https://www.cloudsavvyit.com/2261/should-you-use-a-gui-git-client/ Should You Use a GUI Git Client?]
=== Windows ===
=== 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 [[#Monitor.2Ffind_files_that_have_been_changed_since_last_pull|below]].
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 [[#Monitor.2Ffind_files_that_have_been_changed_since_last_pull|below]].
Line 181: Line 270:


=== Linux ===
=== Linux ===
Use [[#gitk_and_git-gui|gitk]] or gitg. For example,  
Use [[#gitk_and_git-gui|gitk]] or [https://wiki.gnome.org/Apps/Gitg/ gitg] ('''sudo apt install gitg''', better than gitk on gnome based Ubuntu). For example,  
<syntaxhighlight lang='bash'>
<syntaxhighlight lang='bash'>
gitk --all
gitk --all
Line 187: Line 276:


If we run the gitk/gitg in background ('''gitg --all &'''), we will see the tree changed in real time when we run git commands in a terminal.
If we run the gitk/gitg in background ('''gitg --all &'''), we will see the tree changed in real time when we run git commands in a terminal.
The problem with gitk is the font is awful.
'''gitg''' program (install it by '''sudo apt install gitg''') looks nice.
GitKraken needs to sign in with Github or Gitkraken account.
git-cola: I am lost:(


=== Mac ===
=== Mac ===
[https://electronjs.org/apps/github-desktop GitHub Desktop] (Electron based)
* [https://electronjs.org/apps/github-desktop GitHub Desktop] (Electron based)
* [https://www.gitkraken.com/download GitKraken], free but not open-source. GitKraken offers a subscription model for additional features and support.
* [https://www.syntevo.com/smartgit/download/ SmartGit], free but not open-source for the current version. SmartGit also offers a subscription model for additional features and support.
* [https://github.com/jesseduffield/lazygit Lazygit] is a terminal-based Git client with a user-friendly interface.


=== Gitk colors and bold ===
=== Gitk colors and bold ===
[http://gitolite.com/gitk.html The missing gitk documentation]
[http://gitolite.com/gitk.html The missing gitk documentation].


* '''local branch''' names are in a green background
* a yellow dot <span style="background:#ffd500">&#9675; </span> marks the current '''HEAD''' (it seems the yellow dot and '''bold''' branch name are always together). Note that if we use "git log" to show the history in the command line, the <span style="color:#00FFFF; background:#000000">HEAD</span> is shown in cyan color. See [https://lostechies.com/joshuaflanagan/2010/09/03/use-gitk-to-understand-git/ Use gitk to understand git].
* '''remote branch''' names are in a mixed orange/green background
* '''local branch''' names are in a <span style="color:#000000; background:#00C000">green background</span>. See [https://lostechies.com/joshuaflanagan/2010/09/03/use-gitk-to-understand-git/ Use gitk to understand git].
* '''remote branch''' names are in a mixed <span style="color:#000000; background:#fba69c">orange</span>/<span style="color:#000000; background:#00C000">green</span> background. See [https://lostechies.com/joshuaflanagan/2010/09/03/use-gitk-to-understand-git/ Use gitk to understand git].
* the currently checked out branch name is in '''bold'''
* the currently checked out branch name is in '''bold'''
* a yellow dot marks the current HEAD (it seems the yellow dot and '''bold''' branch name are always together)
* tags are on a yellow background
* tags are on a yellow background


See a screenshot at [[#pull|Branch - Pull]].
See a screenshot at [[#pull|Branch - Pull]].


== Set up a new local/remote repository ==
== ssh key ==
<syntaxhighlight lang='bash'>
See [[Linux#Multiple_ssh_keys|Linux > Multiple ssh keys]].
mkdir /path/to/your/project
* [https://help.github.com/articles/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent/#platform-linux Github]
* [https://www.makeuseof.com/using-ssh-for-github-passwordless-authentication/ Using SSH for GitHub Passwordless Authentication]
* [https://confluence.atlassian.com/bitbucket/how-to-install-a-public-key-on-your-bitbucket-cloud-account-276628835.html Bitbucket]. Remember to change the remote repository from https protocol to git protocol on local repository.
 
If you add a new key to your bitbucket account, you will receive an email about the change.
 
=== Github ===
* [https://happygitwithr.com/https-pat.html Personal access token for HTTPS]
* [https://docs.github.com/en/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent# Adding your SSH key to the ssh-agent]
 
<pre>
$ eval "$(ssh-agent -s)"
$ ssh-add -K ~/.ssh/idName_rsa
</pre>
 
=== Multiple git accounts ===
https://www.cloudsavvyit.com/2245/how-to-manage-multiple-git-accounts-on-one-system/ How to Manage Multiple Git Accounts on One System]
 
== Use command line to create a remote repository ==
[https://stackoverflow.com/a/2425632 Is it possible to create a remote repo on GitHub from the CLI without opening browser?]
<pre>
curl -F 'login=username' -F 'token=API Token' \
  https://github.com/api/v2/yaml/repos/create -F name=reponame
</pre>
 
== Set up a new local/remote repository ==
[https://stackoverflow.com/a/32056416 There is no tracking information for the current branch]
<syntaxhighlight lang='bash'>
mkdir /path/to/your/project
cd /path/to/your/project
cd /path/to/your/project
git init
git init
git remote add origin https://[email protected]/arraytools/REPOSITORYNAME.git
git remote add origin https://[email protected]/arraytools/REPOSITORYNAME.git
# git remote add origin [email protected]:arraytools/REPOSITORYNAME.git
# git remote add origin ssh://[email protected]/home/git/REPOSITORYNAME.git
# git remote add origin ssh://[email protected]/home/git/REPOSITORYNAME.git
# git clone            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 user.name "YOUR NAME"
git config --global user.email "YOUR EMAIL ADDRESS"
git config user.email "YOUR EMAIL ADDRESS"
git config --list # confirm
git config --list # confirm


# Option 1
# Create README.md using Github Web
git pull origin main
# Con: no tracking info is recorded
git branch --set-upstream-to=origin/main master
git pull
# Option 2
echo "arraytools" >> contributors.txt
echo "arraytools" >> contributors.txt
git add contributors.txt
git add contributors.txt
Line 220: Line 357:
git push -u origin master
git push -u origin master
</syntaxhighlight>
</syntaxhighlight>
== ssh key ==
See [[Linux#Multiple_ssh_keys|Linux > Multiple ssh keys]].
* [https://help.github.com/articles/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent/#platform-linux Github]
* [https://confluence.atlassian.com/bitbucket/how-to-install-a-public-key-on-your-bitbucket-cloud-account-276628835.html Bitbucket]. Remember to change the remote repository from https protocol to git protocol on local repository.
If you add a new key to your bitbucket account, you will receive an email about the change.


== Already has a git repository on my computer ==
== Already has a git repository on my computer ==
Line 236: Line 366:
</syntaxhighlight>
</syntaxhighlight>


== 'master' and 'origin' ==
== Rename a remote repository ==
* 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.
# Go to github.com, open the project and click Settings button on the left-bottom corner. Change the repository name on top.
* 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.
# On local machine, rename the directory. Go to the directory. Issue
 
<syntaxhighlight lang='bash'>
https://lostechies.com/joshuaflanagan/2010/09/03/use-gitk-to-understand-git/
git remote -v
 
</syntaxhighlight>
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
<syntaxhighlight lang='bash'>
git remote set-url origin [email protected]:someuser/newprojectname.git
</syntaxhighlight>
 
Suppose we have added ssh key to git server and we want to use ssh key/protocol to automatically access the server instead of entering the password (https protocol). See
* [https://confluence.atlassian.com/bitbucket/set-up-ssh-for-git-728138079.html bitbucket]
* [https://help.github.com/articles/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent/#platform-linux github]
<syntaxhighlight lang='bash'>
$ # the REMOTE below could be 'origin' or any name you define
$ git remote show REMOTE
$ git remote set-url REMOTE ssh://[email protected]/USERNAME/REPOS.git
$ git remote show REMOTE
$ git status  # show local branch is update-to-date with REMOTE/BRANCH.
</syntaxhighlight>
 
== '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. That is, if you run git clone -o booyah instead, then you will have booyah/master as your default remote branch. See [https://git-scm.com/book/tr/v2/Git-Branching-Remote-Branches Remote Branches] or [https://lostechies.com/joshuaflanagan/2010/09/03/use-gitk-to-understand-git/ Use gitk to understand git].
 
=== Change GitHub default branch from master to main ===
* [https://stevenmortimer.com/5-steps-to-change-github-default-branch-from-master-to-main/ 5 steps to change GitHub default branch from master to main]
* [https://www.tidyverse.org/blog/2021/10/renaming-default-branch/ Renaming the default branch] from tidyverse by Jenny Bryan
 
== 'origin master' vs 'origin/master' format ==
== 'origin master' vs 'origin/master' format ==
* '''origin master''' format: '''[https://git-scm.com/docs/git-push git push]''', '''[https://git-scm.com/docs/git-pull git pull]''', '''[https://git-scm.com/docs/git-fetch git fetch]''' where the branch name is optional.
* '''origin master''' format: '''[https://git-scm.com/docs/git-push git push]''', '''[https://git-scm.com/docs/git-pull git pull]''', '''[https://git-scm.com/docs/git-fetch git fetch]''' where the branch name is optional.
* origin/master format: git checkout, git merge, git diff, git log, git reset.
* '''origin/master''' format: branch, diff, log, merge, reset but <span style="color: red">don't do it on checkout unless we create a new branch</span>; eg '''git checkout -b newBranch origin/newBranch'''. Note that '''origin/master is a local copy''' of the branch named "master" on the remote named "origin".


See [http://stackoverflow.com/questions/18137175/in-git-what-is-the-difference-between-origin-master-vs-origin-master stackoverflow].
See [http://stackoverflow.com/questions/18137175/in-git-what-is-the-difference-between-origin-master-vs-origin-master stackoverflow].


== Multiple remotes ==
== Multiple remotes ==
[https://opensource.com/article/20/11/multiple-git-repositories Keep track of multiple Git remote repositories]
Suppose I have a remote at github.com. I add another remote (bitbucket.com) in my current project.
Suppose I have a remote at github.com. I add another remote (bitbucket.com) in my current project.
<syntaxhighlight lang='bash'>
<syntaxhighlight lang='bash'>
Line 331: Line 487:
</syntaxhighlight>
</syntaxhighlight>


== '''-u''' option ==
=== Import/move/migrate (not clone) a repository from one remote to another remote ===
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.
NB: bitbucket allows to use its web interface to import a remote repository. We just need to give it the URL (eg from Github) and the new repository name. I can use this way to back up some public repositories from github.
 
=== “git push -u origin master” vs “git push origin master” ===
* [http://stackoverflow.com/questions/5697750/what-exactly-does-the-u-do-git-push-u-origin-master-vs-git-push-origin-ma What does the '-u' do in git push]


=== git branch ===
Suppose the new remote is on bitbucket.
* [http://stackoverflow.com/questions/4878249/how-do-i-change-the-remote-a-git-branch-is-tracking How do I change the remote a git branch is tracking?]
<syntaxhighlight lang="bash">
rsync -av DIRECTORY .
cd SUBDIRECTORY
git remote -v # Examine the current URL
git remote set-url origin [email protected]:USERNAME/DIRECTORY.git
git remote -v # Examine the new URL
git push -u origin --all
git push origin --tags
</syntaxhighlight>
 
Other instructions
* https://stackoverflow.com/questions/1484648/how-to-migrate-git-repository-from-one-server-to-a-new-one
* https://www.smashingmagazine.com/2014/05/moving-git-repository-new-server/
<pre>
# fetch all of the remote branches and tags
$ git fetch origin
$ git branch -a
* master
  remotes/origin/develop
  remotes/origin/master
  remotes/origin/release/0.1


The ''git branch'' command can be used to connect a local branch and a remote branch.
$ git checkout -b develop origin/develop
<syntaxhighlight lang='bash'>
$ git checkout -b release/0.1 origin/release/0.1
$ git status
$ git branch -a
# suppose the local master is connected to bitbucket/master
  develop
  master
* release/0.1
  remotes/origin/develop
  remotes/origin/master
  remotes/origin/release/0.1
# all branches in our repository are stored locally,
# we are ready to move the repository to a new host


$ git branch master -u origin/master
# assume we have an SSH-cloned URL of our new repository
# now the local master is connected to origin/master
$ git remote add new-origin [email protected]:manakor/manascope.git
# the local branch name and the remote branch name can be different if you like!
# This will give us two remotes for the existing repository:
$ git status
# the original one (named origin, connected to the existing remote host) and
</syntaxhighlight>
# a new one (named new-origin, connected to the new host).


Note that '''gitk can not see the difference when we change the connection of a local branch and a remote branch'''. Only the ''git status'' can reveal the connection.
# pushing all branches at once
$ git push --all new-origin
$ git push --tags new-origin


=== Example ===
# make new-origin the default remote,
* [[#Multiple_remotes|Multiple remotes]]
$ git remote rm origin
$ git remote rename new-origin origin
</pre>


== Setup editor ==
=== How to keep two Git repositories in sync ===
See '''man git-commit'''.
[https://opentechguides.com/how-to/article/git/177/git-sync-repos.html How to keep two Git repositories in sync]
<pre>
$ git clone --mirror https://primary_repo_url/primary_repo.git
$ cd primary_repo.git
$ git remote add --mirror=fetch secondary https://secondary_repo_url/secondary_repo.git
 
$ git fetch origin
$ git push secondary --all
</pre>
 
== '''-u''' option ==
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.
 
=== “git push -u origin master” vs “git push origin master” ===
[http://stackoverflow.com/questions/5697750/what-exactly-does-the-u-do-git-push-u-origin-master-vs-git-push-origin-ma What does the '-u' do in git push]. '''The message: most of time we want to use "-u" option'''.
 
Adding '-u' means our local master is '''tracking''' remote's master branch. Run "cat .git/config" and look at the ''[branch 'master']'' section -> the 'remote' key. It should have a value 'origin'. The 'merge' key has a value 'refs/head/master'. These information are added automatically when we clone a remote repository.
 
If we do not put "-u" in git push, it would not be a tracking branch. We can manually edit 'git/config' file or use git branch --set-upstream-to or just "-u" and the branch name (check out '''git help branch'''). For example, "git branch -u origin/newbranch newbranch" where ''newbranch'' is a local branch name.
 
Also we can untrack a remote branch by using "git branch --unset-upstream newbranch".
 
=== git branch ===
* [http://stackoverflow.com/questions/4878249/how-do-i-change-the-remote-a-git-branch-is-tracking How do I change the remote a git branch is tracking?]
 
The ''git branch'' command can be used to connect a local branch and a remote branch.
<syntaxhighlight lang='bash'>
$ git status
# suppose the local master is connected to bitbucket/master
 
$ git branch master -u origin/master
# now the local master is connected to origin/master
# the local branch name and the remote branch name can be different if you like!
$ git status
</syntaxhighlight>
 
Note that '''gitk can not see the difference when we change the connection of a local branch and a remote branch'''. Only the ''git status'' can reveal the connection.
 
=== Example ===
* [[#Multiple_remotes|Multiple remotes]]
 
== Setup editor ==
See '''man git-commit'''.
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
git config --global core.editor "nano"
git config --global core.editor "nano"
Line 371: Line 597:
         editor = nano
         editor = nano
</syntaxhighlight>
</syntaxhighlight>
=== Multiline commit messages ===
Once we issue "git commit -a", it opens a text editor. When we write the messages, '''we want the first line a simple description, the 2nd line empty and the rest of lines a more detailed message'''. With this way, when we use "git log --oneline", the message is short and we can still use "git log" to see the full message.


== .gitignore file ==
== .gitignore file ==
Line 387: Line 616:
</syntaxhighlight>
</syntaxhighlight>
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.
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.
=== R projects ===
<pre>
~*
.Rproj.user
**/*.docs
renv
</pre>
=== Whitelist ===
<ul>
<li>[https://www.cloudsavvyit.com/14444/how-to-set-up-gitignore-as-a-whitelist/ How to Set Up .gitignore As a Whitelist]
<pre>
*
!*/
# track this file
!.gitignore
# whitelist everything in ./config/
!config/
</pre>
</li>
<li>[https://stackoverflow.com/a/44568826  Gitignore everything except a subfolder].
* The first two lines below are required
* If the directory or filename contains spaces, we need to add a backslash to escape the space character.
* We cannot use {*.R,*.Rmd} for including two types of files; we need to write these rules separately.
<pre>
*
!*/
!That/Very/Folder/**
!Also/This/Another/Folder/**
!Primary\ analysis/**/*.R
!Primary\ analysis/**/*.Rmd
</pre>
</li>
</ul>
== git commit message ==
* [https://www.conventionalcommits.org/en/v1.0.0/ Conventional Commits] - A specification for adding human and machine readable meaning to commit messages.
* [https://chris.beams.io/posts/git-commit/ The seven rules of a great Git commit message]
* [http://udacity.github.io/git-styleguide/ Udacity Git Commit Message Style Guide]
* [https://www.freecodecamp.org/news/writing-good-commit-messages-a-practical-guide/ How to Write Good Commit Messages: A Practical Git Guide]
* [https://paulvanderlaken.com/2020/05/11/how-to-write-git-commit-message-7-steps/ How to Write a Git Commit Message, in 7 Steps]
** Separate subject from body with a blank line
** Limit the subject line to 50 characters
** Capitalize the subject line
** Do not end the subject line with a period
** Use the imperative mood in the subject line
** Wrap the body at 72 characters
** Use the body to explain what and why vs. how
* [https://medium.com/@steveamaza/how-to-write-a-proper-git-commit-message-e028865e5791 A commit message should answer three primary questions;]
** Why is this change necessary? (most important)
** How does this commit address the issue?
** What effects does this change have?


== git status, multiple branches ==
== git status, multiple branches ==
Line 441: Line 727:
</syntaxhighlight>
</syntaxhighlight>
See [http://stackoverflow.com/questions/61212/how-do-i-remove-local-untracked-files-from-my-current-git-branch the discussion].
See [http://stackoverflow.com/questions/61212/how-do-i-remove-local-untracked-files-from-my-current-git-branch the discussion].
=== Back up untracked files ===
[https://opensource.com/article/20/10/advanced-git-tips 7 Git tricks that changed my life]
<pre>
$ git ls-files --others --exclude-standard -z |\
      xargs -0 tar rvf ~/backup-untracked.zip
</pre>


== Remove deleted files ==
== Remove deleted files ==
Line 448: Line 741:
</syntaxhighlight>
</syntaxhighlight>


== Undo ==
== Tell if a file is git tracked ==
[https://stackoverflow.com/a/2406813 How to tell if a file is git tracked]
<pre>
git ls-files --error-unmatch <file name>
 
# If a file is tracked,
git ls-files --error-unmatch  Additional17/Additional17.Rmd
Additional17/Additional17.Rmd
 
# If a file is not tracked,
git ls-files --error-unmatch  Datasets_clinical/data.clin.rds
error: pathspec 'Datasets_clinical/data.clin.rds' did not match any file(s) known to git
Did you forget to 'git add'?
</pre>
 
== Undo/Reset ==
https://git-scm.com/book/en/v2/Git-Basics-Undoing-Things
https://git-scm.com/book/en/v2/Git-Basics-Undoing-Things


Line 479: Line 787:
<syntaxhighlight lang='bash'>
<syntaxhighlight lang='bash'>
$ git reset HEAD Filename
$ git reset HEAD Filename
$ git reset    # unstage all due changes
</syntaxhighlight>
</syntaxhighlight>


Line 485: Line 794:
<syntaxhighlight lang='bash'>
<syntaxhighlight lang='bash'>
$ git reset --hard HEAD
$ git reset --hard HEAD
$ git reset --hard HEAD^ 
# discard the last commit and will be abandoned eventually after git did a garbage collection
$ git reset --hard <tree-ish>
</syntaxhighlight>
</syntaxhighlight>


Line 497: Line 810:


* Best for local private changes <syntaxhighlight lang='bash'>
* Best for local private changes <syntaxhighlight lang='bash'>
$ git reset --soft HEAD~1 # reset the HEAD (the last commit) to one commit before in the log history.
$ git reset --hard a1e8fb5
$ git reset --hard a1e8fb5
# Some middle commits will no longer exist in the commit history
# Some middle commits will no longer exist in the commit history
Line 504: Line 819:
# HEAD~ or HEAD^ means to move to commit before HEAD
# HEAD~ or HEAD^ means to move to commit before HEAD
# http://stackoverflow.com/questions/927358/how-do-you-undo-the-last-commit
# http://stackoverflow.com/questions/927358/how-do-you-undo-the-last-commit
$ git reset --soft HEAD^^
# move to the grandparent commit
</syntaxhighlight>
</syntaxhighlight>


Line 527: Line 845:
git rm --cached mylogfile.log  # file
git rm --cached mylogfile.log  # file
git rm --cached -r mydirectory  # directory
git rm --cached -r mydirectory  # directory
git rm --cached <path_to_the_.DS_Store-file>
</syntaxhighlight>
</syntaxhighlight>


=== Git reset revert rebase commands ===
=== Git reset revert rebase commands ===
[https://opensource.com/article/18/6/git-reset-revert-rebase-commands How to reset, revert, and return to previous states in Git]
* [https://opensource.com/article/18/6/git-reset-revert-rebase-commands How to reset, revert, and return to previous states in Git]
* [https://www.lynda.com/Git-tutorials/Reset-types/5030980/2222186-4.html Lynda.com -> Git: Branches, Merges and Remotes -> Reset Branches]


=== Delete any untracked files or directories ===
=== Delete any untracked files or directories ===
Line 544: Line 864:
git clean -f -X # OR git clean -fX
git clean -f -X # OR git clean -fX
</syntaxhighlight>
</syntaxhighlight>
== git clone vs git pull ==
[https://stackoverflow.com/a/3623171 What is the difference between pull and clone in git?]


== git fetch vs git pull ==
== git fetch vs git pull ==
[http://stackoverflow.com/questions/292357/what-are-the-differences-between-git-pull-and-git-fetch search Briefly]
* https://git-scm.com/book/tr/v2/Git-Branching-Remote-Branches has diagrams
* [http://stackoverflow.com/questions/292357/what-are-the-differences-between-git-pull-and-git-fetch search Briefly]


<syntaxhighlight lang='bash'>
<syntaxhighlight lang='bash'>
Line 556: Line 880:
</syntaxhighlight>
</syntaxhighlight>


=== git fetch and gikt ===
=== git fetch ===
After we run '''git fetch origin master''', we will see the remote commits from '''gitk''' if we add '''--all''' option.  
Use '''git fetch''' as often as possible; before git push or before you go offline or before you work.
<syntaxhighlight lang='bash'>
 
<pre>
$ git fetch
$ git log --oneline -5 origin/master
$ git branch  # local only
$ git branch -r # remote only
 
$ git checkout master
$ git merge origin/master
$ git log --oneline master
</pre>
 
git fetch vs git pull
* If I am in the middle of committing something and get some work going on, I will do a git fetch to see what's on the server.
* If I am starting my work without making any changes/commits yet, I'll do a git pull. I want every thing on the server as my starting point.
 
=== git fetch and gikt ===
After we run '''git fetch origin master''', we will see the remote commits from '''gitk''' if we add '''--all''' option.  
<syntaxhighlight lang='bash'>
gitk --all
gitk --all
# OR
# OR
Line 564: Line 906:
</syntaxhighlight>
</syntaxhighlight>


== branch - not the same as in CVS ==
=== git pull ===
* https://lostechies.com/joshuaflanagan/2010/09/03/use-gitk-to-understand-git/
* [https://stackoverflow.com/a/10312587 How do I fetch all Git branches?]
* [http://www.thegeekstuff.com/2017/06/git-branch/ 15 Git Branch Command Examples to Create and Manage Branches]
 
== git show: show details on a commit ==
{{Pre}}
git show SHA
git show --name-status SHA # list the filenames along with an indicator (A for added, M for modified, D for deleted)
</pre>
Use 'f' to move forward and 'b' to move backward.


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.
== git log ==


Below are some info borrowed from Pro Git.
=== log in a branch or origin/master ===
=== master branch ===
View log from origin/master (it's a tracking copy on our local computer; it's not the actual remote branch)
When you clone a repository, it generally automatically creates a ''master'' branch that tracks ''origin/master''.
<pre>
$ git log myBranch


To set up other tracking branches, see [[#Remote_branches|Remote branches]].
$ git log --oneline -5 origin/master # last 5 commits from origin/master
<syntaxhighlight lang="bash">
</pre>
git checkout --track origin/serverfix
</syntaxhighlight>


=== Create a new branch ===
=== git log on a specific file ===
<syntaxhighlight lang="bash">
<syntaxhighlight lang='bash'>
git branch testing    # do not switch
git log FILENAME
git log --oneline --decorate
</syntaxhighlight>
</syntaxhighlight>
Pay attention to the keywords 'HEAD', 'master' and 'testing' in this case.


To create a new branch and switch to the new branch
=== git show change history of a file ===
<syntaxhighlight lang="bash">
Terminal
git status
<pre>
git checkout -b myBranch
git log -p FILENAME  # show changes
# OR create a new branch starting at the commit with an identifier
git log --follow FILENAME # doesn't show changes
# git checkout -b myBranch XXXXXXX
</pre>
git status
 
GUI
<pre>
gitk FILENAME
</pre>
 
=== git log show changed files only ===
[https://www.cloudsavvyit.com/13904/how-to-view-commit-history-with-git-log How to View Commit History With Git Log]


git log
<pre>
</syntaxhighlight>
git log --name-only


=== Delete a branch locally or from the remote ===
git log --stat # show how many lines of changes in files
Delete a local copy of a branch.
</pre>
<syntaxhighlight lang="bash">
# Since you can't delete a branch you're on, switch to the master branch.
git branch
git checkout master
git branch -d myBranch
</syntaxhighlight>


To delete the branch from the remote:
=== git log message is too long ===
<syntaxhighlight lang="bash">
Normally when we use 'git log' command, long log messages get truncated.
git push origin :myBranch


# OR
Use the following to view the complete log messages instead of truncated log messages.
git push -d origin myBranch
<syntaxhighlight lang='bash'>
git log | less
</syntaxhighlight>
</syntaxhighlight>
Common standard is 78 characters. See [http://stackoverflow.com/questions/8824863/show-full-git-commit-message-in-console this] and [http://stackoverflow.com/questions/2119942/how-to-wrap-git-commit-comments this] posts.


=== Switch branches in local repository ===
=== filtering by a date ===
<syntaxhighlight lang="bash">
<pre>
git checkout testing
git log --since=2019-01-01
git branch
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
</syntaxhighlight>


Note that when you run '''git pull''' without specify the branch name (eg gh-pages from the current local branch), it won't pull the latest from another branch (eg master).
git log --until=2019-01-01


=== Basic merging and conflicts ===
git log --until="3 days ago"
<syntaxhighlight lang="bash">
git checkout -b iss53
# shorthand for
# git branch iss53
# git checkout iss53


nano index.html
git log --after=2.weeks --before=3.days
git commit -a -m 'added a new footer [issue 53]'
</pre>
git checkout master


git checkout -b hotfix
=== filter by a name ===
nano index.html
<pre>
git commit -a -m 'fixed the broken email address'
git log --author="xxx"  # author string contains "xxx"
</pre>


git checkout master  # step 1. Move back to master for merging
=== filter by a keyword in log ===
git merge hotfix    # step 2. Merge the hotfix branch into the master
Search for a string in the log
git branch -d hotfix # step 3. Delete the branch
<pre>
git log --grep='String'
</pre>
 
=== filter by commits ===
<pre>
git log bd210165..HEAD
 
git log <SHA>..<SHA>
</pre>


git checkout iss53
=== Count number of commits ===
nano index.html
<pre>
git commit -a -m 'finished the new footer [issue 53]'
git rev-list --count master
</syntaxhighlight>
</pre>


'''Basic Merging:'''
=== Best ones: adding --graph --all ===
<syntaxhighlight lang="bash">
<pre>
git checkout master
git log --graph --all --stat # just see lines of changes, sha1 is complete
git merge iss53
</syntaxhighlight>


'''Basic merge conflicts''':
git log --graph --all --stat --abbrev-commit # same as above but sha1 is short
<syntaxhighlight lang="bash">
git merge iss53
git status # Look at the standard conflict-resolution markers to the top of files


git mergetool
git log --all --abbrev-commit -p FILENAME  # logs from all branches, not just the current branch
git status
</pre>
To shorten the command,
<syntaxhighlight lang='sh'>
git config --global alias.lg "log --graph --all --stat --abbrev-commit"
git lg
</syntaxhighlight>
</syntaxhighlight>
This command adds a new entry to your Git configuration file (usually located at '''~/.gitconfig''').


=== push the new branch to remote ===
=== Search in the code? ===
<syntaxhighlight lang="bash">
* [https://www.cloudsavvyit.com/13980/how-to-search-through-recent-git-commit-changes/ How to Search Through Recent Git Commit Changes]
# make sure we are at the right branch
* [https://ieftimov.com/learn-your-tools-navigating-git-history Navigating your Git History]
$ git branch -a  
** '''git log -S 'some words' '''    # search for the string in the code and show the logs
   master
* [https://stackoverflow.com/questions/17557684/is-it-better-to-use-git-grep-than-plain-grep-if-we-want-to-search-in-versioned-s Is it better to use git grep than plain grep if we want to search in versioned source code?]
* newbranch
<ul>
  remotes/bitbucket/master
<li>You can search in Git even if you aren't sure which commit—or even branch—you made your changes. See [https://opensource.com/article/20/10/advanced-git-tips 7 Git tricks that changed my life]
<pre>
$ git rev-list --all | xargs git grep -F 'KEYWORD'
</pre>
</li>
</ul>
 
== branch - not the same as in CVS ==
* https://lostechies.com/joshuaflanagan/2010/09/03/use-gitk-to-understand-git/
* [http://www.thegeekstuff.com/2017/06/git-branch/ 15 Git Branch Command Examples to Create and Manage Branches]
* [https://www.atlassian.com/git/tutorials/using-branches Git Branch]. '''git branch is tightly integrated with the git checkout and git merge commands.'''
* [https://readmedium.com/9-git-branching-strategies-every-developer-should-know-0a98b146c687 9 Git Branching Strategies Every Developer Should Know]
 
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.
=== list local and remote branches ===
<pre>
mac$ git branch # list branches in local repo
  branch0323
* master
mac$ git branch -a # list all remote branches
   branch0323
* master
   remotes/origin/HEAD -> origin/master
   remotes/origin/HEAD -> origin/master
   remotes/origin/master
   remotes/origin/master
$ git push -u bitbucket newbranch
</pre>
$ git status
 
On branch newbranch
=== "--track" option ===
Your branch is up-to-date with 'bitbucket/newbranch'.
When you clone a repository, it generally automatically creates a ''master'' branch that tracks ''origin/master''.


nothing to commit, working directory clean
To set up other tracking branches, see [[#Remote_branches|Remote branches]].
<syntaxhighlight lang="bash">
git checkout --track origin/serverfix
</syntaxhighlight>
</syntaxhighlight>
If another machine runs ''git pull'', it will get the new branch. The result can be seen by ''gitk --all''.


=== pull ===
=== Create a new local or remote branch, checkout a remote branch? ===
Suppose we are at the 'newbranch'. Some files are modified and committed to 'newbranch' (these actions are only done locally).  
We can use '''git branch''' or '''git checkout''' to create a new branch.
<syntaxhighlight lang="bash">
git branch testing    # do not switch
git log --oneline --decorate


If someone modified files and committed to the 'master' branch, then when we run ''git pull'' (keep it in mind that we are still on ''newbranch'') the files we just modified & committed OR even any files aren't affected since ''git pull'' is pulling files from the 'master' branch.
git checkout -b <new-branch> # creates and checks out <new-branch> off the current HEAD
git checkout -b <new-branch> <existing-branch>
</syntaxhighlight>
Pay attention to the keywords 'HEAD', 'master' and 'testing' in this case.
 
To create a new branch and switch to the new branch
<syntaxhighlight lang="bash">
git status
git checkout -b myBranch
# OR create a new branch starting at the commit with an identifier
# git checkout -b myBranch XXXXXXX
git status
 
git log
</syntaxhighlight>
 
To create a new branch based on a remote branch. <span style="color: red">Remote branch is just like any branch with one exception: you can't check them out.</span> You can merge with them. You can see what's in them. But you can't check them out. <span style="color: red">Instead you need to create a new branch which tracks it.</span>
<pre>
# Method 1: it does not move HEAD.
git branch myBranch origin/myBranch
git log --oneline -5 myBranch  # red color = a local copy of the remote repo, green color = local repo
 
# Method 2: it switches to the new branch immediately
git checkout -b myBranch origin/myBranch
</pre>


If we use the '''gitk --all''' or '''git log --graph --all --oneline --decorate''' command, we may see (remote has an orange background color, branch has a green background color, a yellow dot marks the current HEAD)
To create a remote branch, '''git push origin MyBranch'''; see [https://www.atlassian.com/git/tutorials/using-branches Git Branch] from Atlassian.
* remotes/bitbucket/newbranch
* remotes/bitbucket/master
* newbranch (local)
* master    (local)


These 4 branches could be on different nodes. Note. ''gitk'' output is easy to read but ''git log'' gives the SHA information. The screenshot from ''git log'' below does NOT use the ''--decorate'' option.
=== Delete a branch locally or from the remote ===
[https://www.makeuseof.com/how-to-delete-branch-git/ How to Delete a Branch in Git Locally and Remotely]


[[File:Git branch.png|250px]]
Cf. [[#push_the_new_branch_to_remote|Push to the remote branch]] by '''git push -u origin newBranch; git branch -r'''.


=== Branch management ===
Delete a local copy of a branch.
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
# Since you can't delete a branch you're on, switch to the master branch.
git branch
git branch
git branch -v          # see the last commit on each branch
git checkout master
git branch -vv        # see the last commit and what remote branch a local branch is tracking?
git branch -d myBranch
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 -a          # show all remotes' branches too
git branch -d testing
</syntaxhighlight>
</syntaxhighlight>


=== Branch workflows ===
To delete the branch from the remote:
NA
<syntaxhighlight lang="bash">
git push origin :myBranch
 
# OR
git push -d origin myBranch
 
# Checking
git branch -r
</syntaxhighlight>


=== Inspect a Remote ===
=== Switch branches in local repository ===
https://git-scm.com/book/ch2-5.html
<syntaxhighlight lang="bash">
<syntaxhighlight lang='bash'>
git checkout testing
brb@brb-P45T-A:~/github/SIK$ git remote
git branch
origin
nano test.rb
brb@brb-P45T-A:~/github/SIK$ git remote -v
git commit -a -m 'made a change'
origin https://[email protected]/arraytools/SIK.git (fetch)
git checkout master
origin https://[email protected]/arraytools/SIK.git (push)
nano test.rb
brb@brb-P45T-A:~/github/SIK$ git remote add pb https://github.com/paulboone/ticgit
git commit -a -m 'made other changes'
brb@brb-P45T-A:~/github/SIK$ git remote -v
git log --oneline --decorate --graph --all
origin https://[email protected]/arraytools/SIK.git (fetch)
</syntaxhighlight>
origin https://[email protected]/arraytools/SIK.git (push)
 
pb https://github.com/paulboone/ticgit (fetch)
Note that when you run '''git pull''' without specify the branch name (eg gh-pages from the current local branch), it won't pull the latest from another branch (eg master).
pb https://github.com/paulboone/ticgit (push)
 
brb@brb-P45T-A:~/github/SIK$ git fetch [remote-name]
=== Git worktree ===
brb@brb-P45T-A:~/github/SIK$ git fetch pb
[https://masalmon.eu/2024/01/23/git-worktree/ Load different R package versions at once with git worktree]
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
=== git checkout ===
* remote origin
* https://guide.freecodecamp.org/git/git-checkout/. It compares "git checkout -b" and "git checkout -B".
  Fetch URL: https://arraytools@github.com/arraytools/SIK.git
** '''git checkout -b NEW-BRANCH-NAME''' will create and checkout out a new branch.
  Push  URL: https://arraytools@github.com/arraytools/SIK.git
** '''git checkout -B BRANCH-NAME START-POINT''' will checkout a New Branch or Reset a Branch to a Start Point.
  HEAD branch: master
** <span style="color: red">Generally, Git won’t let you checkout another branch unless your working directory is clean, because you would lose any working directory changes that aren’t committed.</span> You have three options to handle your changes: 1) trash them, 2) commit them, or 3) stash them.
  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
==== Get the short Git version hash of HEAD ====
* remote pb
<pre>
  Fetch URL: https://github.com/paulboone/ticgit
$ git rev-parse --short HEAD
  Push  URL: https://github.com/paulboone/ticgit
38733fd
  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
# Compare to
brb@brb-P45T-A:~/github/SIK$ git remote -v
$ git log --oneline
origin https://[email protected]/arraytools/SIK.git (fetch)
</pre>
origin https://[email protected]/arraytools/SIK.git (push)
</syntaxhighlight>
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, tracking branches ===
==== Detached head/HEAD detached from xxxxxxx when you check out from a commit ====
https://git-scm.com/book/ch3-5.html
* When you run '''git checkout XXX''' (where XXX represents the '''commit hash''' or commit ID), the following happens:
** Your working directory and staging area (index) are updated to match the state of the specified commit.
** All files are reverted to the state they were in at that commit.
** You are now in a '''detached HEAD''' state, meaning you’re not on any branch but directly on the commit.
* Before we run "git checkout", use "git status" to make sure the current local repository is clean.
* Better no to run "git checkout origin/XXX" or "git checkout SHA1" or "git checkout TAG". The right way is to create a local branch and then switch to that. '''git checkout -b branchXYZ origin/branchXYZ'''.
* [https://www.loekvandenouweland.com/content/head-detached-from-origin-master.html HEAD detached from origin/master].
* [https://www.atlassian.com/git/tutorials/using-branches/git-checkout Detached HEADS]. '''When it points to a branch, Git doesn't complain, but when you check out a commit, it switches into a “detached HEAD” state.''' The point is, <span style="color: red">your development should always take place on a branch—never on a detached HEAD.</span>
* [https://www.cloudsavvyit.com/14012/how-do-you-fix-a-detached-head-in-a-git-repository/ How Do You Fix a “Detached HEAD” in a Git Repository?]


Remote references are references (pointers) in your remote repositories, including branches, tags, and so on.
See [http://stackoverflow.com/questions/10228760/fix-a-git-detached-head Fix a Git detached head?]


'''Pushing''':
(2020-03-23) I must made some mistake. See the following and the solution is by following the suggestion from the on-screen message.
<syntaxhighlight lang="bash">
{{Pre}}
git ls-remote (remoteName)
git checkout XXXXXXX
git remote show (remoteName) # add RSA key fingerprint if the git is using the ssh protocol
cp myfile /tmp/myfile
git checkout origin/master # begin to mess up; why git allows this action?
nano myfile # merge something from the old file '/tmp/myfile'
git commit  # repeat the commit action again for another change
git status  # HEAD detached from origin/master
git checkout master
# Warning: you are leaving 2 commits behind, not connected to
any of your branches:
# If you want to keep them by creating a new branch, this may be a good time
to do so with:


git push origin serverfix  # serverfix is a branch name
# git branch <new-branch-name> 854c654
</syntaxhighlight>


'''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
# Switched to branch 'master'
<syntaxhighlight lang="bash">
# Your branch is up to date with 'origin/master'.
git config --global credential.helper cache
 
</syntaxhighlight>
# Solution 1:
git branch branch0323 854c654
git branch # check my current branch
# Solution 2:
git checkout -b branch0323


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 merge branch0323
<syntaxhighlight lang="bash">
# Done
git fetch origin
</pre>
git checkout -b serverfix origin/serverfix
</syntaxhighlight>


'''Tracking Branches''':
(suggested by bing chat)
{{Pre}}
# Discard changes
git reset  # Unstage all changes that have been added to the index (i.e., that are set to be committed)
git checkout -- .  # To revert all unstaged changes (i.e., changes that you’ve made but have not yet added to the index)
git status        # Don't worry about untracked files


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.
git checkout HEX  # HEAD -> HEX
# You are in 'detached HEAD' state. You can look around, make experimental
# changes and commit them, and you can discard any commits you make in this
# state without impacting any branches by switching back to a branch.
git log
git checkout main  # HEAD -> main
</pre>


When you clone a repository, it creates a ''master'' branch that tracks ''origin/master''. However you can set up other tracking branches if you wish - ones that track branches on other remotes, or don't track the ''master'' branch.
==== Good practice ====
See [[#Get_an_old_commit_and_merge_some_of_its_code_to_the_current_code|Get an old commit and merge some of its code to the current code]].


FAQ: [http://stackoverflow.com/questions/10002239/difference-between-git-checkout-track-origin-branch-and-git-checkout-b-branch git checkout --track origin/branch VS git checkout -b branch origin/branch]. Basically '-b' allows a different branch name.
=== Basic merging and conflicts ===
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
git checkout --track origin/serverfix
git checkout -b iss53
# shorthand for
# git branch iss53
# git checkout iss53


# if the branch name you're trying to checkout (a) does not exist and (b) exactly
nano index.html
# matches a name on only one remote, Git will create a tracking branch for you
git commit -a -m 'added a new footer [issue 53]'
git checkout serverfix
git checkout master


# set up a local branch with a different name than the remote branch
git checkout -b hotfix
git checkout -b sf origin/serverfix # your local branch sf will auto pull from origin/serverfix
nano index.html
git commit -a -m 'fixed the broken email address'


# if you ALREADY have a local branch and want to set it to a remote branch
git checkout master  # step 1. Move back to master for merging
# you just pulled down, or want to change the upstream branch you're tracking.
git merge hotfix    # step 2. Merge the hotfix branch into the master
git branch -u origin/serverfix
git branch -d hotfix # step 3. Delete the branch


# see what tracking branches you have set up in your local repo
git checkout iss53
git branch -vv
nano index.html
git commit -a -m 'finished the new footer [issue 53]'
</syntaxhighlight>
</syntaxhighlight>


'''Pulling''':
'''Basic Merging:'''
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
git pull 
git checkout master
# Equivalent to two actions
git merge iss53
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
</syntaxhighlight>
</syntaxhighlight>
See [https://git-scm.com/docs/git-fetch git fetch] and [https://git-scm.com/docs/git-merge git-merge].


'''Deleting Remote Branches''':
'''Basic merge conflicts''':
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
git push origin --delete serverfix
git merge iss53
git status # Look at the standard conflict-resolution markers to the top of files
 
git mergetool
git status
</syntaxhighlight>
</syntaxhighlight>


=== Rebasing - integrate changes from 2 branches ===
=== push the new branch to remote ===
In Git, there are two main ways to integrate changes from one branch into another: the '''merge''' and  the '''rebase'''.
We can have a branch on our local computer only. We can also have a branch that is shared on the remote.


== Detached head/HEAD detached from xxxxxxx ==
<syntaxhighlight lang="bash">
I got the above message when I run
# make sure we are at the right branch
# Gitgui -> checkout -> Revision Expression (some previous version)
$ git branch -a
# Gitgui -> checkout -> Revision Expression (the latest version)
  master
# Git Bash -> git status
* newbranch
  remotes/bitbucket/master
  remotes/origin/HEAD -> origin/master
  remotes/origin/master
$ git push -u bitbucket newbranch # '-u' is to add the tracking information
$ git status
On branch newbranch
Your branch is up-to-date with 'bitbucket/newbranch'.


At this time, I cannot continue as usual to make changes to files and do commits.
nothing to commit, working directory clean
 
The solution is run
<syntaxhighlight lang='bash'>
git checkout master
</syntaxhighlight>
</syntaxhighlight>
If another machine runs ''git pull'', it will get the new branch. The result can be seen by ''gitk --all''.


See [http://stackoverflow.com/questions/10228760/fix-a-git-detached-head this post] from stackoverflow.com.
=== pull ===
Suppose we are at the 'newbranch'. Some files are modified and committed to 'newbranch' (these actions are only done locally).  


== git merge ==
If someone modified files and committed to the 'master' branch, then when we run ''git pull'' (keep it in mind that we are still on ''newbranch'') the files we just modified & committed OR even any files aren't affected since ''git pull'' is pulling files from the 'master' branch.  
See an [https://lostechies.com/joshuaflanagan/2010/09/03/use-gitk-to-understand-git/ example] of merging a temporary branch with the master branch in the local repository.  


[https://lostechies.com/joshuaflanagan/2010/09/03/use-gitk-to-understand-git-merge-and-rebase/ 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.
If we use the '''gitk --all''' or '''git log --graph --all --oneline --decorate''' command, we may see (remote has an orange background color, branch has a green background color, a yellow dot marks the current HEAD)
* remotes/bitbucket/newbranch
* remotes/bitbucket/master
* newbranch (local)
* master   (local)


=== Merge conflict 1 ===
These 4 branches could be on different nodes. Note. ''gitk'' output is easy to read but ''git log'' gives the SHA information. The screenshot from ''git log'' below does NOT use the ''--decorate'' option.
[[#git_push_error_.28file_is_created_by_Windows_but_edited_by_Linux.29.2C_Your_branch_is_ahead_of_.27origin.2Fmaster.27|Your branch is ahead of 'origin/master']]


=== Merge conflict 2 ===
[[File:Git branch.png|250px]]
[[#git_push_error_.28both_clients_are_linux.29.2C_Your_branch_and_.27origin.2Fmaster.27_have_diverged|Your branch and 'origin/master' have diverged]]


=== Manual merge and auto merge ===
=== Branch management ===
If a file looks like
<syntaxhighlight lang="bash">
<pre>
git branch
line1
git branch -v          # see the last commit on each branch
line2
git branch -vv        # see the last commit and what remote branch a local branch is tracking?
line3
git branch --merged    # Filter the list to branches that you have merged into the branch you're currently on
line4
git branch --no-merged # See the branches that contain work you haven't yet merged in
</pre>
git branch -a          # show all remotes' branches too
(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.
git branch -d testing
</syntaxhighlight>


(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.
=== Branch workflows ===
[https://git-scm.com/book/en/v2/Git-Branching-Branching-Workflows 3.4 Git Branching - Branching Workflows]


Whether there are conflicts or not, the practice is to run
=== Inspect a Remote ===
# '''git fetch'''
https://git-scm.com/book/ch2-5.html
# '''git diff master origin/master''' (- part is from master, + part is from origin/master)
<syntaxhighlight lang='bash'>
# '''git merge origin/master''' (possibly need to run '''nano FILENAME + git add + git commit''' or run '''git mergetool + git commit''' if there is a conflict, OR a text editor will be opened to let you enter the commit message if there is no any conflict). Use ''git config --global core.editor nano'' to set the default text editor if this was not done yet; see [https://git-scm.com/book/en/v2/Customizing-Git-Git-Configuration Git configuration].  
brb@brb-P45T-A:~/github/SIK$ git remote
# '''git push'''.  
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


Note that
brb@brb-P45T-A:~/github/SIK$ git remote show origin
* If we are using ''git pull'' instead of '''git fetch + git merge''', we will be directed to the nano editor to enter a commit message if there are no conflicts; however, if we use ''git fetch'', we will NOT be directed to nano editor).
* 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)


* If we directly run ''git push'' (even on non-conflict file) without running '''git pull''', we will be welcome with the message
brb@brb-P45T-A:~/github/SIK$ git remote show pb
<syntaxhighlight lang='bash'>
* remote pb
brb@brb-P45T-A:~/github/toy$ git add .
  Fetch URL: https://github.com/paulboone/ticgit
brb@brb-P45T-A:~/github/toy$ git commit -m "add a line from p45t-a"
  Push URL: https://github.com/paulboone/ticgit
[master 3b69283] add a line from p45t-a
  HEAD branch: master
1 file changed, 1 insertion(+)
  Remote branches:
brb@brb-P45T-A:~/github/toy$ git push
    master tracked
To https://arraytools@github.com/arraytools/toy.git
    ticgit tracked
  ! [rejected]        master -> master (fetch first)
  Local ref configured for 'git push':
error: failed to push some refs to 'https://arraytools@github.com/arraytools/toy.git'
    master pushes to master (local out of date)
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
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)
</syntaxhighlight>
</syntaxhighlight>
This goes back to the same problem mentioned above in [[#Merge_conflict_2|Merge conflict 2]].
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://arraytools@github.com/arraytools/SIK.git (fetch)
origin https://[email protected]/arraytools/SIK.git (push)
 
=== Remote branches, tracking branches ===
https://git-scm.com/book/ch3-5.html


Summary:
Remote references are references (pointers) in your remote repositories, including branches, tags, and so on.
* 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:
'''Pushing''':
* Before going to run '''git merge''', run '''git checkout master''' first.
<syntaxhighlight lang="bash">
* Instead of running '''git pull''', we'd better run '''git fetch''' & '''git merge origin/master''' if the bash code was run in a background.
git ls-remote (remoteName)
git remote show (remoteName)  # add RSA key fingerprint if the git is using the ssh protocol


See also http://www.gitguys.com/topics/merging-branches-without-a-conflict/
git push origin serverfix  # serverfix is a branch name
</syntaxhighlight>


== Practices ==
'''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
Suppose we want to experiment on a new plan, we can create a new branch ('newbranch') in our local repository, merge ''newbranch'' to ''master'' and push to the remote.
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
git branch newbranch    # step 1 create a new branch called 'newbranch'
git config --global credential.helper cache
git checkout newbranch  # step 2 switch to the 'newbranch' branch
nano FILENAME          # step 3 modify some files
git commit              # step 4 commit changes to newbranch
git checkout master    # step 5 check out the master branch
git branch -a          # (optional) verify we are on the master branch
git merge newbranch    # step 6 merge newbranch to master
git push origin master  # step 7 push (local) master to remote/master
</syntaxhighlight>
</syntaxhighlight>


Question: If we have multiple remotes, how do we know if the local master is the same as the origin/master or origin2/master? Answer: git diff.
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'':
<syntaxhighlight lang="bash">
git fetch origin
git checkout -b serverfix origin/serverfix
</syntaxhighlight>
 
'''Tracking Branches''':


== git rebase ==
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. Tracking's advantage is to save our typing. Without tracking information, we need to specify the remote branch name when we want to interact with it (git fetch, git push, git pull).
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.
When you clone a repository, it creates a ''master'' branch that tracks ''origin/master''. However you can set up other tracking branches if you wish - ones that track branches on other remotes, or don't track the ''master'' branch.
* 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.
If you create a new branch on your local repository, this new branch by default has no tracking information to a remote branch. So when we use "git push origin newBranch" (no "-u"), it does not add the tracking info. We can use '''--set-upstream-to''' or '''-u''' option when we use "git branch" to set up the tracking information; see "git help branch". One example: ''git branch -u origin/newBranch newBranch''. Use '''cat .git/config''' to double check.


The good approach (as in that example) is
FAQ: [http://stackoverflow.com/questions/10002239/difference-between-git-checkout-track-origin-branch-and-git-checkout-b-branch git checkout --track origin/branch VS git checkout -b branch origin/branch]. Basically '-b' allows a different branch name.
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
git checkout issue123
git checkout --track origin/serverfix
git rebase master
 
git checkout master
# if the branch name you're trying to checkout (a) does not exist and (b) exactly
git merge issue123
# matches a name on only one remote, Git will create a tracking branch for you
git branch -d issue123
git checkout serverfix
git push origin master
</syntaxhighlight>


== .ref directory ==
# set up a local branch with a different name than the remote branch
<syntaxhighlight lang='bash'>
git checkout -b sf origin/serverfix # your local branch sf will auto pull from origin/serverfix
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
# if you ALREADY have a local branch and want to set it to a remote branch
.git/refs
# you just pulled down, or want to change the upstream branch you're tracking.
├── heads
git branch -u origin/serverfix
│   └── master
├── remotes
│   └── origin
│      ├── HEAD
│      └── master
└── tags


brb@brb-P45T-A:~/github/toy$ ls .git/objects/
# see what tracking branches you have set up in your local repo
03  0f  28  39  47  52  5f  65  6e  8c  ad  b7  ce  da  e5  f2 ff
git branch -vv
07  12  29  3b  49  53  60  67  6f  9a  b1  bb  cf  dc  e9  f5  info
</syntaxhighlight>
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
'''Pulling''':
0c  1b  37  45  51  58  64  6d  8a  aa  b5  c8  d6  e2  f1  fe
<syntaxhighlight lang="bash">
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
</syntaxhighlight>
See [https://git-scm.com/docs/git-fetch git fetch] and [https://git-scm.com/docs/git-merge git-merge].


brb@brb-P45T-A:~/github/toy$ ls .git/branches/
'''Deleting Remote Branches''':
brb@brb-P45T-A:~/github/toy$ ls .git/info/
<syntaxhighlight lang="bash">
exclude
git push origin --delete serverfix
brb@brb-P45T-A:~/github/toy$ ls .git/logs
HEAD  refs
</syntaxhighlight>
</syntaxhighlight>


== Tagging ==
=== Rebasing - integrate changes from 2 branches ===
https://git-scm.com/book/en/v2/Git-Basics-Tagging
In Git, there are two main ways to integrate changes from one branch into another: the '''merge''' and  the '''rebase'''.
<syntaxhighlight lang='bash'>
$ git tag


# Create annotated tags
=== Checkout previous checkout's commit ===
$ git tag -a v1.4 -m "my version 1.4"  
[https://www.smashingmagazine.com/make-life-easier-when-using-git/ How To Make Life Easier When Using Git]
$ git tag
<pre>
v1.4
git checkout -
$ git show v1.4
</pre>
 
== diff between two revisions ==
<syntaxhighlight lang='bash'>
git diff <revision_1>:<file_1> <revision_2>:<file_2>
 
# Better to run git config --global diff.tool meld BEFORE
git difftool <revision_1> <revision_2> # Warning: it will open each file one by one.
                                      # It is not a good idea if many files have changed.
                                      # Better to use "-d" or "--dir-diff" option
git difftool <revision_1> <revision_2> FILENAME -y
                                        # just compare the file <FILENAME>
 
git diff master..test                  # between the tips of the two branches
 
git diff origin/master..master          # useful if origin/master is behind the local's master
 
git diff test                          # between your current working directory and the
                                        # (remote) snapshot on the 'test' branch.


# Tagging Later
git diff --name-only SHA1 SHA2          # show only file names
$ git log --pretty=online
$ git tag -a v1.2 9fceb02
</syntaxhighlight>


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 diff --name-only HEAD~10 HEAD~5    # between the tenth latest commit and the fifth latest
<syntaxhighlight lang='bash'>
$ git push origin v1.5
$ git push origin --tags # push up all tags at once
</syntaxhighlight>
</syntaxhighlight>


== Rename a remote repository ==
=== Monitor/find files that have been changed since last pull ===
# Go to github.com, open the project and click Settings button on the left-bottom corner. Change the repository name on top.
<syntaxhighlight lang="bash">
# On local machine, rename the directory. Go to the directory. Issue
git branch
<syntaxhighlight lang='bash'>
git fetch origin master    # or git fetch on Windows
git remote -v
git diff --name-only origin/master
</syntaxhighlight>
 
to get the ULR for the current working copy. Suppose the url is ''git@github.com:someuser/someproject.git''. Now issue the following command to change to the new repository
git log                    # local
<syntaxhighlight lang='bash'>
git log origin/master      # remote repository
git remote set-url origin [email protected]:someuser/newprojectname.git
 
$ 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
</syntaxhighlight>
</syntaxhighlight>


Suppose we have added ssh key to git server and we want to use ssh key/protocol to automatically access the server instead of entering the password (https protocol). See
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/ <span style="color: #FFD700">yellow circle</span>) is 2 commits behind the remote repository (remotes/origin/master w/ <span style="color: blue">blue circle</span>).
* [https://confluence.atlassian.com/bitbucket/set-up-ssh-for-git-728138079.html bitbucket]
* [https://help.github.com/articles/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent/#platform-linux github]
<syntaxhighlight lang='bash'>
$ # the REMOTE below could be 'origin' or any name you define
$ git remote show REMOTE
$ git remote set-url REMOTE ssh://[email protected]/USERNAME/REPOS.git
$ git remote show REMOTE
$ git status  # show local branch is update-to-date with REMOTE/BRANCH.
</syntaxhighlight>


== setting up SSH access on the server side ==
[[File:Gitk2.png|200px]] [[File:Gitk.png|200px]]
Follow the instruction on [http://git-scm.com/book/en/Git-on-the-Server-Setting-Up-the-Server git-scm.com]. It works.


I tested it by
=== git difftool, mergetool & meld ===
# create a git account (called 'git') on my host machine.  
[https://stackoverflow.com/questions/34119866/setting-up-and-using-meld-as-your-git-difftool-and-mergetool Setting up and using Meld as your git difftool and mergetool]
# 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.
[https://stackoverflow.com/questions/2006032/view-differences-of-branches-with-meld View differences of branches with meld?]
# 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:
'''git diff''' can only show the differences on the terminal. '''git difftool''' will show the difference on the GUI program.
* 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.


== Create a git server ==
'''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 [http://git-scm.com/docs/git-difftool here].
[https://www.howtoforge.com/tutorial/ubuntu-git-server-installation/ How to Install HTTP Git Server with Nginx on Ubuntu 18.04 LTS]


=== Create a git server (github like w/ web interface) ===
To compare two revisions (sha1sum, branch name)
If we like to create a github-like web interface, check out [https://about.gitlab.com/ GitLab]. See
<syntaxhighlight lang='bash'>
* [https://www.howtoforge.com/tutorial/how-to-install-gitlab-on-debian-8/ How to Install Gitlab on Debian 8 (Jessie)],  
git difftool <revision_1> <revision_2>
* [https://www.linux.com/learn/how-run-your-own-git-server How to Run Your Own Git Server]. This includes the installation of postfix for sending emails.
</syntaxhighlight>
It will open the first file in Meld. After we close the first file, it will launch the 2nd file in Meld, and so on.


Below is my note
The current '''meld''' has a new tool to compare git versions. New comparison > Version control. Select a git directory. It will show the differences of the local master and the current folder (left = local master, right = current dir). I can also launch the comparison from the command line:
# https://about.gitlab.com/downloads/ contains steps of setting up Gitlab.
<syntaxhighlight lang='bash'>
# By default, the domain name you have entered in setting up gitlab will be the URL you will use to access gitlab.
git difftool -d master  # '-d' means a directory comparison
# Use the recommended method to install gitlab. Nginx will be installed as an http server.
                        # left = current master, right = current dir
# 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.
# OR
# User's password is used to access GitLab web interface only. It is not used for pushing commits.
git branch myBranch SHA1
# 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'.
git difftool -d myBranch # compare myBranch with my current branch
# 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'.
                        # left = myBranch, right = current master
# The username will affect path to all personal projects; e.g. [email protected]:newuser/test2.git.
</syntaxhighlight>
 
To create a (temporary) branch, use ''git branch -b BRANCHNAME''. To delete a (temporary) branch, use ''git branch -D BRANCHNAME''.


[[File:Gitlab2.png|100px]]  [[File:Gitlab1.png|100px]]  [[File:Gitlab3.png|100px]]
It may be helpful to run the following too
<syntaxhighlight lang='bash'>
git config --global diff.tool meld
</syntaxhighlight>


[https://www.howtoforge.com/tutorial/how-to-install-gitlab-with-postgresql-and-nginx-on-ubuntu-15-04/ How to Install Gitlab with PostgreSQL and Nginx on Ubuntu 15.04] from howtoforge.com.
=== [http://meldmerge.org/ Meld] and [http://diffuse.sourceforge.net/about.html Diffuse] ===
[http://www.bojankomazec.com/2019/10/how-to-install-meld-on-ubuntu.html How to build Meld 3.20 on Ubuntu]. Note when we install meld using apt, it is installed under '''/usr/bin/meld'''.
<syntaxhighlight lang='bash'>
git clone https://gitlab.gnome.org/GNOME/meld.git


=== Gitolite (favored by Ubuntu) ===
cd meld
* https://help.ubuntu.com/lts/serverguide/git.html#git-installing-gitolite
git checkout meld-3-20
* https://www.digitalocean.com/community/tutorials/how-to-use-gitolite-to-control-access-to-a-git-server-on-an-ubuntu-12-04-vps
python3 setup.py install --prefix=/usr


This approach involves the following steps
sudo apt update
# Installing a gitolite server
sudo apt upgrade
# Gitolite configuration
sudo apt install intltool
# Managing gitolite users and repositories
sudo apt install libxml2-utils
# Using your server
sudo apt install libglib2.0-dev-bin


Not sure about any advantages of this approach?
sudo apt install libglib2.0-dev
sudo apt install libgirepository1.0-dev
sudo apt install libcairo2-dev
pip3 install pycairo
pip3 install PyGObject


== Graphical tool ==
sudo python3 setup.py install --prefix=/usr
* http://askubuntu.com/questions/227554/what-are-some-gui-clients-for-git
meld
</syntaxhighlight>


=== Command line approach ===
To make meld to be in the right click menu, follow
<syntaxhighlight lang='bash'>
* http://askubuntu.com/questions/112164/how-can-i-diff-two-files-with-nautilus
$ git log --oneline --decorate --graph --all
* http://superuser.com/questions/307927/right-click-files-to-meld
*   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
</syntaxhighlight>


Another method of comparing two files without using the 'browse' button will be to use the command line.


=== [http://git-scm.com/docs/gitk gitk] and [https://git-scm.com/docs/git-gui git-gui] ===
The 'nautilus-compare' program does not work from my testing on Ubuntu 14.04.
* http://lostechies.com/joshuaflanagan/2010/09/03/use-gitk-to-understand-git/
* http://git-scm.com/download/gui/linux
<syntaxhighlight lang='bash'>
sudo apt-get update; sudo apt-get install gitk
git clone git@github.com:joshuaflanagan/gitk-demo.git


cd gitk-demo
'''Some thoughts'''
gitk --all  # show all refs (branches, tags, etc.)  
* I install kdiff3 (<2 MB to download) and the 'File' -> 'Reload' (F5) function there works though it shows an extra space on the place I modified.
</syntaxhighlight>
* [http://www.scootersoftware.com/download.php Beyond Compare] (commercial $30/$60, trial version can be downloaded)
* '''[http://diffuse.sourceforge.net/download.html diffuse]'''. When I modified a file, diffuse can detect a change and ask me to reload the file. I am using the apt-get to install the software and the version number is 0.4.7 (2014). To copy lines from left panel to right panel, use 'Ctrl + Shift + >' or the '''Copy Selection Right''' icon. One drawback is it cannot save the history from the GUI though we can use the command line to include the file names in the arguments.
* Alternatively we can use WinMerge on Linux. To do that, [https://wiki.winehq.org/Ubuntu install Wine] on Ubuntu. [http://winmerge.org/?lang=en Download Winmerge] (I am using 2.14.0). Then on a terminal, run the following command. At the end, WinMerge will be launched. WinMerge can also be launched from Mint Menu -> Wine -> WinMerge. One problem is I cannot increase the font size (though acceptable) from View -> Select Font.
{{Pre}}
wine WinMerge-2.14.0-Setup.exe
</pre>


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.  
=== git-split-diffs ===
[https://github.com/banga/git-split-diffs git-split-diffs]. This currently requires node version 12 or newer to run.


'''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.
=== Pull and overwrite local files ===
 
If we want to run git pull and also overwrite possibly changed local file, we use (see [http://stackoverflow.com/questions/1125968/force-git-to-overwrite-local-files-on-pull stackoverflow])
It looks these 2 gui tools are sufficient enough.
<syntaxhighlight lang="bash">
git fetch --all
git reset --hard origin/master
</syntaxhighlight>
 
=== 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 [http://stackoverflow.com/questions/2432579/git-your-branch-is-ahead-by-x-commits this post]. The solution is to run '''git fetch''' after '''git pull'''.


=== [https://www.gitkraken.com/git-client GitKraken] ===
=== This repository currently has approximately XXXX loose objects ===
[https://blog.axosoft.com/top-developer-tools-2019/ #1] of Top 20 Dev Tools for 2019
http://stackoverflow.com/questions/21457407/git-gui-perpetually-getting-this-repository-currently-has-approximately-320-lo
<syntaxhighlight lang="bash">
git gc --aggressive
</syntaxhighlight>


=== Others  ===
=== git commit -am ===
* [http://digilander.libero.it/mcostalba/ QGit] - QGit is a git GUI viewer built on Qt/C++.
works only for simple edits. It does not work for renaming files, etc.
* [http://git-cola.github.io/ git-cola] ???
* gitg
* Giggle - Similar to gitk
* SmartGit - Support push, pull, fetch


== Navigating your Git History; git grep, git show, git log ==
For initial file commit, use '''git add -A''' and '''git commit -m XXX'''. ''git commit -a'' will commit all changes to '''tracked''' files. But untracked files will not be committed at any point. Read [https://stackoverflow.com/questions/18551294/git-commit-am-does-not-work-on-initial-commit-why Git commit -am does not work on initial commit. Why?].
* [https://ieftimov.com/learn-your-tools-navigating-git-history Navigating your Git History]
** '''git log -S 'some words' '''   # search for the string in the code and show the logs
* [https://stackoverflow.com/questions/17557684/is-it-better-to-use-git-grep-than-plain-grep-if-we-want-to-search-in-versioned-s Is it better to use git grep than plain grep if we want to search in versioned source code?]
** '''git grep 'some words' '''    # search for the string in the code or filenames and show the code with color highlight


== '''Git Tips''' ==
=== git diff HEAD ===
=== old mode new mode ===
This command shows the differences between the current working directory (which represents the current code) and the '''most recent commit (i.e., HEAD)'''.
See [http://stackoverflow.com/questions/1257592/how-do-i-remove-files-saying-old-mode-100755-new-mode-100644-from-unstaged-cha this post]
<syntaxhighlight lang='bash'>
git config core.filemode false
</syntaxhighlight>


=== Temporarily move to a branch and then move back ===
=== git diff --staged ===
 
=== git diff -- file.a file.b ===
 
=== git checkout -- FileName ===
to recover a modified/deleted file where -- is a linux notation, not specific to git. See [https://stackoverflow.com/a/6561160 Difference between "git checkout <filename>" and "git checkout -​- <filename>"].
<syntaxhighlight lang='bash'>
<syntaxhighlight lang='bash'>
# suppose we have 3 commits so far and we are at commit 3 now.
rm FileName
git status
git pull  # do nothing
git log                        # show 3 commits
git status # still miss 'FileName'
git checkout sha1_commit_1    # move to commit 1
git checkout FileName
git log                        # only show 1 commit
git checkout master            # go back to the original 3 commits
git status
</syntaxhighlight>
</syntaxhighlight>


=== git log on a specific file ===
The following examples give a good clarification.
<syntaxhighlight lang='bash'>
<syntaxhighlight lang='bash'>
git log FILENAME
git checkout README    # would normally discard uncommitted changes
                        # to the _file_ "README"
 
git checkout master    # would normally switch the working copy to
                        # the _branch_ "master"


# to see the difference/patch in each commit
git checkout -- master  # discard uncommitted changes to the _file_ "master"
git log -p FILENAME
</syntaxhighlight>
</syntaxhighlight>


=== git log message is too long ===
=== git reset HEAD FileName ===
Normally when we use 'git log' command, long log messages get truncated.
to un-stage a file


Use the following to view the complete log messages instead of truncated log messages.
=== Rewrite a commit ===
<syntaxhighlight lang='bash'>
ps. This is different from the case of [https://taichimd.us/mediawiki/index.php/Github#Pull_and_overwrite_local_files Pull and overwrite local files]
git log | less
 
Suppose someone made a stupid commit. We want to get a previous version of the code and commit that one.
<syntaxhighlight lang='bash'>
git checkout XXXXXX -- FileName
git commit -am CommitMessage
</syntaxhighlight>
 
===  '''origin''' and nickname ===
<syntaxhighlight lang='bash'>
git remote add NickName https://XXX
git remote
git push -u NickName master
</syntaxhighlight>
</syntaxhighlight>
Common standard is 78 characters. See [http://stackoverflow.com/questions/8824863/show-full-git-commit-message-in-console this] and [http://stackoverflow.com/questions/2119942/how-to-wrap-git-commit-comments this] posts.


=== git push error (file is created by Windows but edited by Linux), Your branch is ahead of 'origin/master' ===
== git merge ==
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.
https://www.atlassian.com/git/tutorials/using-branches/git-merge
 
See an [https://lostechies.com/joshuaflanagan/2010/09/03/use-gitk-to-understand-git/ example] of merging a temporary branch with the master branch in the local repository.
 
[https://lostechies.com/joshuaflanagan/2010/09/03/use-gitk-to-understand-git-merge-and-rebase/ 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.


If I forget to run git pull and after running git push, we will get something like if there is a conflict.
[https://www.lynda.com/Git-tutorials/Resolve-merge-conflicts/5030980/2221745-4.html Resolving merge conflict] from lynda.com
<pre>
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
=== Merge does not delete a local branch ===
# On branch master
Running '''git merge''' will not delete any local branches, even if the corresponding branch on the remote repository has been deleted. The '''git merge''' command is used to integrate changes from one branch into another, it does not delete branches.
# Your branch is ahead of 'origin/master' by 1 commit.
 
#
If a branch has been deleted from the remote repository, you can delete the corresponding local branch manually using the '''git branch -d <branchname>''' command (or '''git branch -D <branchname>''' to force delete).
nothing to commit, working directory clean
 
However, if you want your local repository to reflect the state of the remote repository, including the deletion of remote branches, you can use the git fetch command with the --prune option: '''git fetch --prune'''. This command will delete any tracking branches in your local repository that no longer exist on the remote repository.
 
Let’s say I’m in a branch ‘b’ that has been deleted from the remote. If I am currently on branch ‘b’, running ‘git merge’ will not perform any merge and will issue a message: ‘fatal: No remote for the current branch.’ I need to switch to the master branch in order to run ‘git merge’.
 
=== Merge a local branch to the local master ===
<pre>
git checkout master
git merge newBranch
</pre>
</pre>


Follow the suggestion from [http://stackoverflow.com/questions/10298291/cannot-push-to-github-keeps-saying-need-merge this post] to use git pull for git to do merge. It does not work in this case.
=== Merge a remote branch to the local master ===
<pre>
<pre>
C:\Users\XXX\Documents\GitHub\toy [master]> git pull origin master
git checkout master
remote: Counting objects: 3, done.
git fetch
remote: Compressing objects: 100% (2/2), done.
git merge origin/master
remote: Total 3 (delta 0), reused 3 (delta 0), pack-reused 0
</pre>
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
=== Merge conflict 1 ===
[[#git_push_error_.28file_is_created_by_Windows_but_edited_by_Linux.29.2C_Your_branch_is_ahead_of_.27origin.2Fmaster.27|Your branch is ahead of 'origin/master']]


    Directory: C:\Users\XXX\Documents\GitHub\toy
=== Merge conflict 2 ===
[[#git_push_error_.28both_clients_are_linux.29.2C_Your_branch_and_.27origin.2Fmaster.27_have_diverged|Your branch and 'origin/master' have diverged]]


Mode                LastWriteTime    Length Name
=== Manual merge and auto merge ===
----                -------------    ------ ----
If a file looks like
-a---          5/3/2016  4:33 PM        102 README.md
<pre>
 
line1
C:\Users\XXX\Documents\GitHub\toy [master +0 ~0 -0 !1 | +0 ~0 -0 !1]> git status
line2
# On branch master
line3
# Your branch is ahead of 'origin/master' by 1 commit.
line4
#
# 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")
</pre>
</pre>
(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.


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.
(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.  
<syntaxhighlight lang='bash'>
$ file README.md
README.md: ASCII text, with CR line terminators.  
</syntaxhighlight>


Since we already run ''git pull'', it won't work to run ''git reset --soft HEAD~'' to undo a commit. Two solutions
Whether there are conflicts or not, the practice is to run  
* '''git fetch origin; git reset --hard origin/master''' to [http://stackoverflow.com/questions/19864934/git-your-branch-and-origin-master-have-diverged-how-to-throw-away-local-com throw away my local modified file] OR
# '''git fetch'''
* '''git reset --hard HEAD''' to undo ''git pull''; see [http://stackoverflow.com/questions/101752/i-ran-into-a-merge-conflict-how-can-i-abort-the-merge this post]. After that, we can run '''git reset --soft HEAD~''' to undo a commit. See below.
# '''git diff master origin/master''' (- part is from master, + part is from origin/master)
<pre>
# '''git merge origin/master''' (possibly need to run '''nano FILENAME + git add + git commit''' or run '''git mergetool + git commit''' if there is a conflict, OR a text editor will be opened to let you enter the commit message if there is no any conflict). Use ''git config --global core.editor nano'' to set the default text editor if this was not done yet; see [https://git-scm.com/book/en/v2/Customizing-Git-Git-Configuration Git configuration].  
C:\Users\XXX\Documents\GitHub\toy [master +0 ~0 -0 !1 | +0 ~0 -0 !1]> git reset --hard HEAD
# '''git push'''.  
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~
Note that
* If we are using ''git pull'' instead of '''git fetch + git merge''', we will be directed to the nano editor to enter a commit message if there are no conflicts; however, if we use ''git fetch'', we will NOT be directed to nano editor).


C:\Users\XXX\Documents\GitHub\toy [master +0 ~1 -0]> git status
* If we directly run ''git push'' (even on non-conflict file) without running '''git pull''', we will be welcome with the message
# On branch master
<syntaxhighlight lang='bash'>
# Changes to be committed:
brb@brb-P45T-A:~/github/toy$ git add .
#  (use "git reset HEAD <file>..." to unstage)
brb@brb-P45T-A:~/github/toy$ git commit -m "add a line from p45t-a"
#
[master 3b69283] add a line from p45t-a
#      modified:   README.md
1 file changed, 1 insertion(+)
 
brb@brb-P45T-A:~/github/toy$ git push
C:\Users\XXX\Documents\GitHub\toy [master +0 ~1 -0]> cat README.md
To https://[email protected]/arraytools/toy.git
# toy
! [rejected]        master -> master (fetch first)
second commit
error: failed to push some refs to 'https://[email protected]/arraytools/toy.git'
3rd commit (Windows MACHINE)
hint: Updates were rejected because the remote contains work that you do
C:\Users\XXX\Documents\GitHub\toy [master +0 ~1 -0]> git reset HEAD README.md
hint: not have locally. This is usually caused by another repository pushing
Unstaged changes after reset:
hint: to the same ref. You may want to first integrate the remote changes
M      README.md
hint: (e.g., 'git pull ...') before pushing again.
C:\Users\XXX\Documents\GitHub\toy [master +0 ~1 -0]> git status
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
# On branch master
brb@brb-P45T-A:~/github/toy$ git status
# Changes not staged for commit:
On branch master
(use "git add <file>..." to update what will be committed)
Your branch is ahead of 'origin/master' by 1 commit.
#  (use "git checkout -- <file>..." to discard changes in working directory)
  (use "git push" to publish your local commits)
#
#      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
nothing to commit, working directory clean
</syntaxhighlight>
This goes back to the same problem mentioned above in [[#Merge_conflict_2|Merge conflict 2]].


C:\Users\XXX\Documents\GitHub\toy [master]> cat README.md
Summary:
# toy
* 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.
second commit
* 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.


C:\Users\XXX\Documents\GitHub\toy [master]> git status
See also http://www.gitguys.com/topics/merging-branches-without-a-conflict/
# On branch master
nothing to commit, working directory clean
</pre>
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
== git stash ==
* (undo git pull) git fetch; git reset --hard origin/master # OR git reset --hard HEAD
When you have uncommitted changes and want to switch to a specific commit using '''git checkout <commit_id>'''. ''Stashing'' allows you to save your uncommitted changes temporarily. It’s like putting them in a drawer so you can work on something else.
* (undo commit) git reset --soft HEAD~
<syntaxhighlight lang='sh'>
* (undo stage) git reset HEAD Filename
git status # there maybe some modified but not committed files
* (undo change) git checkout -- Filename
git stash # save your changes in a “stash” without committing them.


=== git push error - Permission denied (publickey) ===
git checkout -b <new-branch> <commit-id>
<syntaxhighlight lang='bash'>
          # it'll switch to <new-branch>
odroid@odroid:~/bitbucket/qt$ git push
git branch
Permission denied (publickey).
fatal: Could not read from remote repository.


Please make sure you have the correct access rights
git checkout main
and the repository exists.
git stash apply
</syntaxhighlight>
</syntaxhighlight>
The error only happens if we ssh to the remote server and run git commands. This is done on the bitbucket server.


https://confluence.atlassian.com/bbkb/permission-denied-publickey-302811860.html
To remove a '''local''' branch (a branch on your local machine), use the following command:
'''git branch -d local_branch_name'''.


On my odroid machine,it shows
If the local branch contains unmerged changes or unpushed commits, use -D instead of -d to force deletion: '''git branch -D local_branch_name''' .
<syntaxhighlight lang='bash'>
odroid@odroid:~/bitbucket/qt$ ssh -T [email protected]
logged in as USERNAME.


You can use git or hg to connect to Bitbucket. Shell access is disabled.
== Practices/collaboration workflow ==
odroid@odroid:~/bitbucket/qt$ ssh-add -h
[https://www.lynda.com/Git-tutorials/Collaboration-workflow/5030980/2220760-4.html Collaboration workflow] example from lynda.com
unknown option -- h
usage: ssh-add [options] [file ...]
Options:
  -l          List fingerprints of all identities.
  -E hash    Specify hash algorithm used for fingerprints.
  -L          List public key parameters of all identities.
  -k          Load only keys and not certificates.
  -c          Require confirmation to sign using identities
  -t life    Set lifetime (in seconds) when adding identities.
  -d          Delete identity.
  -D          Delete all identities.
  -x          Lock agent.
  -X          Unlock agent.
  -s pkcs11  Add keys from PKCS#11 provider.
  -e pkcs11  Remove keys provided by PKCS#11 provider.
</syntaxhighlight>
But if I connect to odroid through ssh, I get
<syntaxhighlight lang='bash'>
odroid@odroid:~/bitbucket/qt$ ssh -T [email protected]
Could not open a connection to your authentication agent.
odroid@odroid:~/bitbucket/qt$ ssh-add -h
Could not open a connection to your authentication agent.
odroid@odroid:~$ ssh-add -l
The agent has no identities.
</syntaxhighlight>
The solution is to follow [https://confluence.atlassian.com/bitbucket/troubleshoot-ssh-issues-271943403.html this].
<syntaxhighlight lang='bash'>
odroid@odroid:~$ eval `ssh-agent`  # start the ssh-agent
odroid@odroid:~$ ssh-add ~/.ssh/personalid    # note that personalid is a ssh identity created before
Identity added: /home/odroid/.ssh/personalid (/home/odroid/.ssh/personalid)
odroid@odroid:~$ ssh-add -l
2048 SHA256:1OQfvlXgVl+AyDwjfA0IpHBlgnM2i1dlt0hlHmjJck /home/odroid/.ssh/personalid (RSA)
odroid@odroid:~$ cd bitbucket/qt
odroid@odroid:~/bitbucket/qt$ ssh -T git@bitbucket.org
logged in as USERNAME.


You can use git or hg to connect to Bitbucket. Shell access is disabled.
=== Create a branch from the current HEAD for experiment ===
odroid@odroid:~/bitbucket/qt$ git pull
Suppose we want to experiment on a new plan, we can create a new branch ('newbranch') in our local repository, merge ''newbranch'' to ''master'' and push to the remote.
Already up-to-date.
<syntaxhighlight lang="bash">
</syntaxhighlight>
git checkout master
git fetch
git merge origin/master
 
git branch newbranch      # step 1 create a new branch called 'newbranch'
git checkout newbranch    # step 2 switch to the 'newbranch' branch
                          # We can combine steps 1 & 2 by 'git checkout -b newbranch'
nano FILENAME              # step 3 modify some files, create new files, ...
git add FILENAME
git commit                # step 4 commit changes to newbranch
git checkout master        # step 5 check out the master branch
git branch -a              # (optional) verify we are on the master branch


=== git push error (both clients are linux), Your branch and 'origin/master' have diverged ===
git fetch                 # double check nothing has been committed to the remote
Two clients (mint and vm) running on Linux. The following is coming from vm machine.
<syntaxhighlight lang='bash'>
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
git merge newbranch        # step 6 merge newbranch to master
first line
git push -u origin master  # step 7 push (local) master to remote/master
<<<<<<< HEAD
</syntaxhighlight>
second line edited by vm
Another scenario is we push our local ''newbranch'' to the remote ''newbranch''. Then we can skip steps 5 & 6 and do '''git push -u origin newbranch''' in step 7.
=======
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.
Question: If we have multiple remotes, how do we know if the local master is the same as the origin/master or origin2/master? Answer: git diff.
  (fix conflicts and run "git commit")


Unmerged paths:
=== Get an old commit and merge some of its code to the current code ===
  (use "git add <file>..." to mark resolution)
<pre>
$ git checkout -b testBranch SHA1 (NB. if we want to checkout an old commit, always create a branch)
$ nano someFile
$ git checkout master # OR "git checkout -"
$ git merge testBranch
$ (optional) git branch -d testBranch
</pre>
Or without using "git merge"
<pre>
$ git checkout -b testBranch SHA1 (NB. if we want to checkout an old commit, always create a branch)
$ cp someFile /tmp/
$ git checkout master # OR "git checkout -"
$ meld /tmp/someFile someFile
$ git commit
$ (optional) git branch -d testBranch
</pre>


both modified:     linuxfile
== git rebase ==
https://lostechies.com/joshuaflanagan/2010/09/03/use-gitk-to-understand-git-merge-and-rebase/


no changes added to commit (use "git add" and/or "git commit -a")
The simple '''git merge''' method can make the history very complicated; see and the following cons.
</syntaxhighlight>
* Branching paths in the history can be unnecessarily complicated
[http://stackoverflow.com/questions/2452226/master-branch-and-origin-master-have-diverged-how-to-undiverge-branches master branch and 'origin/master' have diverged, how to 'undiverge' branches'?]
* 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?


The solution now is to run '''git mergetool''' (assume we have install something like meld, opendiff, kdiff3, tkdiff, or xxdiff). See [http://www.gitguys.com/topics/merging-with-a-gui/ Git Mergetool – Merging With a GUI] from gitguys.com.
'''git rebase''' can be used to avoid these issues.


[[File:Gitmergetool.png|200px]]
The good approach (as in that example) is
 
<syntaxhighlight lang="bash">
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).  
git checkout issue123
git rebase master
git checkout master
git merge issue123
git branch -d issue123
git push origin master
</syntaxhighlight>
 
== .ref directory ==
<syntaxhighlight lang='bash'>
<syntaxhighlight lang='bash'>
brb@ubuntu:~/toy$ cat linuxfile
brb@brb-P45T-A:~/github/toy$ ls -l .git
first line
total 60
second line. conflict resolved in vm
drwxrwxr-x  2 brb brb 4096 May  6 11:55 branches
brb@ubuntu:~/toy$ git status
-rw-rw-r--  1 brb brb  13 May  7 16:12 COMMIT_EDITMSG
On branch master
-rw-rw-r--  1 brb brb  273 May  6 11:55 config
Your branch and 'origin/master' have diverged,
-rw-rw-r--  1 brb brb  73 May  6 11:55 description
and have 1 and 1 different commit each, respectively.
-rw-rw-r--  1 brb brb  95 May  7 16:32 FETCH_HEAD
   (use "git pull" to merge the remote branch into yours)
-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


All conflicts fixed but you are still merging.
brb@brb-P45T-A:~/github/toy$ tree .git/refs
  (use "git commit" to conclude merge)
.git/refs
├── heads
│   └── master
├── remotes
│   └── origin
│      ├── HEAD
│      └── master
└── tags


Changes to be committed:
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


modified:   linuxfile
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
</syntaxhighlight>


Untracked files:
== Tagging a release ==
  (use "git add <file>..." to include in what will be committed)
https://git-scm.com/book/en/v2/Git-Basics-Tagging
<syntaxhighlight lang='bash'>
$ git tag  # or add "--list" or add "-l"
$ git tag -l "v2*"  # add a filtering list tags starting with "v2"
$ git tag -l -n    # list tags with annotations


linuxfile.orig
# Create annotated tags
$ git tag -a v1.4 -m "my version 1.4"
$ git tag
v1.4
$ git show v1.4
$ git diff v1.0..v1.1


brb@ubuntu:~/toy$ git commit -m "resolve the conflict in vm"
# Tagging Later
[master f22932b] resolve the conflict in vm
$ git log --pretty=online
brb@ubuntu:~/toy$ git status
$ git tag -a v1.2 9fceb02
On branch master
Your branch is ahead of 'origin/master' by 2 commits.
  (use "git push" to publish your local commits)


Untracked files:
# Delete a tag
  (use "git add <file>..." to include in what will be committed)
$ git tag -d v1.1
</syntaxhighlight>


linuxfile.orig
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.
<syntaxhighlight lang='bash'>
$ git push origin v1.5
$ git push origin --tags # push up all tags at once


nothing added to commit but untracked files present (use "git add" to track)
# Delete remote tags like remote branches
brb@ubuntu:~/toy$ git push
$ git push origin :v1.1  # OR
$ git push -d origin v1.1
</syntaxhighlight>
</syntaxhighlight>
The repository now looks like:


[[File:Toy merged.png|200px]]
Check out tags just like any sha, but it has a profound effect if we later commit something (Detached HEAD state).
<pre>
$ git checkout -b newBranch v1.1
$ git checkout v1.1
</pre>


=== warning: push.default is unset ===
=== Getting Notifications for New GitHub Project Releases ===
Git 2.0 from 'matching' to 'simple'. To squelch this message ...  
* [https://www.raymondcamden.com/2018/06/13/getting-notifications-for-new-github-project-releases Getting Notifications for New GitHub Project Releases]
* [https://stackoverflow.com/a/20840694 Notifications for new Github project releases?]


See [http://stackoverflow.com/questions/13148066/warning-push-default-is-unset-its-implicit-value-is-changing-in-git-2-0 stackoverflow].  
== setting up SSH access on the server side ==
Follow the instruction on [http://git-scm.com/book/en/Git-on-the-Server-Setting-Up-the-Server git-scm.com]. It works.  


'''It only affects what happens when you don't specify which branches you want to push'''; e.g. 'git push' or 'git push origin' instead of 'git push -u origin master'.  
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.


<syntaxhighlight lang='bash'>
Some important points:
$ git push bitbucket
* There is no daemon to be installed. We only need to install the 'git' program on the server.
warning: push.default is unset; its implicit value is changing in
* When a client uses the 'git' command to communicate with the server, it is actually using the 'ssh' to access the server.
Git 2.0 from 'matching' to 'simple'. To squelch this message
* 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.
and maintain the current behavior after the default changes, use:
* 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.


  git config --global push.default matching
== Create a git server ==
* [https://www.cloudsavvyit.com/2510/how-to-set-up-a-private-git-server/ How to Set Up a Private Git Server]
* [https://www.andrewhoog.com/post/howto-setup-a-private-git-server-on-ubuntu-18.04/ HOWTO setup a private git server on Ubuntu 18.04] (including to set the git user’s shell to the '''git-shell''')
<ol>
<li>Install git and git-shell</li>
<syntaxhighlight>
$ sudo apt update
$ sudo apt install git
$ sudo nano /etc/shells  # ADD /usr/bin/git-shell
</syntaxhighlight>
<li>Setup a dedicated (non-sudo) git user</li>
<syntaxhighlight>
$ sudo adduser --disabled-password git
$ sudo su git
$ cd
$ mkdir ~/.ssh && chmod 700 ~/.ssh
$ touch ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys
$ nano ~/.ssh/authorized_keys # add the public keys of any users
                      # you want to access your private git server
$ sudo chsh git -s $(which git-shell)
</syntaxhighlight>
<li>Create individual repo directories</li>
<syntaxhighlight>
$ cd /home/git
$ sudo mkdir ios-backup-extractor.git
$ cd ios-backup-extractor.git && sudo git init --bare && cd ..
$ sudo chown -R git.git ios-backup-extractor.git/
</syntaxhighlight>
<li>Use your private git repo</li>
<syntaxhighlight>
$ git clone git@<IPADDRESS>:<repo-name> ~/git/
$ git remote add origin git@<IPADDRESS>:<repo-name>.git
</syntaxhighlight>
</ol>
* [https://www.howtoforge.com/tutorial/ubuntu-git-server-installation/ How to Install HTTP Git Server with Nginx on Ubuntu 18.04 LTS]


To squelch this message and adopt the new behavior now, use:
=== Create a git server (github like w/ web interface) ===
If we like to create a github-like web interface, check out [https://about.gitlab.com/ GitLab]. See
* [https://www.howtoforge.com/tutorial/how-to-install-gitlab-on-debian-8/ How to Install Gitlab on Debian 8 (Jessie)],  
* [https://www.linux.com/learn/how-run-your-own-git-server How to Run Your Own Git Server]. This includes the installation of postfix for sending emails.


  git config --global push.default simple
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.


When push.default is set to 'matching', git will push local branches
[[File:Gitlab2.png|100px]]  [[File:Gitlab1.png|100px]]  [[File:Gitlab3.png|100px]]
to the remote branches that already exist with the same name.


In Git 2.0, Git will default to the more conservative 'simple'
[https://www.howtoforge.com/tutorial/how-to-install-gitlab-with-postgresql-and-nginx-on-ubuntu-15-04/ How to Install Gitlab with PostgreSQL and Nginx on Ubuntu 15.04] from howtoforge.com.
behavior, which only pushes the current branch to the corresponding
remote branch that 'git pull' uses to update the current branch.


See 'git help config' and search for 'push.default' for further information.
=== Gitolite (favored by Ubuntu) ===
(the 'simple' mode was introduced in Git 1.7.11. Use the similar mode
* https://help.ubuntu.com/lts/serverguide/git.html#git-installing-gitolite
'current' instead of 'simple' if you sometimes use older versions of Git)
* https://www.digitalocean.com/community/tutorials/how-to-use-gitolite-to-control-access-to-a-git-server-on-an-ubuntu-12-04-vps
</syntaxhighlight>


I guess 'simple' (the default) is what we/beginners usually want. Run
This approach involves the following steps
<syntaxhighlight lang='bash'>
# Installing a gitolite server
git config --global push.default simple
# Gitolite configuration
</syntaxhighlight>
# Managing gitolite users and repositories
# Using your server


=== git difftool & meld ===
Not sure about any advantages of this approach?
[https://stackoverflow.com/questions/34119866/setting-up-and-using-meld-as-your-git-difftool-and-mergetool Setting up and using Meld as your git difftool and mergetool]


'''git diff''' can only show the differences on the terminal. '''git difftool''' will show the difference on the GUI program.
== Graphical tool, app ==
* http://askubuntu.com/questions/227554/what-are-some-gui-clients-for-git


'''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 [http://git-scm.com/docs/git-difftool here].
=== Command line approach ===
 
To compare two revisions (sha1sum, branch name)
<syntaxhighlight lang='bash'>
<syntaxhighlight lang='bash'>
git difftool <revision_1> <revision_2>
$ 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
</syntaxhighlight>
</syntaxhighlight>
It will open the first file in Meld. After we close the first file, it will launch the 2nd file in Meld, and so on.


To create a (temporary) branch, use ''git branch -b BRANCHNAME''. To delete a (temporary) branch, use ''git branch -D BRANCHNAME''.
=== Tig ===
[https://opensource.com/article/19/6/what-tig How to use Tig to browse Git logs]


It may be helpful to run the following too
=== [http://git-scm.com/docs/gitk gitk] and [https://git-scm.com/docs/git-gui git-gui] ===
* http://lostechies.com/joshuaflanagan/2010/09/03/use-gitk-to-understand-git/
* http://git-scm.com/download/gui/linux
<syntaxhighlight lang='bash'>
<syntaxhighlight lang='bash'>
git config --global diff.tool meld
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.)
</syntaxhighlight>
</syntaxhighlight>


=== Search/find a deleted file from the commit history ===
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.
https://stackoverflow.com/questions/7203515/git-how-to-find-a-deleted-file-in-the-project-commit-history
 
'''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.


For example, the noweb/code.pdf file was mentioned in the Readme file but it is missing from the CRAN's survival package.
It looks these 2 gui tools are sufficient enough.


<syntaxhighlight lang='bash'>
=== [https://www.gitkraken.com/git-client GitKraken] ===
$ git log --all --full-history -- noweb/code.pdf
[https://blog.axosoft.com/top-developer-tools-2019/ #1] of Top 20 Dev Tools for 2019
commit 1f0dbc538e9147ab264c5215cf205b9b3bc171cb
Author: Terry M Therneau <[email protected]>
Date:  Sun Jun 26 14:19:51 2016 +0000


    version 2.39-5
=== Others  ===
* [http://digilander.libero.it/mcostalba/ QGit] - QGit is a git GUI viewer built on Qt/C++.
* [http://git-cola.github.io/ git-cola] ???
* gitg
* Giggle - Similar to gitk
* SmartGit - Support push, pull, fetch


commit ec6b50c973b9298a5f1aeb839b2d04d3448e69de
== '''Git Tips''' ==
Author: Terry M Therneau <[email protected]>
Date:  Wed May 11 11:45:26 2016 +0000


    version 2.39-4
=== Permission denied (publickey) ===
The error happens on either github or bitbucket.  


commit 38a8ccc0fb014c2b2bfbb2b5153b419e615b01ba
Some resources:
Author: Terry M Therneau <therneau.terry@mayo.edu>
* [https://help.github.com/en/github/authenticating-to-github Authenticating to GitHub]
Date:   Sat Apr 16 19:26:46 2016 +0000
* [https://confluence.atlassian.com/bbkb/permission-denied-publickey-302811860.html Permission denied (publickey)]
* Simple solution: add the ssh key in ~/.ssh/config file. There is no need to use '''ssh-add''' command. Tested on github.com and bitbucket.org. See
** [[Ssh#Configuration_file_.7E.2F.ssh.2Fconfig.2C_avoid_ssh_connection_timeout|.ssh/config]] file
** [https://stackoverflow.com/a/4246809 How to permanently add a private key with ssh-add on Ubuntu?]


    version 2.39-2
=== old mode new mode ===
See [http://stackoverflow.com/questions/1257592/how-do-i-remove-files-saying-old-mode-100755-new-mode-100644-from-unstaged-cha this post]
<syntaxhighlight lang='bash'>
git config core.filemode false
</syntaxhighlight>
</syntaxhighlight>
Here we see code.pdf file existed in version 2.39-2 and was last seen in version 2.39-5.


To restore the deleted, we use
=== Temporarily move to a branch and then move back ===
<pre>
git checkout 38a8ccc -- code.pdf
</pre>
Note that I follow the instruction to add the caret sign (^) at the end of SHA, I'll get an error ''pathspec 'code.pdf' did not match any file(s) known to git.'' My git version is 2.7.4.
 
However, for another file, I do need to use caret.
<syntaxhighlight lang='bash'>
<syntaxhighlight lang='bash'>
git log --all --full-history -- src/coxfit2.c
# suppose we have 3 commits so far and we are at commit 3 now.
 
git status
git checkout 68e5adc1d1486e2b1daa7db9203fd9226e029992^ -- src/coxfit2.c
git log                       # show 3 commits
git checkout sha1_commit_1    # move to commit 1
git log                        # only show 1 commit
git checkout master            # go back to the original 3 commits
git status
</syntaxhighlight>
</syntaxhighlight>


=== Pull request ===
=== git push error (file is created by Windows but edited by Linux), Your branch is ahead of 'origin/master' ===
[https://tonyelhabr.rbind.io/post/making-first-pull-request/ A Newbie's Guide to Making A Pull Request (for an R package)]
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.


== diff between two revisions ==
If I forget to run git pull and after running git push, we will get something like if there is a conflict.
<syntaxhighlight lang='bash'>
<pre>
git diff <revision_1>:<file_1> <revision_2>:<file_2>
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.


# Better to run git config --global diff.tool meld BEFORE
C:\Users\XXX\Documents\GitHub\toy [master]> git status
git difftools <revision_1> <revision_2> # ask to go each file separately
# On branch master
git difftools <revision_1> <revision_2> FILENAME -y
# Your branch is ahead of 'origin/master' by 1 commit.
                                        # just compare the file <FILENAME>
#
nothing to commit, working directory clean
</pre>


git diff master..test                  # between the tips of the two branches
Follow the suggestion from [http://stackoverflow.com/questions/10298291/cannot-push-to-github-keeps-saying-need-merge this post] to use git pull for git to do merge. It does not work in this case.
<pre>
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.


git diff test                          # between your current working directory and the (remote) snapshot on the 'test' branch.
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


git diff --name-only SHA1 SHA2          # show only file names
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")
</pre>


git diff --name-only HEAD~10 HEAD~5    # between the tenth latest commit and the fifth latest
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.
<syntaxhighlight lang='bash'>
$ file README.md
README.md: ASCII text, with CR line terminators.
</syntaxhighlight>
</syntaxhighlight>


=== Monitor/find files that have been changed since last pull ===
Since we already run ''git pull'', it won't work to run ''git reset --soft HEAD~'' to undo a commit. Two solutions
<syntaxhighlight lang="bash">
* '''git fetch origin; git reset --hard origin/master''' to [http://stackoverflow.com/questions/19864934/git-your-branch-and-origin-master-have-diverged-how-to-throw-away-local-com throw away my local modified file] OR
git branch
* '''git reset --hard HEAD''' to undo ''git pull''; see [http://stackoverflow.com/questions/101752/i-ran-into-a-merge-conflict-how-can-i-abort-the-merge this post]. After that, we can run '''git reset --soft HEAD~''' to undo a commit. See below.
git fetch origin master   # or git fetch on Windows
<pre>
git diff --name-only origin/master
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
git log                    # local
C:\Users\XXX\Documents\GitHub\toy [master]> git status
git log origin/master     # remote repository
# On branch master
 
# Your branch is ahead of 'origin/master' by 1 commit.
$ 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
nothing to commit, working directory clean
</syntaxhighlight>


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/ <span style="color: #FFD700">yellow circle</span>) is 2 commits behind the remote repository (remotes/origin/master w/ <span style="color: blue">blue circle</span>).
C:\Users\XXX\Documents\GitHub\toy [master]> git reset --soft HEAD~


[[File:Gitk2.png|200px]] [[File:Gitk.png|200px]]
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


=== Pull and overwrite local files ===
C:\Users\XXX\Documents\GitHub\toy [master +0 ~1 -0]> cat README.md
If we want to run git pull and also overwrite possibly changed local file, we use (see [http://stackoverflow.com/questions/1125968/force-git-to-overwrite-local-files-on-pull stackoverflow])
# toy
<syntaxhighlight lang="bash">
second commit
git fetch --all
3rd commit (Windows MACHINE)
git reset --hard origin/master
C:\Users\XXX\Documents\GitHub\toy [master +0 ~1 -0]> git reset HEAD README.md
</syntaxhighlight>
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")


=== Your branch is ahead by X commits after running '''git pull''' ===
C:\Users\XXX\Documents\GitHub\toy [master +0 ~1 -0]> git checkout -- README.md
'''git status''' shows '''Your branch is Ahead by X commits''' after running '''git pull'''. See [http://stackoverflow.com/questions/2432579/git-your-branch-is-ahead-by-x-commits this post]. The solution is to run '''git fetch''' after '''git pull'''.


=== This repository currently has approximately XXXX loose objects ===
C:\Users\XXX\Documents\GitHub\toy [master]> cat README.md
http://stackoverflow.com/questions/21457407/git-gui-perpetually-getting-this-repository-currently-has-approximately-320-lo
# toy
<syntaxhighlight lang="bash">
second commit
git gc --aggressive
</syntaxhighlight>


=== git commit -am ===
C:\Users\XXX\Documents\GitHub\toy [master]> git status
works only for simple edits. It does not work for renaming files, etc.
# On branch master
nothing to commit, working directory clean
</pre>
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).


=== git diff --staged ===
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 checkout -- FileName ===
=== git push error (both clients are linux), Your branch and 'origin/master' have diverged ===
to recover a modified/deleted file where -- is a linux notation, not specific to git. See [https://stackoverflow.com/a/6561160 Difference between "git checkout <filename>" and "git checkout -​- <filename>"].
Two clients (mint and vm) running on Linux. The following is coming from vm machine.
<syntaxhighlight lang='bash'>
<syntaxhighlight lang='bash'>
rm FileName
brb@ubuntu:~/toy$ git push
git pull  # do nothing
! [rejected]        master -> master (fetch first)
git status # still miss 'FileName'
error: failed to push some refs to 'https://[email protected]/arraytools/toy.git'
git checkout FileName
hint: Updates were rejected because the remote contains work that you do
</syntaxhighlight>
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
The following examples give a good clarification.
hint: (e.g., 'git pull ...') before pushing again.
<syntaxhighlight lang='bash'>
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
git checkout README    # would normally discard uncommitted changes
brb@ubuntu:~/toy$ git pull
                        # to the _file_ "README"
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.


git checkout master    # would normally switch the working copy to
brb@ubuntu:~/toy$ cat linuxfile
                        # the _branch_ "master"
first line
<<<<<<< HEAD
second line edited by vm
=======
second line edited by mint
>>>>>>> b2f1ee4b1f9c2a428a1af061c7b40316a8f85d3d


git checkout -- master # discard uncommitted changes to the _file_ "master"
brb@ubuntu:~/toy$ git status
</syntaxhighlight>
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)


=== git reset HEAD FileName ===
You have unmerged paths.
to un-stage a file
  (fix conflicts and run "git commit")


=== Rewrite a commit ===
Unmerged paths:
ps. This is different from the case of [https://taichimd.us/mediawiki/index.php/Github#Pull_and_overwrite_local_files Pull and overwrite local files]
  (use "git add <file>..." to mark resolution)


Suppose someone made a stupid commit. We want to get a previous version of the code and commit that one.
both modified:      linuxfile
<syntaxhighlight lang='bash'>
git checkout XXXXXX -- FileName
git commit -am CommitMessage
</syntaxhighlight>


===  '''origin''' and nickname ===
no changes added to commit (use "git add" and/or "git commit -a")
<syntaxhighlight lang='bash'>
git remote add NickName https://XXX
git remote
git push -u NickName master
</syntaxhighlight>
</syntaxhighlight>
[http://stackoverflow.com/questions/2452226/master-branch-and-origin-master-have-diverged-how-to-undiverge-branches master branch and 'origin/master' have diverged, how to 'undiverge' branches'?]


== Binary files and why is my .git folder so big? ==
The solution now is to run '''git mergetool''' (assume we have install something like meld, opendiff, kdiff3, tkdiff, or xxdiff). See [http://www.gitguys.com/topics/merging-with-a-gui/ Git Mergetool – Merging With a GUI] from gitguys.com.
https://www.reddit.com/r/git/comments/4xsh26/why_is_my_git_folder_so_big/
<syntaxhighlight lang='bash'>
git gc --aggressive --prune
</syntaxhighlight>


It seems there is no way I can remove binary files (history) from .git folder.
[[File:Gitmergetool.png|200px]]


== Large files and storage limit ==
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).  
* [https://help.github.com/articles/working-with-large-files/ The individual file size limit is 100MB] on Github.
<syntaxhighlight lang='bash'>
* [https://confluence.atlassian.com/bitbucket/what-kind-of-limits-do-you-have-on-repository-file-upload-size-273877699.html The total repository on your '''Bitbucket''' is 1GB]
brb@ubuntu:~/toy$ cat linuxfile
 
first line
=== Less than 100MB ===
second line. conflict resolved in vm
<syntaxhighlight lang="bash">
brb@ubuntu:~/toy$ git status
$ git push -u origin master
On branch master
Counting objects: 115, done.
Your branch and 'origin/master' have diverged,
Delta compression using up to 12 threads.
and have 1 and 1 different commit each, respectively.
Compressing objects: 100% (100/100), done.
  (use "git pull" to merge the remote branch into yours)
Writing objects: 100% (115/115), 97.54 MiB | 4.48 MiB/s, done.
 
Total 115 (delta 16), reused 0 (delta 0)
All conflicts fixed but you are still merging.
remote: warning: GH001: Large files detected. You may want to try Git Large File Storage - https://git-lfs.github.com.
  (use "git commit" to conclude merge)
remote: warning: See http://git.io/iEPt8g for more information.
 
remote: warning: File GSE48215/breastcancer-bt20_raw.vcf is 79.57 MB; this is larger than GitHub's recommended maximum file size of 50.00 MB
Changes to be committed:
To https://github.com/arraytools/seqtools_testdata.git
* [new branch]      master -> master
Branch master set up to track remote branch master from origin.
</syntaxhighlight>
It looks like all files are uploaded successfully.


One annoying thing about github is when we download the repository it automatically add a folder name (REPOSITORY-BRANCH) at the top. For example, it creates 'seqtools_testdata-master'.
modifiedlinuxfile
<syntaxhighlight lang="bash">
$ unzip -l ~/Downloads/seqtools_testdata-master.zip
Archive: /home/odroid/Downloads/seqtools_testdata-master.zip
9f5e132bcfd2007f5fc1fb4ee465c5b307b3e85a
   Length      Date    Time    Name
---------  ---------- -----  ----
        0  2016-06-01 21:05  seqtools_testdata-master/
        0  2016-06-01 21:05  seqtools_testdata-master/GSE11209-master/
46737374  2016-06-01 21:05  seqtools_testdata-master/GSE11209-master/SRR002051.fastq
46675548  2016-06-01 21:05  seqtools_testdata-master/GSE11209-master/SRR002059.fastq
        0  2016-06-01 21:05  seqtools_testdata-master/GSE11209-master/Saccharomyces_cerevisiae/
...
</syntaxhighlight>
=== Larger than 100MB ===
<pre>
remote: error: File hg19/chr1.fa is 242.46 MB; this exceeds GitHub's file size limit of 100.00 MB
remote: error: File hg19/chr1.fa.bwt is 237.70 MB; this exceeds GitHub's file size limit of 100.00 MB
remote: error: File hg19/chr1.fa.sa is 118.85 MB; this exceeds GitHub's file size limit of 100.00 MB
To https://github.com/arraytools/GSE48215.git
! [remote rejected] master -> master (pre-receive hook declined)
</pre>


== Import from one remote to another remote ==
Untracked files:
Suppose the new remote is on bitbucket.
  (use "git add <file>..." to include in what will be committed)
<syntaxhighlight lang="bash">
rsync -av DIRECTORY .
cd SUBDIRECTORY
git remote -v # Examine the current URL
git remote set-url origin git@bitbucket.org:USERNAME/DIRECTORY.git
git remote -v # Examine the new URL
git push -u origin --all
git push origin --tags
</syntaxhighlight>


Other instructions
linuxfile.orig
* https://stackoverflow.com/questions/1484648/how-to-migrate-git-repository-from-one-server-to-a-new-one
* https://www.smashingmagazine.com/2014/05/moving-git-repository-new-server/


== Import from CVS ==
brb@ubuntu:~/toy$ git commit -m "resolve the conflict in vm"
* http://git-scm.com/docs/gitcvs-migration
[master f22932b] resolve the conflict in vm
* http://stackoverflow.com/questions/20869710/migrate-from-cvs-to-git-without-losing-history (see also comments after the suggestion using git-cvsimport)
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)


<syntaxhighlight lang="bash">
Untracked files:
sudo apt-get install git-cvs  # cvsimport command
  (use "git add <file>..." to include in what will be committed)
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
linuxfile.orig
git cvsimport -C ~/Downloads/tmp ModuleName # SLOW & give up
</syntaxhighlight>


== Zip up the folder but exclude the .git subfolder ==
nothing added to commit but untracked files present (use "git add" to track)
<syntaxhighlight lang='bash'>
brb@ubuntu:~/toy$ git push
zip -r myproject.zip myproject -x *.git*
</syntaxhighlight>
</syntaxhighlight>
On Mac, we should add '''--exclude=*.DS_Store*''' to exclude Mac OS X directory display metadata files.
The repository now looks like:


== Preview HTML files from Github and Bitbucket ==
[[File:Toy merged.png|200px]]
http://htmlpreview.github.io/


== General resources ==
=== warning: push.default is unset ===
* https://www.atlassian.com/git/tutorial/remote-repositories
Git 2.0 from 'matching' to 'simple'. To squelch this message ...  
* 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 =
See [http://stackoverflow.com/questions/13148066/warning-push-default-is-unset-its-implicit-value-is-changing-in-git-2-0 stackoverflow].


== Self-hosted ==
'''It only affects what happens when you don't specify which branches you want to push'''; e.g. 'git push' or 'git push origin' instead of 'git push -u origin master'.  
* [https://about.gitlab.com/installation/ gitlab]
** [https://about.gitlab.com/2017/06/29/whats-next-for-gitlab-ci/ From 2/3 of the Self-Hosted Git Market, to the Next-Generation CI System, to Auto DevOps]
** [http://blog.bitrise.io/2017/01/27/state-of-app-development-in-2016.html#self-hosted State of App Development in 2016]
** [https://about.gitlab.com/comparison/gitlab-self-hosted-vs-github.html GitLab Self-hosted vs. GitHub.com]
* [https://gogs.io/ gogs]
** [https://www.howtoforge.com/tutorial/how-to-install-gogs-go-git-service-on-ubuntu-1604/ How to Install Gogs Go Git Service on Ubuntu 16.04]
* [https://gitea.io/en-US/ gitea]
** [https://www.howtoforge.com/tutorial/install-gitea-using-docker-on-ubuntu/ How to Install Gitea Self-hosted Git Service using Docker on Ubuntu 18.04]


== [https://about.gitlab.com/ Gitlab] ==
<syntaxhighlight lang='bash'>
* [https://cran.r-project.org/web/packages/gitlabr/index.html gitlabr] R package
$ git push bitbucket
warning: push.default is unset; its implicit value is changing in
Git 2.0 from 'matching' to 'simple'. To squelch this message
and maintain the current behavior after the default changes, use:


Compared to Github, Gitlab can
  git config --global push.default matching
# host private projects for free
# host static web pages on http://pages.gitlab.io/.


=== Host web site ===
To squelch this message and adopt the new behavior now, use:
http://pages.gitlab.io/


=== http://monitor.gitlab.net/ ===
  git config --global push.default simple


=== How to install and configure Gitlab on Ubuntu ===
When push.default is set to 'matching', git will push local branches
https://www.howtoforge.com/tutorial/how-to-install-and-configure-gitlab-on-ubuntu-16-04/
to the remote branches that already exist with the same name.


== [https://bitbucket.org/ Bitbucket] ==
In Git 2.0, Git will default to the more conservative 'simple'
* [https://blog.bitbucket.org/2018/07/02/new-ip-addresses-bitbucket-cloud/ New IP] July 2, 2018
behavior, which only pushes the current branch to the corresponding
* [https://bitbucket.org/site/master/issues/3488/what-is-the-storage-limit-for-free Storage limit] warning after 1GB, hard limit for 2GB.
remote branch that 'git pull' uses to update the current branch.


== Github ==
See 'git help config' and search for 'push.default' for further information.
=== Github Status ===
(the 'simple' mode was introduced in Git 1.7.11. Use the similar mode
* https://twitter.com/githubstatus
'current' instead of 'simple' if you sometimes use older versions of Git)
* https://status.github.com/ (deprecate on Mar 3, 2019)
</syntaxhighlight>
* https://www.githubstatus.com/


=== Large files (eg binary) ===
I guess 'simple' (the default) is what we/beginners usually want. Run
* [https://help.github.com/articles/what-is-my-disk-quota/ Disk Quota]. Repositories < 1GB and files < 100MB.
<syntaxhighlight lang='bash'>
* Releases allow you to include binary files, such as compiled programs. See https://help.github.com/articles/distributing-large-binaries/
git config --global push.default simple
</syntaxhighlight>


=== Create a new repository ===
=== Search/find a deleted file from the commit history ===
After we use the web interface to create a new empty repository, we are instructed to do one of the following
https://stackoverflow.com/questions/7203515/git-how-to-find-a-deleted-file-in-the-project-commit-history
 
For example, the noweb/code.pdf file was mentioned in the Readme file but it is missing from the CRAN's survival package.


* create a new repository on the command line
<syntaxhighlight lang='bash'>
<syntaxhighlight lang='bash'>
echo "# toy" >> README.md
$ git log --all --full-history -- noweb/code.pdf
git init
commit 1f0dbc538e9147ab264c5215cf205b9b3bc171cb
git add README.md
Author: Terry M Therneau <therneau.terry@mayo.edu>
git commit -m "first commit"
Date:  Sun Jun 26 14:19:51 2016 +0000
git remote add origin https://github.com/arraytools/toy.git
 
git push -u origin master
    version 2.39-5
</syntaxhighlight>
 
* Compare '''git remote add''' (set up remote url) and [[#Rename_a_remote_repository|git remote set-url]] (switch remote url)
commit ec6b50c973b9298a5f1aeb839b2d04d3448e69de
* push an existing repository from the command line
Author: Terry M Therneau <therneau.terry@mayo.edu>
<syntaxhighlight lang='bash'>
Date:  Wed May 11 11:45:26 2016 +0000
git remote add origin https://github.com/arraytools/toy.git
 
git push -u origin master
    version 2.39-4
</syntaxhighlight>
* import code from another repository. You can initialize this repository with code from a Subversion, Mercurial, or TFS project.


=== Host web site ===
commit 38a8ccc0fb014c2b2bfbb2b5153b419e615b01ba
* https://pages.github.com/. Create a new repository "username.github.io". Fill out some files there. Go to https://username.github.io to see the result.
Author: Terry M Therneau <therneau.terry@mayo.edu>
* Updating gh-pages (assuming your vignette file is named 'index.Rmd'). See a [https://github.com/waldronlab/HGNChelper note].
Date:   Sat Apr 16 19:26:46 2016 +0000
: <syntaxhighlight lang='bash'>
 
# pip install ghp-import
    version 2.39-2
Rscript -e "devtools::build_vignettes()"
ghp-import inst/doc
git push
</syntaxhighlight>
</syntaxhighlight>
* [http://blog.teamtreehouse.com/using-github-pages-to-host-your-website Using GitHub Pages To Host Your Website] using a Custom Domain. The IP address information for Github is changed to [https://help.github.com/articles/my-custom-domain-isn-t-working/ new ones].
Here we see code.pdf file existed in version 2.39-2 and was last seen in version 2.39-5.
: <syntaxhighlight lang='bash'>
# Create a new repository in Github using the web interface
# clone it to the local pc
git clone https://github.com/user/repository.git


# create a new branch
To restore the deleted, we use
cd repository
<pre>
git checkout --orphan gh-pages
git checkout 38a8ccc -- code.pdf
git status # double check we are in the gh-pages branch
</pre>
git rm -rf .
Note that I follow the instruction to add the caret sign (^) at the end of SHA, I'll get an error ''pathspec 'code.pdf' did not match any file(s) known to git.'' My git version is 2.7.4.


# create new files.  
However, for another file, I do need to use caret.
touch index.html
<syntaxhighlight lang='bash'>
git add -a
git log --all --full-history -- src/coxfit2.c
git commit -m "Adding pages"


# push to github
git checkout 68e5adc1d1486e2b1daa7db9203fd9226e029992^ -- src/coxfit2.c
git push origin gh-pages
 
# see the web page at
# http://username.github.io/repository/.
</syntaxhighlight>
</syntaxhighlight>
* [https://opensource.com/article/19/5/run-your-blog-github-pages-python Run your blog on GitHub Pages with Python]


Some Examples:
=== Removing files/a folder from a repository ===
* [http://blog.ankitaggarwal.me/PiScope/ PiScope]
* [https://help.github.com/en/github/authenticating-to-github/removing-sensitive-data-from-a-repository Removing sensitive data from a repository]
* [http://rstudio.github.io/dygraphs/index.html dygraphs for R]
* [https://stackoverflow.com/a/2004311 How to permanently delete a file stored in GIT?]
* [http://christophergandrud.github.io/networkD3/ networkD3] for R
To remove the file called Rakefile:
* [http://arraytools.github.io/bdge/ BRB-DGE]
<pre>
* [http://thomsonlab.github.io/html/formula.html read depth calculator] It can run some script!!!
$ git filter-branch --force --index-filter \
  'git rm --cached --ignore-unmatch Rakefile' \
  --prune-empty --tag-name-filter cat -- --all


=== 12 件可以用 GitHub 完成的很酷的事情 ===
$ git push --all --force
[https://hackernoon.com/12-cool-things-you-can-do-with-github-f3e0424cf2f0 12 cool things you can do with GitHub]
</pre>


= Create Websites =
=== Pull request ===
== Documentation generator ==
<ul>
* [https://www.makeuseof.com/tag/static-site-generator-build-website/ Use a Static Site Generator to Build a Quick Website]. Jekyll, Hugo, Hexo, Gitbook and Pelican. Jekyll was explained in detail.
<li>[https://www.digitalocean.com/community/tutorials/how-to-create-a-pull-request-on-github How To Create a Pull Request on GitHub]
* [https://en.wikipedia.org/wiki/Comparison_of_documentation_generators Comparison of documentation generators]
<li>https://www.wikihow.com/Create-a-Pull-Request-on-Github
<li>[https://tonyelhabr.rbind.io/post/making-first-pull-request/ A Newbie's Guide to Making A Pull Request (for an R package)]
<li>[https://usethis.r-lib.org/articles/articles/pr-functions.html Pull request helpers] from the '''usethis''' package.
<li>[https://www.howtogeek.com/devops/what-are-git-pull-requests-and-how-do-you-use-them/ What Are Git Pull Requests, And How Do You Use Them?]
<li>[https://stackoverflow.com/a/30584951 How can I check out a GitHub pull request with git?]
<pre>
git fetch origin pull/$ID/head:$BRANCHNAME
git checkout $BRANCHNAME
</pre>
* pull/$ID/head: This is the reference to the pull request you want to fetch.
* $BRANCHNAME is the name of the new branch that '''you''' want to use in your local repository.
<li>Copilot
<pre>
git fetch origin
git checkout -b branch_name origin/branch_name
git pull origin branch_name # optional if we want to update it with any new changes
</pre>
</ul>


== Rmarkdown ==
=== Cannot see new files added to my git working directory ===
[https://www.emilyzabor.com/tutorials/rmarkdown_websites_tutorial.html Creating websites in R] by Emily C. Zabor. The makes use of Jekyll theme. It covers
[https://stackoverflow.com/a/6710893 Cannot see new files added to my git working directory]. It happened when I include a new subdirectory which comes from other people's repository. The solution for my case is to '''rm .git/index''' and then run git add/commit/push. Next time I need to remove the .git from that subdirectory first.
* Personal websites: index.Rmd, _site.yml. No special package is required except rmarkdown.
* Package websites: pkgdown package is used.
* Project websites: index.Rmd, _site.yml. No special package is required except rmarkdown.
* Blogs: blogdown package is used.


The tutorial's source code is also on github (Click the Github icon at the top).
== Binary files and why is my .git folder so big? ==
Binary files will be tracked by git too.


=== Slides ===
https://www.reddit.com/r/git/comments/4xsh26/why_is_my_git_folder_so_big/
[https://3mmarand.github.io/rbs_intro/#1 An Introduction to Reproducible Analyses in R] and its [https://github.com/3mmaRand/rbs_intro source]
<syntaxhighlight lang='bash'>
git gc --aggressive --prune
</syntaxhighlight>


== [http://jekyllrb.com/ Jekyll] ==
It seems there is no way I can remove binary files (history) from .git folder.
* From help.github.com
** [https://help.github.com/articles/using-jekyll-with-pages/ Using Jekyll with Pages]
** [https://help.github.com/en/articles/setting-up-your-github-pages-site-locally-with-jekyll Setting up your GitHub Pages site locally with Jekyll]
** [https://help.github.com/en/articles/using-jekyll-as-a-static-site-generator-with-github-pages Using Jekyll as a static site generator with GitHub Pages]
* https://www.makeuseof.com/tag/static-site-generator-build-website/
* [http://24ways.org/2013/get-started-with-github-pages/ Get Started With GitHub Pages (Plus Bonus Jekyll)]
* [http://www.cookbook-r.com/Graphs/ Cookbook for R] powered by knitr and Jekyll.
* Slower than Hugo as pointed out by [https://www.rstudio.com/resources/videos/making-websites-with-r/ YiHui Xie].
* [https://github.com/nicolas-van/easy-markdown-to-github-pages/blob/master/README.md Easy Markdown to Github Pages]. The key is go to Settings and pay attention to Github Pages.
** Create a new repository with a README
** Go to Settings - Github Pages. Source = main branch. Theme = Caymen or Architect. It will modify README file. Feel free to do any changes. Then click 'Commit Changes'.
** See my example at https://arraytools.github.io/test-site-Architect
** It does not work by just creating _config.yml file along with README.md without using 'Settings'. You have to change the setting.
** For the free plan, the repository has to be public in order to use Github Pages.


=== [http://jekyllrb.com/docs/installation/ Install Jekyll] ===
== Large files and storage limit ==
on Ubuntu 14.04 I use (the second command will take a while to start),
* [https://help.github.com/articles/working-with-large-files/ Managing large files].
<pre>
** [https://docs.github.com/en/repositories/working-with-files/managing-large-files/about-git-large-file-storage About Git Large File Storage]  
sudo apt-get install ruby1.9.1-dev
* [https://confluence.atlassian.com/bitbucket/what-kind-of-limits-do-you-have-on-repository-file-upload-size-273877699.html The total repository on your '''Bitbucket''' is 1GB]
sudo gem install jekyll
* [https://www.cloudsavvyit.com/13830/how-to-store-large-files-in-git/ How to Store Large Files in Git]
</pre>


=== Example ===
=== Less than 100MB ===
* http://www.masalmon.eu/2017/11/16/wheretoliveus/ and its source code in [https://github.com/maelle/maelle.github.io Github].
<pre style="white-space: pre-wrap; /* CSS 3 */ white-space: -moz-pre-wrap; /* Mozilla, since 1999 */ white-space: -pre-wrap; /* Opera 4-6 */ white-space: -o-pre-wrap; /* Opera 7 */ word-wrap: break-word; /* IE 5.5+ */ " >  
* https://privefl.github.io/blog/one-year-as-a-subscriber-to-stack-overflow/ and its [https://github.com/privefl/blog source]
$ git push -u origin master
* [https://singularity-tutorial.github.io/ Singularity-tutorial], [https://github.com/Singularity-tutorial/Singularity-tutorial.github.io source]
Counting objects: 115, done.
 
Delta compression using up to 12 threads.
=== Script ===
Compressing objects: 100% (100/100), done.
<pre>
Writing objects: 100% (115/115), 97.54 MiB | 4.48 MiB/s, done.
cd /tmp
Total 115 (delta 16), reused 0 (delta 0)
jekyll new MyNewSite
remote: warning: GH001: Large files detected. You may want to try Git Large File Storage - https://git-lfs.github.com.
# It will create a new folder 'MyNewSite' with about.md, _config.yml, css (folder),
remote: warning: See http://git.io/iEPt8g for more information.
#    _includes (folder), index.html, _layouts (folder), _posts (folder) and _sass (folder).
remote: warning: File GSE48215/breastcancer-bt20_raw.vcf is 79.57 MB; this is larger than GitHub's recommended maximum file size of 50.00 MB
cd MyNewSite
To https://github.com/arraytools/seqtools_testdata.git
jekyll serve --watch
* [new branch]      master -> master
# It'll say the Server Address: http://127.0.0.1:4000/
Branch master set up to track remote branch master from origin.
# We can open a browser to see a template of html page created by '''jekyll new''' command.
</pre>
</pre>
It looks like all files are uploaded successfully.


== [https://hexo.io/zh-tw/ hexo] ==
One annoying thing about github is when we download the repository it automatically add a folder name (REPOSITORY-BRANCH) at the top. For example, it creates 'seqtools_testdata-master'.
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.
<syntaxhighlight lang="bash">
$ unzip -l ~/Downloads/seqtools_testdata-master.zip
Archive:  /home/odroid/Downloads/seqtools_testdata-master.zip
9f5e132bcfd2007f5fc1fb4ee465c5b307b3e85a
  Length      Date    Time    Name
---------  ---------- -----  ----
        0  2016-06-01 21:05  seqtools_testdata-master/
        0  2016-06-01 21:05  seqtools_testdata-master/GSE11209-master/
46737374  2016-06-01 21:05  seqtools_testdata-master/GSE11209-master/SRR002051.fastq
46675548  2016-06-01 21:05  seqtools_testdata-master/GSE11209-master/SRR002059.fastq
        0  2016-06-01 21:05  seqtools_testdata-master/GSE11209-master/Saccharomyces_cerevisiae/
...
</syntaxhighlight>


=== Example ===
=== Larger than 100MB ===
* http://mutse.github.io/
<pre>
remote: error: File hg19/chr1.fa is 242.46 MB; this exceeds GitHub's file size limit of 100.00 MB
remote: error: File hg19/chr1.fa.bwt is 237.70 MB; this exceeds GitHub's file size limit of 100.00 MB
remote: error: File hg19/chr1.fa.sa is 118.85 MB; this exceeds GitHub's file size limit of 100.00 MB
To https://github.com/arraytools/GSE48215.git
! [remote rejected] master -> master (pre-receive hook declined)
</pre>


== [http://sphinx-doc.org/ Sphinx] & [https://github.com/rtfd/readthedocs.org Read The Docs] ==
=== git submodule ===
=== Simple GitHub repo and ReadTheDocs set up ===
* [https://stackoverflow.com/a/541490 Managing large binary files with Git]
http://tutos.readthedocs.io/en/latest/source/git_rtd.html#creating-repository-on-github
* https://git-scm.com/docs/git-submodule
* http://alx.github.io/gitbook/5_submodules.html
* [https://www.howtogeek.com/devops/how-to-turn-a-turn-a-directory-in-a-git-repository-into-a-submodule/ How to Turn a Turn a Directory in a Git Repository Into a Submodule]


=== Examples ===
== Import from CVS ==
* http://tutos.readthedocs.io/en/latest/index.html
* http://git-scm.com/docs/gitcvs-migration
* https://angus.readthedocs.io/en/2017/rmarkdown_rnaseq.html
* http://stackoverflow.com/questions/20869710/migrate-from-cvs-to-git-without-losing-history (see also comments after the suggestion using git-cvsimport)
* https://geoparse.readthedocs.org/en/latest/
* https://portcullis.readthedocs.io/en/latest/, Portcullis [https://github.com/TGAC/portcullis source code], [https://academic.oup.com/gigascience/advance-article/doi/10.1093/gigascience/giy131/5173486 Efficient and accurate detection of splice junctions from RNA-Seq with Portcullis]


=== Raspberry Pi/Python ===
<syntaxhighlight lang="bash">
[https://projects.raspberrypi.org/en/projects/documenting-your-code/2 Creating a project website with Sphinx] from Documenting your code.
sudo apt-get install git-cvs  # cvsimport command
tar xzvf tmp.tar.gz
cd DirectoryName


== [https://gohugo.io/ Hugo] ==
# The next command requires a connection to the CVS server even we have a copy of CVS in the local pc
R [https://github.com/rstudio/blogdown blogdown] package depends on Hugo.
git cvsimport -C ~/Downloads/tmp ModuleName # SLOW & give up
</syntaxhighlight>


Install [https://snapcraft.io/hugo snap] from the Snap Store.
== Zip up the folder but exclude the .git subfolder ==
<syntaxhighlight lang='bash'>
zip -r myproject.zip myproject -x *.git*
</syntaxhighlight>
On Mac, we should add '''--exclude=*.DS_Store*''' to exclude Mac OS X directory display metadata files.


=== [https://gohugo.io/getting-started/installing/ Install] ===
== Preview PDF files ==
[https://opensource.com/article/18/3/start-blog-30-minutes-hugo Start a blog in 30 minutes with Hugo, a static site generator written in Go] (Unix and Windows). Note Hugo generates HTML for you. You then take that HTML and serve it on some web server, such as Apache HTTPD, or Nginx.
* It has a built-in support.


On Ubuntu
== Open a PDF file from raw.githubusercontent.com ==
<pre>
* When I open a PDF file from https://raw.githubusercontent.com/rstudio/cheatsheets/main/tidyr.pdf, it automatically downloaded the file in the browser.
sudo apt-get install hugo
** Solution: create an HTML file and embed the PDF file in it. [https://stackoverflow.com/a/54531930 Opening PDF in a browser with Github Pages].
</pre>
* [https://dirask.com/posts/Github-how-to-display-raw-PDF-from-github-repository-in-web-browser-instead-of-download-PpqXnD Github - how to display raw PDF from github repository in web browser instead of download?] (it still works). Use Google Docs viewer by adding <nowiki>https://docs.google.com/viewer?url=</nowiki> before the original URL link. For example,
** https://docs.google.com/viewer?url=https://raw.githubusercontent.com/rstudio/cheatsheets/main/tidyr.pdf


[https://www.digitalocean.com/community/tutorials/how-to-install-and-use-hugo-a-static-site-generator-on-ubuntu-14-04 How To Install and Use Hugo, a Static Site Generator, on Ubuntu 14.04]. See the latest binary version (32/64-bit or ARM/ARM64, Windows/Linux/Mac) at https://github.com/gohugoio/hugo/releases/.
== Preview HTML files from Github and Bitbucket ==
<pre>
http://htmlpreview.github.io/
wget https://github.com/gohugoio/hugo/releases/download/v0.31.1/hugo_0.31.1_Linux-64bit.deb
sudo dpkg -i hugo*.deb


# Install the Hugo Themes
Example: [https://github.com/chuvanan/rdatatable-cookbook data.table cookbook]
# SKIP FOR NOW


# Install the Pygments Syntax Highlighter
== General resources ==
sudo apt-get install python-setuptools python-dev build-essential
* https://www.atlassian.com/git/tutorial/remote-repositories
sudo easy_install pip
* http://www.sbf5.com/~cduan/technical/git/git-4.shtml
pip install --user Pygments # https://github.com/pypa/pip/issues/4186
* http://www.acquia.com/blog/getting-started-collaborative-development-git
</pre>
* http://documentup.com/skwp/git-workflows-book
* http://www.eqqon.com/index.php/Collaborative_Github_Workflow


=== Create a new site ===
== Backup all your GitHub and GitLab git repositories ==
Follow https://gohugo.io/getting-started/quick-start/
[https://www.reddit.com/r/selfhosted/comments/u6dww1/a_simple_way_to_backup_all_your_github_and_gitlab/ A simple way to backup all your GitHub and GitLab git repositories]
<pre>
(trusty)brb@localhost:~/Downloads$ hugo new site quickstart
Congratulations! Your new Hugo site is created in /home/brb/Downloads/quickstart.


Just a few more steps and you're ready to go:
= Git hosting services =


1. Download a theme into the same-named folder.
== Self-hosted ==
  Choose a theme from https://themes.gohugo.io/, or
* [https://about.gitlab.com/installation/ gitlab]
  create your own with the "hugo new theme <THEMENAME>" command.
** [https://about.gitlab.com/2017/06/29/whats-next-for-gitlab-ci/ From 2/3 of the Self-Hosted Git Market, to the Next-Generation CI System, to Auto DevOps]
2. Perhaps you want to add some content. You can add single files
** [http://blog.bitrise.io/2017/01/27/state-of-app-development-in-2016.html#self-hosted State of App Development in 2016]
  with "hugo new <SECTIONNAME>/<FILENAME>.<FORMAT>".
** [https://about.gitlab.com/comparison/gitlab-self-hosted-vs-github.html GitLab Self-hosted vs. GitHub.com]
3. Start the built-in live server via "hugo server".
* [https://gogs.io/ gogs]
** [https://www.howtoforge.com/tutorial/how-to-install-gogs-go-git-service-on-ubuntu-1604/ How to Install Gogs Go Git Service on Ubuntu 16.04]
* [https://gitea.io/en-US/ gitea]
** [https://www.howtoforge.com/tutorial/install-gitea-using-docker-on-ubuntu/ How to Install Gitea Self-hosted Git Service using Docker on Ubuntu 18.04]


Visit https://gohugo.io/ for quickstart guide and full documentation.
== [https://about.gitlab.com/ Gitlab] ==
* [https://cran.r-project.org/web/packages/gitlabr/index.html gitlabr] R package


(trusty)brb@localhost:~/Downloads$ cd quickstart;\
Compared to Github, Gitlab can
git init;\
# host private projects for free
git submodule add https://github.com/budparr/gohugo-theme-ananke.git themes/ananke;\
# host static web pages on http://pages.gitlab.io/.


# Edit your config.toml configuration file
=== Host web site ===
# and add the Ananke theme.
http://pages.gitlab.io/
echo 'theme = "ananke"' >> config.toml


(trusty)brb@localhost:~/Downloads/quickstart$ hugo new posts/my-first-post.md
=== http://monitor.gitlab.net/ ===
/home/brb/Downloads/quickstart/content/posts/my-first-post.md created


(trusty)brb@localhost:~/Downloads/quickstart$ ls -l content/posts
=== How to install and configure Gitlab on Ubuntu ===
total 12
* https://www.howtoforge.com/tutorial/how-to-install-and-configure-gitlab-on-ubuntu-16-04/
-rw-rw-r-- 1 brb brb 76 Dec 19 16:00 my-first-post.md
* [https://www.cloudsavvyit.com/2234/how-to-set-up-a-personal-gitlab-server/ How To Set Up a Personal Gitlab Server]


(trusty)brb@localhost:~/Downloads/quickstart$ ls -l
=== Running an R Script on a Schedule ===
total 40
* [https://blog.rmhogervorst.nl/blog/2020/09/26/running-an-r-script-on-a-schedule-overview/ Running an R Script on a Schedule: Overview]
drwxrwxr-x 2 brb brb 4096 Dec 19 15:58 archetypes
* [https://blog.rmhogervorst.nl/blog/2020/09/24/running-an-r-script-on-a-schedule-gitlab/ Tweeting from gitlab actions]
-rw-rw-r-- 1 brb brb  91 Dec 19 16:03 config.toml
* [https://blog.rmhogervorst.nl/blog/2020/09/25/running-an-r-script-on-a-schedule-docker-containers/ Docker Containers on gitlab]
drwxrwxr-x 3 brb brb 4096 Dec 19 16:00 content
drwxrwxr-x 2 brb brb 4096 Dec 19 15:58 data
drwxrwxr-x 2 brb brb 4096 Dec 19 15:58 layouts
drwxrwxr-x 6 brb brb 4096 Dec 19 16:20 public
drwxrwxr-x 2 brb brb 4096 Dec 19 15:58 static
drwxrwxr-x 3 brb brb 4096 Dec 19 16:00 themes


(trusty)brb@localhost:~/Downloads/quickstart$ cat config.toml
== [https://bitbucket.org/ Bitbucket] ==
baseURL = "http://example.org/"
* [https://blog.bitbucket.org/2018/07/02/new-ip-addresses-bitbucket-cloud/ New IP] July 2, 2018
languageCode = "en-us"
* [https://bitbucket.org/site/master/issues/3488/what-is-the-storage-limit-for-free Storage limit] warning after 1GB, hard limit for 2GB.
title = "TAICHIMD"
* [https://bitbucket.org/blog/ssh-host-key-changes SSH Host Key Rotation. IMPORTANT NOTICE: Bitbucket Cloud’s RSA SSH Host Key will be rotated on June 20, 2023 1700 UTC]
theme = "ananke"
:<syntaxhighlight lang='bash'>
ssh-keygen -R bitbucket.org && curl https://bitbucket.org/site/ssh >> ~/.ssh/known_hosts
 
ssh [email protected] host_key_info # verify
</syntaxhighlight>
 
=== Large files ===
[https://confluence.atlassian.com/bitbucket/git-large-file-storage-in-bitbucket-829078514.html Manage huge files in Bitbucket with Git LFS]
 
== Gitbucket ==
[https://www.howtoforge.com/tutorial/how-to-install-gitbucket-on-ubuntu-1804/ How to Install GitBucket with Nginx on Ubuntu 18.04 LTS]
 
== Github ==
=== Github Status ===
* https://twitter.com/githubstatus
* https://status.github.com/ (deprecate on Mar 3, 2019)
* https://www.githubstatus.com/
 
=== Gist ===
<ul>
<li>[https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token Creating a personal access token]
<li>[https://github.com/aprescott/gist-backup gist-backup], [https://vostbur.github.io/posts/backup-all-your-own-gists/ Backup (clone) all your own gists]
<li>[https://www.mydatahack.com/downloading-all-public-github-gist-files/ Downloading All Public GitHub Gist Files] (it works, python3)
<pre>
import requests, json
headers = {"content-type" : "application/json"}
url = 'https://api.github.com/users/mydatahack/gists'
r = requests.get(url, headers = headers)
metadata_file = './data/my_gist_list.json'
# Getting metadata
prettyJson = json.dumps(r.json(), indent=4, sort_keys=True)
f = open(metadata_file, 'w')
f.write(prettyJson)
 
print('Metadata obtained as {}'.format(metadata_file))
 
# Downloading files
data = r.json()
counter = 0
for i in data:
    files_node = i['files']
    file_name = [k for k in files_node][0]
    r = requests.get(files_node[file_name]['raw_url'])
    f = open('./data/{}'.format(file_name), 'w')
    f.write(r.text)
    f.close()
    print('Downloaded {}'.format(file_name))
    counter += 1
 
print('{} files successfully downloaded.'.format(counter))
</pre>
</ul>


# Start the server
=== Large files (eg binary) ===
(trusty)brb@localhost:~/Downloads/quickstart$ hugo server -D # prompt will not be returned, Press Ctrl+C to stop
* [https://help.github.com/articles/what-is-my-disk-quota/ Disk Quota]. Repositories < 1GB and files < 100MB.
                                                            # -D/--buildDrafts: include content marked as draft
* Releases allow you to include binary files, such as compiled programs. See https://help.github.com/articles/distributing-large-binaries/
Started building sites ...


Built site for language en:
=== Create a new repository ===
1 of 1 draft rendered
After we use the web interface to create a new empty repository, we are instructed to do one of the following
0 future content
 
0 expired content
* create a new repository on the command line
1 regular pages created
<syntaxhighlight lang='bash'>
8 other pages created
echo "# toy" >> README.md
0 non-page files copied
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
</syntaxhighlight>
* Compare '''git remote add''' (set up remote url) and [[#Rename_a_remote_repository|git remote set-url]] (switch remote url)
* push an existing repository from the command line
<syntaxhighlight lang='bash'>
git remote add origin https://github.com/arraytools/toy.git
git push -u origin master
</syntaxhighlight>
* import code from another repository. You can initialize this repository with code from a Subversion, Mercurial, or TFS project.
 
=== Archive a repository ===
* [https://stackoverflow.com/a/47202414 How to archive a repository on GitHub]
* [https://github.com/MarioniLab/MNN2017 An example]
 
=== Host web site: pages and wiki ===
* [https://docs.github.com/en/pages/configuring-a-custom-domain-for-your-github-pages-site Configuring a custom domain for your GitHub Pages site]
* https://pages.github.com/. Create a new repository "username.github.io". Fill out some files there. Go to https://username.github.io to see the result.
* [https://youtu.be/p1QU3kLFPdg How to put an HTML website online (on the Internet) - 2022] (video)
* Updating gh-pages (assuming your vignette file is named 'index.Rmd'). See a [https://github.com/waldronlab/HGNChelper note].
: <syntaxhighlight lang='bash'>
# pip install ghp-import
Rscript -e "devtools::build_vignettes()"
ghp-import inst/doc
git push
</syntaxhighlight>
* [http://blog.teamtreehouse.com/using-github-pages-to-host-your-website Using GitHub Pages To Host Your Website] using a Custom Domain. The IP address information for Github is changed to [https://help.github.com/articles/my-custom-domain-isn-t-working/ new ones].
: <syntaxhighlight lang='bash'>
# Create a new repository in Github using the web interface
# clone it to the local pc
git clone https://github.com/user/repository.git
 
# create a new branch
cd repository
git checkout --orphan gh-pages
git status # double check we are in the gh-pages branch
git rm -rf .
 
# create new files.
touch index.html
git add -a
git commit -m "Adding pages"
 
# push to github
git push origin gh-pages
 
# see the web page at
# http://username.github.io/repository/.
</syntaxhighlight>
* [https://opensource.com/article/19/5/run-your-blog-github-pages-python Run your blog on GitHub Pages with Python]
 
Some Examples:
* [http://blog.ankitaggarwal.me/PiScope/ PiScope]
* [http://rstudio.github.io/dygraphs/index.html dygraphs for R]
* [http://christophergandrud.github.io/networkD3/ networkD3] for R
* [http://arraytools.github.io/bdge/ BRB-DGE]
* [http://thomsonlab.github.io/html/formula.html read depth calculator] It can run some script!!!
* Wiki has its own git. See [https://github.com/davidgilbertson/about-github/wiki this example].
 
=== Create a documentation site with Docsify and GitHub Pages ===
* [https://opensource.com/article/20/7/docsify-github-pages How to create a documentation site with Docsify and GitHub Pages]
* [https://opensource.com/article/23/5/docsify-markdown-html Generate web pages from Markdown with Docsify-This], https://docsify-this.net/#/
 
=== GitHub Action to Deploy Static Assets to GitHub Pages ===
[https://github.com/maxheld83/ghpages ghpages]
 
=== Github Docker Container Registry ===
[https://www.cloudsavvyit.com/6871/how-to-get-started-with-githubs-new-docker-container-registry/ How to Get Started with Github’s New Docker Container Registry]
 
=== Github Actions (GHA) ===
* https://github.com/features/actions
** https://docs.github.com/en/free-pro-team@latest/actions
** [https://docs.github.com/en/free-pro-team@latest/actions/reference/specifications-for-github-hosted-runners Specifications for GitHub-hosted runners]. 2-core CPU, 7 GB of RAM memory, 14 GB of SSD disk space. For the free plan, 2,000 Actions minutes/month + 500MB of GitHub Packages storage.
** [https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idruns-on Workflow syntax]: on, name, jobs, jobs.<job_id>.name, jobs.<job_id>.runs-on, jobs.<job_id>.env, jobs.jobs.<job_id>.steps, <job_id>.strategy, jobs.<job_id>.container.
* [https://www.lynda.com/search?q=github+action Lynda.com -> Learning Github Actions]
* [https://www.cloudsavvyit.com/15503/how-to-run-github-actions-builds-on-your-own-servers-with-self-hosted-runners/ How to Run Github Actions Builds on Your Own Servers With Self-Hosted Runners]
* https://github.com/r-lib/actions
** [[R_packages#usethis_package|R usethis package]]
** [https://fromthebottomoftheheap.net/2020/04/30/rendering-your-readme-with-github-actions/ Rendering your README with GitHub Actions]
** [https://youtu.be/K4x-uqLl_m4 How to migrate from TravisCI to GitHub Actions for R packages (video)]. It teaches how to use the [https://usethis.r-lib.org/reference/use_github_action.html usethis::use_github_action_check_standard()] function.
** [https://www.rostrum.blog/2020/08/09/ghactions-pkgs/ Quick GitHub Actions for your R package]. [https://usethis.r-lib.org/reference/use_pkgdown.html usethis::use_pkgdown()] (set up a website for your package, not related to Github Action)
** [https://bioconductor.org/packages/release/bioc/html/biocthis.html biocthis]
* [[#Git_hooks|Git hooks]]
* Tutorials
** [https://www.pixelstech.net/article/1577096152-A-tutorial-on-Github-Actions A tutorial on Github Actions]
* Docker
** [https://www.docker.com/blog/first-docker-github-action-is-here/ First Docker GitHub Action is here!]
** [https://docs.github.com/en/actions/language-and-framework-guides/publishing-docker-images Publishing Docker images]
** [https://github.com/seandavi/BuildABiocWorkshop2020 BuildABiocWorkshop2020] works.
*** Read the vignette [https://seandavi.github.io/BuildABiocWorkshop2020/articles/HOWTO_BUILD_WORKSHOP.html How To Build A Workshop Package]
*** In repository setting, I need to enable Github Pages and use "'''/doc'''" as the folder in the "gh-pages" branch.
*** In repository setting -> Secrets, I need to create two '''secrets'''. One name is '''DOCKER_USERNAME''' and the other is '''DOCKER_PASSWORD'''. Their values are from docker hub account info.
*** After commit and push changes, we can go to github actions and click "update" (my commit message) -> "job1". It shows each step with running time listed on the yaml file.
*** For a successful run, we will see docker hub page was created and a gh-page was created too.
* [https://github.com/arraytools/biocdownload An example to monitor the number of Bioconductor package downloads]. Note that the 'bioc' version needs to be updated once a new version of Bioconductor has been released.
** [https://github.com/JamesIves/github-pages-deploy-action GitHub action for deploying a project to GitHub pages]
* [https://blog.revolutionanalytics.com/2020/08/mlops-with-r-and-github-actions.html MLOPS with R and GitHub Actions]
** [https://github.com/marketplace?type=actions Github action templates]
* [https://blog.rmhogervorst.nl/blog/2020/09/24/running-an-r-script-on-a-schedule-gh-actions/ Running an R Script on a Schedule: Gh-Actions]
* [https://medium.com/@nabil.servais/using-github-actions-to-test-your-go-code-on-arm64-ce581e646cb Using Github actions to test your go code on ARM64]
<ul>
<li>[https://docs.github.com/en/free-pro-team@latest/actions/hosting-your-own-runners/about-self-hosted-runners Self-hosted runners].
<ul>
<li>[https://github.blog/2019-11-05-self-hosted-runners-for-github-actions-is-now-in-beta/ Self-hosted runners for GitHub Actions is now in beta] </li>
<li>[https://github.com/r-lib/actions/issues/173 setup-r@v1 stalls on a self-hosted ubuntu-18.04 runner? #173]. It ask sudo password for ''apt'' command. </li>
<li>https://github.com/tcardonne/docker-github-runner This Docker image allows you to create your own runners on Docker. </li>
<li>[https://testdriven.io/blog/github-actions-docker/ Deploying Self-Hosted Github Actions Runners with Docker] </li>
<li>Google: githubactions self host apt command </li>
<li>A working example ([https://github.com/arraytools/ga_readme ga_readme] private repo). Note the runner has an access all to my host OS's apps like R/Rscript and all R's libraries. We can put the GHA in a docker; see the next item for a step-by-step tutorial.
{{Pre}}
# For convenience I extract the ''actions-runner'' to the repo directory and I add ''actions-runner'' to .gitignore.
$ ~/github/ga_readme/actions-runner$ ./run.sh
 
√ Connected to GitHub
 
2020-11-22 13:09:50Z: Listening for Jobs
2020-11-22 13:09:53Z: Running job: build
2020-11-22 13:09:59Z: Job build completed with result: Succeeded
</pre>
{{Pre}}
# The yml file contains several names:
#  CI - workflow name
#  build - job name
#  Run a one-line script - step name
 
$ cat .github/workflows/main.yml
name: CI
on:
  push:
    branches: [ main ]
  # Allows you to run this workflow manually from the Actions tab
  workflow_dispatch:
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
  # This workflow contains a single job called "build"
  build:
    runs-on: self-hosted
    # Steps represent a sequence of tasks that will be executed as part of the job
    steps:
      # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
      - uses: actions/checkout@v2
 
      # Runs a single command using the runners shell
      - name: Run a one-line script
        run: Rscript --vanilla -e "library()"
 
      # Runs a set of commands using the runners shell
      - name: Render README
        run: Rscript -e 'rmarkdown::render("README.Rmd")'
      - name: Commit results
        run: |
          git config --local user.email "[email protected]"
          git config --local user.name "GitHub Actions"
          git commit README.md -m 'Re-build README.Rmd' || echo "No changes to commit"
          git push origin || echo "No changes to commit"
</pre>
</li>
<li>[https://dev.to/wayofthepie/ephemeral-self-hosted-github-actions-runners-1h5m Ephemeral Self-Hosted Github Actions Runners]: '''Dockerizing a runner'''  </li>
</ul>
<li>[https://pacha.dev/blog/2023/05/19/using-bookdown-with-gh-pages/ Using bookdown with gh-pages] (5/19/2023)
<li>[https://www.youtube.com/watch?v=aZ38ph9plOU Why use Github Actions (as an R programmer) ?] (7/14/2024)
<li>[https://www.howtogeek.com/devops/should-you-use-github-actions-or-a-self-hosted-build-server/ Should You Use GitHub Actions, or a Self-Hosted Build Server?]
</ul>
 
=== Workflow status badge, DOI ===
* [https://help.github.com/en/actions/configuring-and-managing-workflows/configuring-a-workflow Configuring a workflow]
* [https://dev.to/jonasbn/til-adding-an-action-workflow-status-badge-to-your-github-repository-388d Adding an action/workflow status badge to your GitHub repository]
* [https://guides.github.com/activities/citable-code/ Making Your Code Citable]
** An example [https://github.com/RMHogervorst/scheduling_r_scripts scheduling_r_scripts]
* [https://rdrr.io/github/r-lib/usethis/man/badges.html README badges] from usethis R package
* [https://www.mzes.uni-mannheim.de/socialsciencedatalab/article/r-package/ How to write your own R package and publish it on CRAN]
* [https://www.raspberrypi.org/blog/pumpkin-pi-build-monitor/ Monitor your GitHub build with a Raspberry Pi pumpkin]
 
=== Passkey ===
* [https://www.ithome.com.tw/news/158880 GitHub正式支援Passkey]
* [https://www.makeuseof.com/github-passkeys-log-in-without-password/ Passkeys: How to Log In to GitHub Without a Password]
 
== VS code ==
[https://visualstudiomagazine.com/articles/2021/08/31/github-vs-code.aspx One-Click VS Code in Browser from GitHub Repo]. This assumes we have logged in the github account and it does not matter whether the repository is owned by me or not.
 
=== 12 件可以用 GitHub 完成的很酷的事情 ===
[https://hackernoon.com/12-cool-things-you-can-do-with-github-f3e0424cf2f0 12 cool things you can do with GitHub]
 
= Create Websites =
== Documentation generator ==
* [https://www.makeuseof.com/tag/static-site-generator-build-website/ Use a Static Site Generator to Build a Quick Website]. Jekyll, Hugo, Hexo, Gitbook and Pelican. Jekyll was explained in detail.
* [https://en.wikipedia.org/wiki/Comparison_of_documentation_generators Comparison of documentation generators]
 
== Rmarkdown ==
[https://www.emilyzabor.com/tutorials/rmarkdown_websites_tutorial.html Creating websites in R] by Emily C. Zabor. The makes use of Jekyll theme. It covers
* Personal websites: index.Rmd, _site.yml. No special package is required except rmarkdown.
* Package websites: pkgdown package is used.
* Project websites: index.Rmd, _site.yml. No special package is required except rmarkdown.
* Blogs: blogdown package is used.
 
The tutorial's source code is also on github (Click the Github icon at the top).
 
=== Slides ===
[https://3mmarand.github.io/rbs_intro/#1 An Introduction to Reproducible Analyses in R] and its [https://github.com/3mmaRand/rbs_intro source]
 
=== Math ===
* [https://github.com/STAT545-UBC/Discussion/issues/102 Problems with adding math formula in README.md]
* https://youtu.be/dpVnmxpVdvg using the [http://latex.codecogs.com/eqneditor/editor.php codecogs] RESTful service
* [https://stackoverflow.com/a/30389289 How to support latex in github-pages?]
 
== [http://jekyllrb.com/ Jekyll] ==
* From help.github.com
** [https://help.github.com/articles/using-jekyll-with-pages/ Using Jekyll with Pages]
** [https://help.github.com/en/articles/setting-up-your-github-pages-site-locally-with-jekyll Setting up your GitHub Pages site locally with Jekyll]
** [https://help.github.com/en/articles/using-jekyll-as-a-static-site-generator-with-github-pages Using Jekyll as a static site generator with GitHub Pages]
* https://www.makeuseof.com/tag/static-site-generator-build-website/
* [http://24ways.org/2013/get-started-with-github-pages/ Get Started With GitHub Pages (Plus Bonus Jekyll)]
* [http://www.cookbook-r.com/Graphs/ Cookbook for R] powered by knitr and Jekyll.
* Slower than Hugo as pointed out by [https://www.rstudio.com/resources/videos/making-websites-with-r/ YiHui Xie].
* [https://github.com/nicolas-van/easy-markdown-to-github-pages/blob/master/README.md Easy Markdown to Github Pages]. The key is go to Settings and pay attention to Github Pages.
** Create a new repository with a README
** Go to Settings - Github Pages. Source = main branch. Theme = Caymen or Architect. It will modify README file. Feel free to do any changes. Then click 'Commit Changes'.
** See my example at https://arraytools.github.io/test-site-Architect
** It does not work by just creating _config.yml file along with README.md without using 'Settings'. You have to change the setting.
** For the free plan, the repository has to be public in order to use Github Pages.
* [https://www.makeuseof.com/tag/jekyll-vs-gatsbyjs-static-site-builder/ Jekyll vs. GatsbyJS: Which Static Site Builder Builds the Best Website?]
 
=== [http://jekyllrb.com/docs/installation/ Install Jekyll] ===
on Ubuntu 14.04 I use (the second command will take a while to start),
<pre>
sudo apt-get install ruby1.9.1-dev
sudo gem install jekyll
</pre>
 
=== RStudio ===
[https://seth-dobson.github.io/r-blogging-on-a-chromebook/ R Blogging on a Chromebook]. A simple approach using Jekyll, GitHub, and RStudio Cloud.
 
=== Example ===
* http://www.masalmon.eu/2017/11/16/wheretoliveus/ and its source code in [https://github.com/maelle/maelle.github.io Github].
* https://privefl.github.io/blog/one-year-as-a-subscriber-to-stack-overflow/ and its [https://github.com/privefl/blog source]
* [https://singularity-tutorial.github.io/ Singularity-tutorial], [https://github.com/Singularity-tutorial/Singularity-tutorial.github.io source]
 
=== Script ===
<pre>
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.
</pre>
 
== [https://hexo.io/zh-tw/ 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 ===
* http://mutse.github.io/
 
== [http://sphinx-doc.org/ Sphinx] & [https://github.com/rtfd/readthedocs.org Read The Docs] ==
=== Simple GitHub repo and ReadTheDocs set up ===
http://tutos.readthedocs.io/en/latest/source/git_rtd.html#creating-repository-on-github
 
=== Examples ===
* http://tutos.readthedocs.io/en/latest/index.html
* https://angus.readthedocs.io/en/2017/rmarkdown_rnaseq.html
* https://geoparse.readthedocs.org/en/latest/
* https://portcullis.readthedocs.io/en/latest/, Portcullis [https://github.com/TGAC/portcullis source code], [https://academic.oup.com/gigascience/advance-article/doi/10.1093/gigascience/giy131/5173486 Efficient and accurate detection of splice junctions from RNA-Seq with Portcullis]
 
=== Raspberry Pi/Python ===
[https://projects.raspberrypi.org/en/projects/documenting-your-code/2 Creating a project website with Sphinx] from Documenting your code.
 
== [https://gohugo.io/ Hugo] ==
* R [https://github.com/rstudio/blogdown blogdown] package depends on Hugo.
* [https://opensource.com/article/19/4/building-hosting-website-git Build and host a website with Git]
* Install [https://snapcraft.io/hugo snap] from the Snap Store.
 
=== [https://gohugo.io/getting-started/installing/ Install] ===
[https://opensource.com/article/18/3/start-blog-30-minutes-hugo Start a blog in 30 minutes with Hugo, a static site generator written in Go] (Unix and Windows). Note Hugo generates HTML for you. You then take that HTML and serve it on some web server, such as Apache HTTPD, or Nginx.
 
On Ubuntu
<pre>
sudo apt-get install hugo
</pre>
 
[https://www.digitalocean.com/community/tutorials/how-to-install-and-use-hugo-a-static-site-generator-on-ubuntu-14-04 How To Install and Use Hugo, a Static Site Generator, on Ubuntu 14.04]. See the latest binary version (32/64-bit or ARM/ARM64, Windows/Linux/Mac) at https://github.com/gohugoio/hugo/releases/.
<pre>
wget https://github.com/gohugoio/hugo/releases/download/v0.31.1/hugo_0.31.1_Linux-64bit.deb
sudo dpkg -i hugo*.deb
 
# Install the Hugo Themes
# SKIP FOR NOW
 
# Install the Pygments Syntax Highlighter
sudo apt-get install python-setuptools python-dev build-essential
sudo easy_install pip
pip install --user Pygments # https://github.com/pypa/pip/issues/4186
</pre>
 
[https://www.howtoforge.com/tutorial/how-to-install-hugo-site-generator-on-ubuntu/ How to Install Hugo Site Generator On Ubuntu 18.04 LTS]
 
=== Create a new site ===
Follow https://gohugo.io/getting-started/quick-start/
<pre>
(trusty)brb@localhost:~/Downloads$ hugo new site quickstart
Congratulations! Your new Hugo site is created in /home/brb/Downloads/quickstart.
 
Just a few more steps and you're ready to go:
 
1. Download a theme into the same-named folder.
  Choose a theme from https://themes.gohugo.io/, or
  create your own with the "hugo new theme <THEMENAME>" command.
2. Perhaps you want to add some content. You can add single files
  with "hugo new <SECTIONNAME>/<FILENAME>.<FORMAT>".
3. Start the built-in live server via "hugo server".
 
Visit https://gohugo.io/ for quickstart guide and full documentation.
 
(trusty)brb@localhost:~/Downloads$ cd quickstart;\
git init;\
git submodule add https://github.com/budparr/gohugo-theme-ananke.git themes/ananke;\
 
# Edit your config.toml configuration file
# and add the Ananke theme.
echo 'theme = "ananke"' >> config.toml
 
(trusty)brb@localhost:~/Downloads/quickstart$ hugo new posts/my-first-post.md
/home/brb/Downloads/quickstart/content/posts/my-first-post.md created
 
(trusty)brb@localhost:~/Downloads/quickstart$ ls -l content/posts
total 12
-rw-rw-r-- 1 brb brb 76 Dec 19 16:00 my-first-post.md
 
(trusty)brb@localhost:~/Downloads/quickstart$ ls -l
total 40
drwxrwxr-x 2 brb brb 4096 Dec 19 15:58 archetypes
-rw-rw-r-- 1 brb brb  91 Dec 19 16:03 config.toml
drwxrwxr-x 3 brb brb 4096 Dec 19 16:00 content
drwxrwxr-x 2 brb brb 4096 Dec 19 15:58 data
drwxrwxr-x 2 brb brb 4096 Dec 19 15:58 layouts
drwxrwxr-x 6 brb brb 4096 Dec 19 16:20 public
drwxrwxr-x 2 brb brb 4096 Dec 19 15:58 static
drwxrwxr-x 3 brb brb 4096 Dec 19 16:00 themes
 
(trusty)brb@localhost:~/Downloads/quickstart$ cat config.toml
baseURL = "http://example.org/"
languageCode = "en-us"
title = "TAICHIMD"
theme = "ananke"
 
# Start the server
(trusty)brb@localhost:~/Downloads/quickstart$ hugo server -D
# prompt will not be returned, Press Ctrl+C to stop
# -D/--buildDrafts: include content marked as draft
 
Started building sites ...
 
Built site for language en:
1 of 1 draft rendered
0 future content
0 expired content
1 regular pages created
8 other pages created
0 non-page files copied
1 paginator pages created
1 paginator pages created
0 tags created
0 tags created
0 categories created
0 categories created
total in 27 ms
total in 27 ms
Watching for changes in /home/brb/Downloads/quickstart/{data,content,layouts,themes,static}
Watching for changes in /home/brb/Downloads/quickstart/{data,content,layouts,themes,static}
Serving pages from memory
Serving pages from memory
Running in Fast Render Mode. For full rebuilds on change: hugo server --disableFastRender
Running in Fast Render Mode. For full rebuilds on change: hugo server --disableFastRender
Web Server is available at http://localhost:1313/ (bind address 127.0.0.1)
Web Server is available at http://localhost:1313/ (bind address 127.0.0.1)
Press Ctrl+C to stop
Press Ctrl+C to stop
</pre>
</pre>
 
 
[[File:Hugo quickstart.png|300px]]
[[File:Hugo quickstart.png|300px]]
 
=== Deploy Your Website ===
* https://gohugo.io/getting-started/usage/
* [https://www.digitalocean.com/community/tutorials/how-to-deploy-a-hugo-site-to-production-with-git-hooks-on-ubuntu-14-04 How To Deploy a Hugo Site to Production with Git Hooks on Ubuntu 14.04]
 
After running hugo server for local web development, you need to do a final hugo run without the server part of the command to rebuild your site. You may then deploy your site by copying the public/ directory to your production web server.
<pre>
(trusty)brb@localhost:~/Downloads/quickstart$ hugo
Started building sites ...
 
Built site for language en:
0 of 1 draft rendered
0 future content
0 expired content
0 regular pages created
6 other pages created
0 non-page files copied
0 paginator pages created
0 tags created
0 categories created
total in 15 ms
</pre>
 
=== Dev vs Deploy Destinations ===
 
=== Directory Structure ===
 
=== Configure Hugo ===
 
=== Hugo themes ===
* https://themes.gohugo.io/
* https://themes.gohugo.io/tags/documentation/
* https://themes.gohugo.io/slate/ & https://github.com/gesquive/hugo-slate-demo
<pre>
(trusty)brb@localhost:~$ cd Downloads
(trusty)brb@localhost:~$ git clone https://github.com/gesquive/hugo-slate-demo
(trusty)brb@localhost:~$ cd hugo-slate-demo/
(trusty)brb@localhost:~/Downloads/hugo-slate-demo$ hugo server -t slate
</pre>
 
=== Examples ===
* http://noreastrconf.com/
 
=== Gitlab ===
[https://jozef.io/r915-gitlab-pages-own-domain/ Porting and redirecting a Hugo-based blogdown website to an HTTPS-enabled custom domain and how to do it the easy way]
 
== roxygen ==
* https://cran.r-project.org/web/packages/roxygen2/
* http://roxygen.org/roxygen.pdf
* https://stackoverflow.com/questions/26798150/is-there-a-documentation-generator-for-r-like-there-is-for-java
 
== Pelican ==
* [https://fedoramagazine.org/make-github-pages-blog-with-pelican/ Make a Github Pages blog with Pelican]
* [https://rsip22.github.io/blog/create-a-blog-with-pelican-and-github-pages.html Creating a blog with pelican and Github pages]


=== Deploy Your Website ===
= Git hooks =
* https://gohugo.io/getting-started/usage/
* [https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks Customizing Git - Git Hooks]
* [https://www.digitalocean.com/community/tutorials/how-to-deploy-a-hugo-site-to-production-with-git-hooks-on-ubuntu-14-04 How To Deploy a Hugo Site to Production with Git Hooks on Ubuntu 14.04]
* [https://www.digitalocean.com/community/tutorials/how-to-deploy-a-hugo-site-to-production-with-git-hooks-on-ubuntu-14-04 How To Deploy a Hugo Site to Production with Git Hooks on Ubuntu 14.04]
 
* [https://www.jianshu.com/p/f9312b51e011 git hooks 实现自动部署]
After running hugo server for local web development, you need to do a final hugo run without the server part of the command to rebuild your site. You may then deploy your site by copying the public/ directory to your production web server.
* [https://gist.github.com/noelboss/3fe13927025b89757f8fb12e9066f2fa Simple automated GIT Deployment using GIT Hooks]
<pre>
* [https://www.atlassian.com/git/tutorials/git-hooks Git Hooks Overview] from bitbucket
(trusty)brb@localhost:~/Downloads/quickstart$ hugo
* [https://www.digitalocean.com/community/tutorials/how-to-use-git-hooks-to-automate-development-and-deployment-tasks How To Use Git Hooks To Automate Development and Deployment Tasks] on Ubuntu 14.04
Started building sites ...
* [https://dzone.com/articles/using-a-raspberry-pi-as-your-development-server Using a Raspberry Pi as Your Development Server]
 
* [https://youtu.be/7-qAb4YZF2g post-receive on a remote server] (video). Apache web page is used as an example. Note one server-end repository directory and one git ‘local’ directory are used on the remote server.
Built site for language en:
* [https://www.hostinger.com/tutorials/how-to-use-git-hooks/ How to Use Git Hooks?] (with some short examples)
0 of 1 draft rendered
* [https://www.tygertec.com/git-hooks-practical-uses-windows/ Git hooks, practical uses (yes, even on Windows)]
0 future content
* https://githooks.com/
0 expired content
* [https://www.atlassian.com/continuous-delivery/continuous-integration/git-hooks 3 Git hooks for continuous integration]
0 regular pages created
* [https://dev.to/fedekau/using-git-hooks-to-improve-your-day-to-day-workflow-4nl5 Using git hooks to improve your day-to-day workflow]
6 other pages created
* [https://stackoverflow.com/a/7637053 Simple git post-commit hook to copy committed files to a certain folder]
0 non-page files copied
* [https://www.vogella.com/tutorials/Git/article.html#gitcommithooks Git commit and other hooks]
0 paginator pages created
* [https://journals.plos.org/ploscompbiol/article?id=10.1371/journal.pcbi.1004947#sec008 Ten Simple Rules for Taking Advantage of Git and GitHub]. Rule 5: Let GitHub Do Some Tasks for You: Integrate.
0 tags created
* [https://gist.github.com/rmflight/8863882 useful commit hooks for R package dev]
0 categories created
* [https://datawookie.dev/blog/2021/09/pre-commit-hook-for-processing-readme-rmd/ Pre-Commit Hook for Processing README.Rmd]
total in 15 ms
</pre>
 
=== Dev vs Deploy Destinations ===
 
=== Directory Structure ===
 
=== Configure Hugo ===
 
=== Hugo themes ===
* https://themes.gohugo.io/
* https://themes.gohugo.io/tags/documentation/
* https://themes.gohugo.io/slate/ & https://github.com/gesquive/hugo-slate-demo
<pre>
(trusty)brb@localhost:~$ cd Downloads
(trusty)brb@localhost:~$ git clone https://github.com/gesquive/hugo-slate-demo
(trusty)brb@localhost:~$ cd hugo-slate-demo/
(trusty)brb@localhost:~/Downloads/hugo-slate-demo$ hugo server -t slate
</pre>
 
=== Examples ===
* http://noreastrconf.com/
 
=== Gitlab ===
[https://jozef.io/r915-gitlab-pages-own-domain/ Porting and redirecting a Hugo-based blogdown website to an HTTPS-enabled custom domain and how to do it the easy way]
 
== roxygen ==
* https://cran.r-project.org/web/packages/roxygen2/
* http://roxygen.org/roxygen.pdf
* https://stackoverflow.com/questions/26798150/is-there-a-documentation-generator-for-r-like-there-is-for-java
 
== Pelican ==
* [https://fedoramagazine.org/make-github-pages-blog-with-pelican/ Make a Github Pages blog with Pelican]
* [https://rsip22.github.io/blog/create-a-blog-with-pelican-and-github-pages.html Creating a blog with pelican and Github pages]


= Markdown =
= Markdown =
Line 2,144: Line 3,079:
* https://help.github.com/articles/basic-writing-and-formatting-syntax/
* https://help.github.com/articles/basic-writing-and-formatting-syntax/
* [https://help.github.com/articles/relative-links-in-readmes/  Relative links]
* [https://help.github.com/articles/relative-links-in-readmes/  Relative links]
* [https://twitter.com/github/status/1527345223898042368?s=20&t=0b2V5eb3BrKGBzZoOVERJQ Mathematical expressions can now be displayed in Markdown on GitHub]


To show images on readme.md file use
To show images on readme.md file use
<pre>
{{Pre}}
<img src="https://raw.github.com/arraytools/arduino/master/images/%E5%9B%9B%E6%B5%B7%E4%B8%80%E5%AE%B6.jpg"/>
<img src="https://raw.github.com/arraytools/arduino/master/images/%E5%9B%9B%E6%B5%B7%E4%B8%80%E5%AE%B6.jpg"/>
# or relative paths (assume readme.md is at the root of your repository
# or relative paths (assume readme.md is at the root of your repository
Line 2,184: Line 3,120:
</pre>
</pre>


= Continuous Integration, Travis-CI =
= Continuous Integration, Travis-CI, Continuous Deployment =
* [https://rpadovani.com/introduction-gitlab-ci A generic introduction to Gitlab CI]
* [https://rpadovani.com/introduction-gitlab-ci A generic introduction to Gitlab CI]
* [https://appsilondatascience.com/blog/rstats/2018/02/07/circleci.html Continuous integration for your private R projects with CircleCI]
* [https://appsilondatascience.com/blog/rstats/2018/02/07/circleci.html Continuous integration for your private R projects with CircleCI]
Line 2,193: Line 3,129:
* [https://liao961120.github.io/2019/01/30/recreate-rbloggers.html Using Travis-CI to Create R-bloggers for Taiwan]
* [https://liao961120.github.io/2019/01/30/recreate-rbloggers.html Using Travis-CI to Create R-bloggers for Taiwan]
* [https://jozefhajnala.gitlab.io/r/r106-r-package-gitlab-ci/ How to easily automate R analysis, modeling and development work using CI/CD, with working examples]
* [https://jozefhajnala.gitlab.io/r/r106-r-package-gitlab-ci/ How to easily automate R analysis, modeling and development work using CI/CD, with working examples]
* [https://www.iamnagdev.com/?p=907 How to use CI/CD for your ML Projects?] Aug 2020. Gitlab was used. R language was used.
* Wercker
* Wercker
** https://en.wikipedia.org/wiki/Wercker
** https://en.wikipedia.org/wiki/Wercker
** https://devcenter.wercker.com/
** https://devcenter.wercker.com/
** Mentioned in [https://amstat.tandfonline.com/doi/full/10.1080/00031305.2017.1397549#.XPZobstKhNk Infrastructure and Tools for Teaching Computing Throughout the Statistical Curriculum] Mine Çetinkaya-Rundel & Colin Rundel 2018
** Mentioned in [https://amstat.tandfonline.com/doi/full/10.1080/00031305.2017.1397549#.XPZobstKhNk Infrastructure and Tools for Teaching Computing Throughout the Statistical Curriculum] Mine Çetinkaya-Rundel & Colin Rundel 2018
* [https://www.howtoforge.com/tutorial/how-to-install-strider-cd-on-ubuntu-1804/ How to Install Strider Continuous Integration Server on Ubuntu 18.04 LTS]
* [https://www.lynda.com/Jenkins-tutorials/Building-your-CICD-pipeline/5010652/5042899-4.html Building your CI/CD pipeline] from lynda.com
** '''Continuous integration''': Developers work locally and commit to a shared repo. That code is integrated with other code. The code base is tested.
** '''Continuous delivery''': Partner to continuous integration. Allows for building, testing, and delivery with every code change.
** '''Continuous deployment''': Deployment that's done automatically, without human intervention.
* [[Jenkins|Jenkins]]
* [https://www.cloudsavvyit.com/3391/how-to-automate-safe-lambda-deployments-from-git/ How to Automate Safe Lambda Deployments from Git]
* [https://www.cloudsavvyit.com/15115/how-to-build-docker-images-in-a-gitlab-ci-pipeline/ How to Build Docker Images In a Gitlab CI pipeline]


= Mobile apps =
= Mobile apps =

Revision as of 14:40, 29 July 2024

Git

Resources

Github profile

Customize Your GitHub Profile With a ReadMe

git config

5 Git configurations I make on Linux

This has been run the very first time you use git commit.

git commit (commit to the local repository) will ask username/password if we have not logged in (that is, this step has been done before we run git commit). The identity will be saved under ~/.gitconfig file.

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]

Type

git config --list

to confirm the configuration.

Another way: Tweak your Git config for multiple user IDs

ssh key

Privacy email

github

Introduction to version Control in R with RStudio, Git, and Github

  • create a new repo on github. Skip creating License or README since if the new repository is not empty we will have a trouble to do an initial "git push". We can set the new repository private initially until everything is working. If a new repository was created, github will give us an instruction.
  • create a new project folder locally. Make sure ".gitignore" is created/checked in RStudio
    • create new files/directories locally.
    • run "git init".
    • run "git config user.name"
    • run "git config user.email"
    • run "git remote add origin [email protected]:arraytools/heatmap.git" for example where heatmap is my repository's name. The link is under the green Code -> SSH button.
    • run "git branch -M main"
    • run "git push -u origin main"
  • Change the github repository to public if we want to use services like html preview.

R: usethis

git and GitHub in R for the casual user

Most common commands

  1. git config
  2. git init
  3. git clone
  4. git checkout
  5. git add
  6. git commit
  7. git status
  8. git push
  9. git pull
  10. git branch
  11. git merge
  12. git rebase

git stage area

If you have run git add, git rm or git mv command, you put some files in the stage area. In other words git knows about the change, but it is not permanent in the repository. The next commit will include the changes staged.

Should you decide not to commit the change, the status command will remind you that you can use the git reset command to unstage these changes.

For example, if your IDE accidentally deletes a file for you, you can run git reset HEAD FILENAME and git checkout FILENAME to recover the file.

'git mv' vs 'mv'

If we use 'git mv SOMEFILE NEWILE', we will not be able to use 'git checkout SOMEFILE'.

If we try to do that, we will get a message "error: pathspec 'SOMEFILE' did not match any file(s) known to git".

git remote, git push, git clone and remote repository

For a new repository, use git remote add origin (not git remote set-url) before calling git push.

git remote add origin https://github.com/USERNAME/REPOSITORY.git # 'origin' is an alias of the long URL
git remote add origin [email protected]:USERNAME/REPOSITORY.git

git push (push to a remote repository) will ask the username and/or password. To avoid asking the username part,

git remote set-url origin https://name:[email protected]/name/repo.git
git remote set-url origin https://[email protected]/name/repo.git # skip password for security
git remote -v
cat .git/config

OR when you run git clone, use the format

git clone https://[email protected]/name/repos.git

git clone https://[email protected]/name/repos.git repos2 # use 'repos2' as the directory name
# git clone [email protected]:username/repos.git
git remote -v

Either way, we can check the the remote repository by using git config --list or cat .git/config.

git config --global credential.helper cache

git clone when no 'master' branch exists

Warning: remote HEAD refers to nonexistent ref, unable to checkout

In my case, I need to run

git clone ssh://[email protected]/home/git/seqtoolsweb.git --branch gh-pages --single-branch seqtoolsweb

A local copy of origin/master

When we do 'git push', git will automatically create a copy of origin/branchName on our local computer. So origin/branchName is a branch on our local machine that references the remote server branch.

Use 'git fetch' to sync our local copy of origin/branchName with remote's branchName.

Github wiki pages

Documenting your project with wikis from the official Github Help website.

See here for git clone the wiki repository.

git clone https://[email protected]/myusername/foobar.wiki.git
git checkout $(git rev-list -n 1 HEAD -- yourPage)^ -- yourPage

It works on the motionEye wiki page. git clone https://github.com/ccrisan/motioneye.wiki.git

git clone --depth=1

只克隆某个指定分支的最近一次commit. Why use a git clone depth 1?

git fork

First example

My example of working on a new repository called 'network'.

  1. 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.
  2. 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
# It seems 'git push' is the only chance we use the format 'origin master' instead of '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 # You are in 'detached HEAD' state

# 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   # You are in 'detached HEAD' state
                             # I should use "git checkout master" to go back to my local master
                             # OR
                             # use something like "git checkout -b test 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

GUI version of Git software

Should You Use a GUI Git Client?

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.

When installing Git for Windows, there's a tricky option you need to be careful with. You can configure Git to change line endings on text files from Linux (LF only) to/from Windows-DOS (CR and LF).

Linux

Use gitk or gitg (sudo apt install gitg, better than gitk on gnome based Ubuntu). For example,

gitk --all

If we run the gitk/gitg in background (gitg --all &), we will see the tree changed in real time when we run git commands in a terminal.

The problem with gitk is the font is awful.

gitg program (install it by sudo apt install gitg) looks nice.

GitKraken needs to sign in with Github or Gitkraken account.

git-cola: I am lost:(

Mac

  • GitHub Desktop (Electron based)
  • GitKraken, free but not open-source. GitKraken offers a subscription model for additional features and support.
  • SmartGit, free but not open-source for the current version. SmartGit also offers a subscription model for additional features and support.
  • Lazygit is a terminal-based Git client with a user-friendly interface.

Gitk colors and bold

The missing gitk documentation.

  • a yellow dot marks the current HEAD (it seems the yellow dot and bold branch name are always together). Note that if we use "git log" to show the history in the command line, the HEAD is shown in cyan color. See Use gitk to understand git.
  • local branch names are in a green background. See Use gitk to understand git.
  • remote branch names are in a mixed orange/green background. See Use gitk to understand git.
  • the currently checked out branch name is in bold
  • tags are on a yellow background

See a screenshot at Branch - Pull.

ssh key

See Linux > Multiple ssh keys.

If you add a new key to your bitbucket account, you will receive an email about the change.

Github

$ eval "$(ssh-agent -s)"
$ ssh-add -K ~/.ssh/idName_rsa

Multiple git accounts

https://www.cloudsavvyit.com/2245/how-to-manage-multiple-git-accounts-on-one-system/ How to Manage Multiple Git Accounts on One System]

Use command line to create a remote repository

Is it possible to create a remote repo on GitHub from the CLI without opening browser?

curl -F 'login=username' -F 'token=API Token' \
  https://github.com/api/v2/yaml/repos/create -F name=reponame

Set up a new local/remote repository

There is no tracking information for the current branch

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 [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 user.name "YOUR NAME"
git config user.email "YOUR EMAIL ADDRESS"
git config --list # confirm

# Option 1
# Create README.md using Github Web
git pull origin main
# Con: no tracking info is recorded
git branch --set-upstream-to=origin/main master
git pull

# Option 2
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

Rename a remote repository

  1. Go to github.com, open the project and click Settings button on the left-bottom corner. Change the repository name on top.
  2. 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

Suppose we have added ssh key to git server and we want to use ssh key/protocol to automatically access the server instead of entering the password (https protocol). See

$ # the REMOTE below could be 'origin' or any name you define
$ git remote show REMOTE
$ git remote set-url REMOTE ssh://[email protected]/USERNAME/REPOS.git
$ git remote show REMOTE
$ git status  # show local branch is update-to-date with REMOTE/BRANCH.

'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. That is, if you run git clone -o booyah instead, then you will have booyah/master as your default remote branch. See Remote Branches or Use gitk to understand git.

Change GitHub default branch from master to main

'origin master' vs 'origin/master' format

  • origin master format: git push, git pull, git fetch where the branch name is optional.
  • origin/master format: branch, diff, log, merge, reset but don't do it on checkout unless we create a new branch; eg git checkout -b newBranch origin/newBranch. Note that origin/master is a local copy of the branch named "master" on the remote named "origin".

See stackoverflow.

Multiple remotes

Keep track of multiple Git remote repositories

Suppose I have a remote at github.com. I add another remote (bitbucket.com) in my current project.

$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
$ git push -u bitbucket master
$ git status
On branch master
Your branch is up-to-date with 'bitbucket/master'.

$ git branch -a
* master
  remotes/bitbucket/master
  remotes/origin/HEAD -> origin/master
  remotes/origin/master

$ git checkout origin/master             # seems not what I want to do
Note: checking out 'origin/master'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b new_branch_name

HEAD is now at 980fd0b... test fetch +1
$ git status
HEAD detached at origin/master

$ git checkout master
Switched to branch 'master'
Your branch is up-to-date with 'bitbucket/master'.
$ git status
On branch master
Your branch is up-to-date with 'bitbucket/master'.

nothing to commit, working directory clean

$ nano linuxfile
$ git commit -am "multiple remote +1"
$ git push origin master
$ git status
On branch master
Your branch is ahead of 'bitbucket/master' by 1 commit.
  (use "git push" to publish your local commits)

nothing to commit, working directory clean

$ # Question: How to switch back to origin repository to sync?
$ #           How do I change the remote a git branch is tracking?
$ # Method 1: "-u" in git push; see next section about "-u"

$ git push -u origin master
Branch master set up to track remote branch master from origin.
Everything up-to-date
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.

nothing to commit, working directory clean

$ # Method 2: "-u" in git branch; see next section about "-u"
$ git branch master -u bitbucket/master
Branch master set up to track remote branch master from bitbucket.
$ git status
On branch master
Your branch is ahead of 'bitbucket/master' by 1 commit.
  (use "git push" to publish your local commits)

nothing to commit, working directory clean

How to know which remote's master branch to pull/push

$ git status
# On branch master
# Your branch is up-to-date with 'bitbucket/master'

Import/move/migrate (not clone) a repository from one remote to another remote

NB: bitbucket allows to use its web interface to import a remote repository. We just need to give it the URL (eg from Github) and the new repository name. I can use this way to back up some public repositories from github.

Suppose the new remote is on bitbucket.

rsync -av DIRECTORY .
cd SUBDIRECTORY
git remote -v # Examine the current URL
git remote set-url origin [email protected]:USERNAME/DIRECTORY.git
git remote -v # Examine the new URL
git push -u origin --all
git push origin --tags

Other instructions

# fetch all of the remote branches and tags
$ git fetch origin
$ git branch -a
* master
  remotes/origin/develop
  remotes/origin/master
  remotes/origin/release/0.1

$ git checkout -b develop origin/develop
$ git checkout -b release/0.1 origin/release/0.1
$ git branch -a
  develop
  master
* release/0.1
  remotes/origin/develop
  remotes/origin/master
  remotes/origin/release/0.1
# all branches in our repository are stored locally,
# we are ready to move the repository to a new host

# assume we have an SSH-cloned URL of our new repository
$ git remote add new-origin [email protected]:manakor/manascope.git
# This will give us two remotes for the existing repository: 
# the original one (named origin, connected to the existing remote host) and 
# a new one (named new-origin, connected to the new host).

# pushing all branches at once 
$ git push --all new-origin
$ git push --tags new-origin

# make new-origin the default remote,
$ git remote rm origin
$ git remote rename new-origin origin

How to keep two Git repositories in sync

How to keep two Git repositories in sync

$ git clone --mirror https://primary_repo_url/primary_repo.git
$ cd primary_repo.git
$ git remote add --mirror=fetch secondary https://secondary_repo_url/secondary_repo.git

$ git fetch origin
$ git push secondary --all

-u option

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.

“git push -u origin master” vs “git push origin master”

What does the '-u' do in git push. The message: most of time we want to use "-u" option.

Adding '-u' means our local master is tracking remote's master branch. Run "cat .git/config" and look at the [branch 'master'] section -> the 'remote' key. It should have a value 'origin'. The 'merge' key has a value 'refs/head/master'. These information are added automatically when we clone a remote repository.

If we do not put "-u" in git push, it would not be a tracking branch. We can manually edit 'git/config' file or use git branch --set-upstream-to or just "-u" and the branch name (check out git help branch). For example, "git branch -u origin/newbranch newbranch" where newbranch is a local branch name.

Also we can untrack a remote branch by using "git branch --unset-upstream newbranch".

git branch

The git branch command can be used to connect a local branch and a remote branch.

$ git status
# suppose the local master is connected to bitbucket/master

$ git branch master -u origin/master
# now the local master is connected to origin/master
# the local branch name and the remote branch name can be different if you like!
$ git status

Note that gitk can not see the difference when we change the connection of a local branch and a remote branch. Only the git status can reveal the connection.

Example

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

After that

$ cat ~/.gitconfig
[core]
        editor = nano

Multiline commit messages

Once we issue "git commit -a", it opens a text editor. When we write the messages, we want the first line a simple description, the 2nd line empty and the rest of lines a more detailed message. With this way, when we use "git log --oneline", the message is short and we can still use "git log" to see the full message.

.gitignore file

packrat/*
!packrat/packrat.lock
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.

R projects

~*
.Rproj.user
**/*.docs
renv

Whitelist

  • How to Set Up .gitignore As a Whitelist
    *
    !*/
    
    # track this file
    !.gitignore
    
    # whitelist everything in ./config/
    !config/
    
  • Gitignore everything except a subfolder.
    • The first two lines below are required
    • If the directory or filename contains spaces, we need to add a backslash to escape the space character.
    • We cannot use {*.R,*.Rmd} for including two types of files; we need to write these rules separately.
    *
    !*/
    
    !That/Very/Folder/**
    !Also/This/Another/Folder/**
    !Primary\ analysis/**/*.R
    !Primary\ analysis/**/*.Rmd
    

git commit message

git status, multiple branches

Your branch is up-to-date with 'origin/master'

$ git status
On branch master
Your branch is up-to-date with 'origin/master'.

nothing to commit, working directory clean

http://stackoverflow.com/questions/27828404/why-does-git-status-show-branch-is-up-to-date-when-changes-exist-upstream

When git status says up to date, it means "up to date with the upstream status that was retrieved last time we did a fetch" which is not the same as "up to date with the latest live status of the upstream".

nothing to commit, working directory clean

If we have a new branch on local which does not exist on remote, it is useful to use the git remote show REMOTENAME command to find out what branches are tracked.

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

$ git remote show bitbucket
* remote bitbucket
  Fetch URL: ssh://[email protected]/XXXXXX/toy.git
  Push  URL: ssh://[email protected]/XXXXXX/toy.git
  HEAD branch: master
  Remote branch:
    master tracked
  Local ref configured for 'git push':
    master pushes to master (up to date)
$ git diff bitbucket/master
diff --git a/linuxfile b/linuxfile
index 894674f..b9f3a6f 100644
--- a/linuxfile
+++ b/linuxfile
@@ -1,6 +1,6 @@
 test ssh key (mod in mint again)
 changed from 'newbranch'
-another line 
+mod from newbranch 
$ git push bitbucket master
Everything up-to-date

Note that

  1. The last command is NOT working since only the local/master can be pushed to remote/master. Local/newbranch cannot be pushed to remote/master.
  2. The local 'master' branch can be pushed to either remote1/master or remote2/master.

Remove untracked files

Go to the top directory of the local repository (or it won't work), then run

$ git clean -f -n  # dry run
$ git clean -f     # real run

See the discussion.

Back up untracked files

7 Git tricks that changed my life

$ git ls-files --others --exclude-standard -z |\
      xargs -0 tar rvf ~/backup-untracked.zip

Remove deleted files

git ls-files --deleted
git rm `git ls-files --deleted`

Tell if a file is git tracked

How to tell if a file is git tracked

git ls-files --error-unmatch <file name>

# If a file is tracked,
git ls-files --error-unmatch  Additional17/Additional17.Rmd
Additional17/Additional17.Rmd

# If a file is not tracked,
git ls-files --error-unmatch  Datasets_clinical/data.clin.rds
error: pathspec 'Datasets_clinical/data.clin.rds' did not match any file(s) known to git
Did you forget to 'git add'?

Undo/Reset

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  # no output
$ git checkout -- Dirname   # no output
$ git checkout -- '*.R'
$ 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

See also git checkout --FileName.

Unstaging a Staged File

$ git reset HEAD Filename
$ git reset    # unstage all due changes

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
$ git reset --hard HEAD^  
# discard the last commit and will be abandoned eventually after git did a garbage collection

$ git reset --hard <tree-ish>

Undo git commit

We can use git revert or git reset. See Undoing Commits & Changes from Atlassian.

  • Best for public shared repositories
    $ git revert --no-edit 6d8dafe 
    # using the first 7 characters of the identifier is more than enough
    # Previous commits still be kept
  • Best for local private changes
    $ git reset --soft HEAD~1 # reset the HEAD (the last commit) to one commit before in the log history.
    
    $ git reset --hard a1e8fb5
    # Some middle commits will no longer exist in the commit history
    
    $ git reset --soft HEAD~
    # --soft means reset into staging
    # HEAD~ or HEAD^ means to move to commit before HEAD
    # http://stackoverflow.com/questions/927358/how-do-you-undo-the-last-commit
    
    $ git reset --soft HEAD^^
    # move to the grandparent commit

Undo git push

http://stackoverflow.com/questions/1270514/undoing-a-git-push

git checkout master
git reset --hard cc4b63bebb6
git push origin +master

change commit message

https://help.github.com/articles/changing-a-commit-message/#commit-has-not-been-pushed-online

To change the last committed message

git commit --amend # Enter and save
git push --force origin master

Remove a file from a Git repository without deleting it from the local filesystem

git rm --cached mylogfile.log   # file
git rm --cached -r mydirectory  # directory
git rm --cached <path_to_the_.DS_Store-file>

Git reset revert rebase commands

Delete any untracked files or directories

How to remove local (untracked) files from the current Git working tree?

# Print out the list of files which will be removed (dry run)
git clean -n
# Delete the files from the repository
git clean -f
# To remove directories, run 
git clean -f -d # OR git clean -fd
# To remove ignored files, run 
git clean -f -X # OR git clean -fX

git clone vs git pull

What is the difference between pull and clone in git?

git fetch vs git pull

git fetch origin master

git merge origin/master

# git push origin master

git fetch

Use git fetch as often as possible; before git push or before you go offline or before you work.

$ git fetch
$ git log --oneline -5 origin/master
$ git branch  # local only
$ git branch -r # remote only

$ git checkout master
$ git merge origin/master
$ git log --oneline master

git fetch vs git pull

  • If I am in the middle of committing something and get some work going on, I will do a git fetch to see what's on the server.
  • If I am starting my work without making any changes/commits yet, I'll do a git pull. I want every thing on the server as my starting point.

git fetch and gikt

After we run git fetch origin master, we will see the remote commits from gitk if we add --all option.

gitk --all
# OR
gitg --all

git pull

git show: show details on a commit

git show SHA
git show --name-status SHA # list the filenames along with an indicator (A for added, M for modified, D for deleted)

Use 'f' to move forward and 'b' to move backward.

git log

log in a branch or origin/master

View log from origin/master (it's a tracking copy on our local computer; it's not the actual remote branch)

$ git log myBranch

$ git log --oneline -5 origin/master # last 5 commits from origin/master

git log on a specific file

git log FILENAME

git show change history of a file

Terminal

git log -p FILENAME  # show changes
git log --follow FILENAME # doesn't show changes

GUI

gitk FILENAME

git log show changed files only

How to View Commit History With Git Log

git log --name-only 

git log --stat # show how many lines of changes in files

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.

filtering by a date

git log --since=2019-01-01

git log --until=2019-01-01

git log --until="3 days ago"

git log --after=2.weeks --before=3.days

filter by a name

git log --author="xxx"  # author string contains "xxx"

filter by a keyword in log

Search for a string in the log

git log --grep='String'

filter by commits

git log bd210165..HEAD

git log <SHA>..<SHA>

Count number of commits

git rev-list --count master

Best ones: adding --graph --all

git log --graph --all --stat # just see lines of changes, sha1 is complete

git log --graph --all --stat --abbrev-commit # same as above but sha1 is short

git log --all --abbrev-commit -p FILENAME  # logs from all branches, not just the current branch

To shorten the command,

git config --global alias.lg "log --graph --all --stat --abbrev-commit"
git lg

This command adds a new entry to your Git configuration file (usually located at ~/.gitconfig).

Search in the code?

  • You can search in Git even if you aren't sure which commit—or even branch—you made your changes. See 7 Git tricks that changed my life
    $ git rev-list --all | xargs git grep -F 'KEYWORD'
    

branch - not the same as in CVS

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.

list local and remote branches

mac$ git branch # list branches in local repo
  branch0323
* master
mac$ git branch -a # list all remote branches
  branch0323
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/master

"--track" option

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 local or remote branch, checkout a remote branch?

We can use git branch or git checkout to create a new branch.

git branch testing    # do not switch
git log --oneline --decorate

git checkout -b <new-branch> # creates and checks out <new-branch> off the current HEAD
git checkout -b <new-branch> <existing-branch>

Pay attention to the keywords 'HEAD', 'master' and 'testing' in this case.

To create a new branch and switch to the new branch

git status
git checkout -b myBranch
# OR create a new branch starting at the commit with an identifier
# git checkout -b myBranch XXXXXXX
git status

git log

To create a new branch based on a remote branch. Remote branch is just like any branch with one exception: you can't check them out. You can merge with them. You can see what's in them. But you can't check them out. Instead you need to create a new branch which tracks it.

# Method 1: it does not move HEAD.
git branch myBranch origin/myBranch
git log --oneline -5 myBranch   # red color = a local copy of the remote repo, green color = local repo

# Method 2: it switches to the new branch immediately
git checkout -b myBranch origin/myBranch

To create a remote branch, git push origin MyBranch; see Git Branch from Atlassian.

Delete a branch locally or from the remote

How to Delete a Branch in Git Locally and Remotely

Cf. Push to the remote branch by git push -u origin newBranch; git branch -r.

Delete a local copy of a branch.

# Since you can't delete a branch you're on, switch to the master branch. 
git branch
git checkout master
git branch -d myBranch

To delete the branch from the remote:

git push origin :myBranch

# OR
git push -d origin myBranch

# Checking
git branch -r

Switch branches in local repository

git checkout testing
git branch
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

Note that when you run git pull without specify the branch name (eg gh-pages from the current local branch), it won't pull the latest from another branch (eg master).

Git worktree

Load different R package versions at once with git worktree

git checkout

  • https://guide.freecodecamp.org/git/git-checkout/. It compares "git checkout -b" and "git checkout -B".
    • git checkout -b NEW-BRANCH-NAME will create and checkout out a new branch.
    • git checkout -B BRANCH-NAME START-POINT will checkout a New Branch or Reset a Branch to a Start Point.
    • Generally, Git won’t let you checkout another branch unless your working directory is clean, because you would lose any working directory changes that aren’t committed. You have three options to handle your changes: 1) trash them, 2) commit them, or 3) stash them.

Get the short Git version hash of HEAD

$ git rev-parse --short HEAD
38733fd

# Compare to 
$ git log --oneline

Detached head/HEAD detached from xxxxxxx when you check out from a commit

  • When you run git checkout XXX (where XXX represents the commit hash or commit ID), the following happens:
    • Your working directory and staging area (index) are updated to match the state of the specified commit.
    • All files are reverted to the state they were in at that commit.
    • You are now in a detached HEAD state, meaning you’re not on any branch but directly on the commit.
  • Before we run "git checkout", use "git status" to make sure the current local repository is clean.
  • Better no to run "git checkout origin/XXX" or "git checkout SHA1" or "git checkout TAG". The right way is to create a local branch and then switch to that. git checkout -b branchXYZ origin/branchXYZ.
  • HEAD detached from origin/master.
  • Detached HEADS. When it points to a branch, Git doesn't complain, but when you check out a commit, it switches into a “detached HEAD” state. The point is, your development should always take place on a branch—never on a detached HEAD.
  • How Do You Fix a “Detached HEAD” in a Git Repository?

See Fix a Git detached head?

(2020-03-23) I must made some mistake. See the following and the solution is by following the suggestion from the on-screen message.

git checkout XXXXXXX
cp myfile /tmp/myfile
git checkout origin/master  # begin to mess up; why git allows this action?
nano myfile # merge something from the old file '/tmp/myfile'
git commit  # repeat the commit action again for another change
git status  # HEAD detached from origin/master
git checkout master 
# Warning: you are leaving 2 commits behind, not connected to
any of your branches:
# If you want to keep them by creating a new branch, this may be a good time
to do so with:

# git branch <new-branch-name> 854c654

# Switched to branch 'master'
# Your branch is up to date with 'origin/master'.

# Solution 1:
git branch branch0323 854c654
git branch # check my current branch
# Solution 2:
git checkout -b branch0323

git merge branch0323
# Done

(suggested by bing chat)

# Discard changes
git reset  # Unstage all changes that have been added to the index (i.e., that are set to be committed)
git checkout -- .  # To revert all unstaged changes (i.e., changes that you’ve made but have not yet added to the index)
git status         # Don't worry about untracked files

git checkout HEX   # HEAD -> HEX
# You are in 'detached HEAD' state. You can look around, make experimental
# changes and commit them, and you can discard any commits you make in this
# state without impacting any branches by switching back to a branch.
git log
git checkout main  # HEAD -> main

Good practice

See Get an old commit and merge some of its code to the current code.

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  # step 1. Move back to master for merging
git merge hotfix     # step 2. Merge the hotfix branch into the master 
git branch -d hotfix # step 3. Delete the branch

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

push the new branch to remote

We can have a branch on our local computer only. We can also have a branch that is shared on the remote.

# make sure we are at the right branch
$ git branch -a 
  master
* newbranch
  remotes/bitbucket/master
  remotes/origin/HEAD -> origin/master
  remotes/origin/master
$ git push -u bitbucket newbranch # '-u' is to add the tracking information
$ git status
On branch newbranch
Your branch is up-to-date with 'bitbucket/newbranch'.

nothing to commit, working directory clean

If another machine runs git pull, it will get the new branch. The result can be seen by gitk --all.

pull

Suppose we are at the 'newbranch'. Some files are modified and committed to 'newbranch' (these actions are only done locally).

If someone modified files and committed to the 'master' branch, then when we run git pull (keep it in mind that we are still on newbranch) the files we just modified & committed OR even any files aren't affected since git pull is pulling files from the 'master' branch.

If we use the gitk --all or git log --graph --all --oneline --decorate command, we may see (remote has an orange background color, branch has a green background color, a yellow dot marks the current HEAD)

  • remotes/bitbucket/newbranch
  • remotes/bitbucket/master
  • newbranch (local)
  • master (local)

These 4 branches could be on different nodes. Note. gitk output is easy to read but git log gives the SHA information. The screenshot from git log below does NOT use the --decorate option.

Git branch.png

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 -a          # show all remotes' branches too
git branch -d testing

Branch workflows

3.4 Git Branching - Branching Workflows

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, tracking branches

https://git-scm.com/book/ch3-5.html

Remote references are references (pointers) in your remote repositories, including branches, tags, and so on.

Pushing:

git ls-remote (remoteName)
git remote show (remoteName)  # add RSA key fingerprint if the git is using the ssh protocol

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. Tracking's advantage is to save our typing. Without tracking information, we need to specify the remote branch name when we want to interact with it (git fetch, git push, git pull).

When you clone a repository, it creates a master branch that tracks origin/master. However you can set up other tracking branches if you wish - ones that track branches on other remotes, or don't track the master branch.

If you create a new branch on your local repository, this new branch by default has no tracking information to a remote branch. So when we use "git push origin newBranch" (no "-u"), it does not add the tracking info. We can use --set-upstream-to or -u option when we use "git branch" to set up the tracking information; see "git help branch". One example: git branch -u origin/newBranch newBranch. Use cat .git/config to double check.

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

# if the branch name you're trying to checkout (a) does not exist and (b) exactly
# matches a name on only one remote, Git will create a tracking branch for you
git checkout serverfix

# set up a local branch with a different name than the remote branch
git checkout -b sf origin/serverfix # your local branch sf will auto pull from origin/serverfix

# if you ALREADY have a local branch and want to set it to a remote branch
# you just pulled down, or want to change the upstream branch you're tracking.
git branch -u origin/serverfix

# see what tracking branches you have set up in your local repo
git branch -vv

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

See git fetch and git-merge.

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.

Checkout previous checkout's commit

How To Make Life Easier When Using Git

git checkout -

diff between two revisions

git diff <revision_1>:<file_1> <revision_2>:<file_2>

# Better to run git config --global diff.tool meld BEFORE
git difftool <revision_1> <revision_2> # Warning: it will open each file one by one.
                                       # It is not a good idea if many files have changed.
                                       # Better to use "-d" or "--dir-diff" option
git difftool <revision_1> <revision_2> FILENAME -y
                                        # just compare the file <FILENAME>

git diff master..test                   # between the tips of the two branches

git diff origin/master..master          # useful if origin/master is behind the local's master

git diff test                           # between your current working directory and the 
                                        # (remote) snapshot on the 'test' branch.

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).

Gitk2.png Gitk.png

git difftool, mergetool & meld

Setting up and using Meld as your git difftool and mergetool

View differences of branches with 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 difftool <revision_1> <revision_2>

It will open the first file in Meld. After we close the first file, it will launch the 2nd file in Meld, and so on.

The current meld has a new tool to compare git versions. New comparison > Version control. Select a git directory. It will show the differences of the local master and the current folder (left = local master, right = current dir). I can also launch the comparison from the command line:

git difftool -d master  # '-d' means a directory comparison
                        # left = current master, right = current dir 

# OR
git branch myBranch SHA1
git difftool -d myBranch # compare myBranch with my current branch
                         # left = myBranch, right = current master

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

Meld and Diffuse

How to build Meld 3.20 on Ubuntu. Note when we install meld using apt, it is installed under /usr/bin/meld.

git clone https://gitlab.gnome.org/GNOME/meld.git

cd meld
git checkout meld-3-20
python3 setup.py install --prefix=/usr

sudo apt update
sudo apt upgrade
sudo apt install intltool 
sudo apt install libxml2-utils
sudo apt install libglib2.0-dev-bin

sudo apt install libglib2.0-dev
sudo apt install libgirepository1.0-dev
sudo apt install libcairo2-dev
pip3 install pycairo
pip3 install PyGObject 

sudo python3 setup.py install --prefix=/usr
meld

To make meld to be in the right click menu, follow

Another method of comparing two files without using the 'browse' button will be to use the command line.

The 'nautilus-compare' program does not work from my testing on Ubuntu 14.04.

Some thoughts

  • I install kdiff3 (<2 MB to download) and the 'File' -> 'Reload' (F5) function there works though it shows an extra space on the place I modified.
  • Beyond Compare (commercial $30/$60, trial version can be downloaded)
  • diffuse. When I modified a file, diffuse can detect a change and ask me to reload the file. I am using the apt-get to install the software and the version number is 0.4.7 (2014). To copy lines from left panel to right panel, use 'Ctrl + Shift + >' or the Copy Selection Right icon. One drawback is it cannot save the history from the GUI though we can use the command line to include the file names in the arguments.
  • Alternatively we can use WinMerge on Linux. To do that, install Wine on Ubuntu. Download Winmerge (I am using 2.14.0). Then on a terminal, run the following command. At the end, WinMerge will be launched. WinMerge can also be launched from Mint Menu -> Wine -> WinMerge. One problem is I cannot increase the font size (though acceptable) from View -> Select Font.
wine WinMerge-2.14.0-Setup.exe

git-split-diffs

git-split-diffs. This currently requires node version 12 or newer to run.

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

http://stackoverflow.com/questions/21457407/git-gui-perpetually-getting-this-repository-currently-has-approximately-320-lo

git gc --aggressive

git commit -am

works only for simple edits. It does not work for renaming files, etc.

For initial file commit, use git add -A and git commit -m XXX. git commit -a will commit all changes to tracked files. But untracked files will not be committed at any point. Read Git commit -am does not work on initial commit. Why?.

git diff HEAD

This command shows the differences between the current working directory (which represents the current code) and the most recent commit (i.e., HEAD).

git diff --staged

git diff -- file.a file.b

git checkout -- FileName

to recover a modified/deleted file where -- is a linux notation, not specific to git. See Difference between "git checkout <filename>" and "git checkout -​- <filename>".

rm FileName
git pull   # do nothing
git status # still miss 'FileName'
git checkout FileName

The following examples give a good clarification.

git checkout README     # would normally discard uncommitted changes
                        # to the _file_ "README"

git checkout master     # would normally switch the working copy to
                        # the _branch_ "master"

git checkout -- master  # discard uncommitted changes to the _file_ "master"

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

git merge

https://www.atlassian.com/git/tutorials/using-branches/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.

Resolving merge conflict from lynda.com

Merge does not delete a local branch

Running git merge will not delete any local branches, even if the corresponding branch on the remote repository has been deleted. The git merge command is used to integrate changes from one branch into another, it does not delete branches.

If a branch has been deleted from the remote repository, you can delete the corresponding local branch manually using the git branch -d <branchname> command (or git branch -D <branchname> to force delete).

However, if you want your local repository to reflect the state of the remote repository, including the deletion of remote branches, you can use the git fetch command with the --prune option: git fetch --prune. This command will delete any tracking branches in your local repository that no longer exist on the remote repository.

Let’s say I’m in a branch ‘b’ that has been deleted from the remote. If I am currently on branch ‘b’, running ‘git merge’ will not perform any merge and will issue a message: ‘fatal: No remote for the current branch.’ I need to switch to the master branch in order to run ‘git merge’.

Merge a local branch to the local master

git checkout master
git merge newBranch

Merge a remote branch to the local master

git checkout master
git fetch
git merge origin/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

  1. git fetch
  2. git diff master origin/master (- part is from master, + part is from origin/master)
  3. git merge origin/master (possibly need to run nano FILENAME + git add + git commit or run git mergetool + git commit if there is a conflict, OR a text editor will be opened to let you enter the commit message if there is no any conflict). Use git config --global core.editor nano to set the default text editor if this was not done yet; see Git configuration.
  4. git push.

Note that

  • If we are using git pull instead of git fetch + git merge, we will be directed to the nano editor to enter a commit message if there are no conflicts; however, if we use git fetch, we will NOT be directed to nano editor).
  • If we directly run git push (even on non-conflict file) without running git pull, 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 stash

When you have uncommitted changes and want to switch to a specific commit using git checkout <commit_id>. Stashing allows you to save your uncommitted changes temporarily. It’s like putting them in a drawer so you can work on something else.

git status # there maybe some modified but not committed files
git stash # save your changes in a “stash” without committing them.

git checkout -b <new-branch> <commit-id>
          # it'll switch to <new-branch>
git branch

git checkout main
git stash apply

To remove a local branch (a branch on your local machine), use the following command: git branch -d local_branch_name.

If the local branch contains unmerged changes or unpushed commits, use -D instead of -d to force deletion: git branch -D local_branch_name .

Practices/collaboration workflow

Collaboration workflow example from lynda.com

Create a branch from the current HEAD for experiment

Suppose we want to experiment on a new plan, we can create a new branch ('newbranch') in our local repository, merge newbranch to master and push to the remote.

git checkout master
git fetch
git merge origin/master

git branch newbranch       # step 1 create a new branch called 'newbranch'
git checkout newbranch     # step 2 switch to the 'newbranch' branch
                           # We can combine steps 1 & 2 by 'git checkout -b newbranch'
nano FILENAME              # step 3 modify some files, create new files, ...
git add FILENAME
git commit                 # step 4 commit changes to newbranch
git checkout master        # step 5 check out the master branch
git branch -a              # (optional) verify we are on the master branch

git fetch                  # double check nothing has been committed to the remote

git merge newbranch        # step 6 merge newbranch to master
git push -u origin master  # step 7 push (local) master to remote/master

Another scenario is we push our local newbranch to the remote newbranch. Then we can skip steps 5 & 6 and do git push -u origin newbranch in step 7.


Question: If we have multiple remotes, how do we know if the local master is the same as the origin/master or origin2/master? Answer: git diff.

Get an old commit and merge some of its code to the current code

$ git checkout -b testBranch SHA1 (NB. if we want to checkout an old commit, always create a branch)
$ nano someFile
$ git checkout master # OR "git checkout -"
$ git merge testBranch
$ (optional) git branch -d testBranch

Or without using "git merge"

$ git checkout -b testBranch SHA1 (NB. if we want to checkout an old commit, always create a branch)
$ cp someFile /tmp/
$ git checkout master # OR "git checkout -"
$ meld /tmp/someFile someFile
$ git commit
$ (optional) git branch -d testBranch

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 a release

https://git-scm.com/book/en/v2/Git-Basics-Tagging

$ git tag  # or add "--list" or add "-l"
$ git tag -l "v2*"  # add a filtering list tags starting with "v2"
$ git tag -l -n     # list tags with annotations

# Create annotated tags
$ git tag -a v1.4 -m "my version 1.4" 
$ git tag
v1.4
$ git show v1.4
$ git diff v1.0..v1.1

# Tagging Later
$ git log --pretty=online
$ git tag -a v1.2 9fceb02

# Delete a tag
$ git tag -d v1.1

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

# Delete remote tags like remote branches
$ git push origin :v1.1   # OR
$ git push -d origin v1.1

Check out tags just like any sha, but it has a profound effect if we later commit something (Detached HEAD state).

$ git checkout -b newBranch v1.1
$ git checkout v1.1

Getting Notifications for New GitHub Project Releases

setting up SSH access on the server side

Follow the instruction on git-scm.com. It works.

I tested it by

  1. create a git account (called 'git') on my host machine.
  2. sudo to create a directory called /opt/git/project.git. Change the owner to 'git'. Cd to the directory and initialize it.
  3. Create two virtual machines (vb1 and vb2). Creating a username 'david' on vb1 and a user name 'joseph' on vb2.
  4. Create ssh key for both 'david' and 'joseph'. Ssh to copy their ssh keys to git account.
  5. 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.
  6. Switch to vb2 and run git clone (no password is needed). The user can modify the code and commit & push files to the server.
  7. 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.

Create a git server

  1. Install git and git-shell
  2. $ sudo apt update
    $ sudo apt install git
    $ sudo nano /etc/shells  # ADD /usr/bin/git-shell
  3. Setup a dedicated (non-sudo) git user
  4. $ sudo adduser --disabled-password git
    $ sudo su git
    $ cd
    $ mkdir ~/.ssh && chmod 700 ~/.ssh
    $ touch ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys
    $ nano ~/.ssh/authorized_keys # add the public keys of any users 
                           # you want to access your private git server
    $ sudo chsh git -s $(which git-shell)
  5. Create individual repo directories
  6. $ cd /home/git
    $ sudo mkdir ios-backup-extractor.git
    $ cd ios-backup-extractor.git && sudo git init --bare && cd ..
    $ sudo chown -R git.git ios-backup-extractor.git/
  7. Use your private git repo
  8. $ git clone git@<IPADDRESS>:<repo-name> ~/git/
    $ git remote add origin git@<IPADDRESS>:<repo-name>.git

Create a git server (github like w/ web interface)

If we like to create a github-like web interface, check out GitLab. See

Below is my note

  1. https://about.gitlab.com/downloads/ contains steps of setting up Gitlab.
  2. By default, the domain name you have entered in setting up gitlab will be the URL you will use to access gitlab.
  3. Use the recommended method to install gitlab. Nginx will be installed as an http server.
  4. The root username and password is root and 5iveL!fe.
  5. 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.
  6. User's password is used to access GitLab web interface only. It is not used for pushing commits.
  7. 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'.
  8. 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'.
  9. The username will affect path to all personal projects; e.g. [email protected]:newuser/test2.git.

Gitlab2.png Gitlab1.png Gitlab3.png

How to Install Gitlab with PostgreSQL and Nginx on Ubuntu 15.04 from howtoforge.com.

Gitolite (favored by Ubuntu)

This approach involves the following steps

  1. Installing a gitolite server
  2. Gitolite configuration
  3. Managing gitolite users and repositories
  4. Using your server

Not sure about any advantages of this approach?

Graphical tool, app

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

Tig

How to use Tig to browse Git logs

gitk and git-gui

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.

GitKraken

#1 of Top 20 Dev Tools for 2019

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

Permission denied (publickey)

The error happens on either github or bitbucket.

Some resources:

old mode new mode

See this post

git config core.filemode false

Temporarily move to a branch and then move back

# suppose we have 3 commits so far and we are at commit 3 now.
git status
git log                        # show 3 commits
git checkout sha1_commit_1     # move to commit 1
git log                        # only show 1 commit
git checkout master            # go back to the original 3 commits
git status

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.

Gitmergetool.png

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:

Toy merged.png

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' or 'git push origin' instead of 'git push -u origin master'.

$ git push bitbucket
warning: push.default is unset; its implicit value is changing in
Git 2.0 from 'matching' to 'simple'. To squelch this message
and maintain the current behavior after the default changes, use:

  git config --global push.default matching

To squelch this message and adopt the new behavior now, use:

  git config --global push.default simple

When push.default is set to 'matching', git will push local branches
to the remote branches that already exist with the same name.

In Git 2.0, Git will default to the more conservative 'simple'
behavior, which only pushes the current branch to the corresponding
remote branch that 'git pull' uses to update the current branch.

See 'git help config' and search for 'push.default' for further information.
(the 'simple' mode was introduced in Git 1.7.11. Use the similar mode
'current' instead of 'simple' if you sometimes use older versions of Git)

I guess 'simple' (the default) is what we/beginners usually want. Run

git config --global push.default simple

Search/find a deleted file from the commit history

https://stackoverflow.com/questions/7203515/git-how-to-find-a-deleted-file-in-the-project-commit-history

For example, the noweb/code.pdf file was mentioned in the Readme file but it is missing from the CRAN's survival package.

$ git log --all --full-history -- noweb/code.pdf
commit 1f0dbc538e9147ab264c5215cf205b9b3bc171cb
Author: Terry M Therneau <[email protected]>
Date:   Sun Jun 26 14:19:51 2016 +0000

    version 2.39-5

commit ec6b50c973b9298a5f1aeb839b2d04d3448e69de
Author: Terry M Therneau <[email protected]>
Date:   Wed May 11 11:45:26 2016 +0000

    version 2.39-4

commit 38a8ccc0fb014c2b2bfbb2b5153b419e615b01ba
Author: Terry M Therneau <[email protected]>
Date:   Sat Apr 16 19:26:46 2016 +0000

    version 2.39-2

Here we see code.pdf file existed in version 2.39-2 and was last seen in version 2.39-5.

To restore the deleted, we use

git checkout 38a8ccc -- code.pdf

Note that I follow the instruction to add the caret sign (^) at the end of SHA, I'll get an error pathspec 'code.pdf' did not match any file(s) known to git. My git version is 2.7.4.

However, for another file, I do need to use caret.

git log --all --full-history -- src/coxfit2.c

git checkout 68e5adc1d1486e2b1daa7db9203fd9226e029992^ -- src/coxfit2.c

Removing files/a folder from a repository

To remove the file called Rakefile:

$ git filter-branch --force --index-filter \
  'git rm --cached --ignore-unmatch Rakefile' \
  --prune-empty --tag-name-filter cat -- --all

$ git push --all --force

Pull request

Cannot see new files added to my git working directory

Cannot see new files added to my git working directory. It happened when I include a new subdirectory which comes from other people's repository. The solution for my case is to rm .git/index and then run git add/commit/push. Next time I need to remove the .git from that subdirectory first.

Binary files and why is my .git folder so big?

Binary files will be tracked by git too.

https://www.reddit.com/r/git/comments/4xsh26/why_is_my_git_folder_so_big/

git gc --aggressive --prune

It seems there is no way I can remove binary files (history) from .git folder.

Large files and storage limit

Less than 100MB

 
$ git push -u origin master
Counting objects: 115, done.
Delta compression using up to 12 threads.
Compressing objects: 100% (100/100), done.
Writing objects: 100% (115/115), 97.54 MiB | 4.48 MiB/s, done.
Total 115 (delta 16), reused 0 (delta 0)
remote: warning: GH001: Large files detected. You may want to try Git Large File Storage - https://git-lfs.github.com.
remote: warning: See http://git.io/iEPt8g for more information.
remote: warning: File GSE48215/breastcancer-bt20_raw.vcf is 79.57 MB; this is larger than GitHub's recommended maximum file size of 50.00 MB
To https://github.com/arraytools/seqtools_testdata.git
 * [new branch]      master -> master
Branch master set up to track remote branch master from origin.

It looks like all files are uploaded successfully.

One annoying thing about github is when we download the repository it automatically add a folder name (REPOSITORY-BRANCH) at the top. For example, it creates 'seqtools_testdata-master'.

$ unzip -l ~/Downloads/seqtools_testdata-master.zip 
Archive:  /home/odroid/Downloads/seqtools_testdata-master.zip
9f5e132bcfd2007f5fc1fb4ee465c5b307b3e85a
  Length      Date    Time    Name
---------  ---------- -----   ----
        0  2016-06-01 21:05   seqtools_testdata-master/
        0  2016-06-01 21:05   seqtools_testdata-master/GSE11209-master/
 46737374  2016-06-01 21:05   seqtools_testdata-master/GSE11209-master/SRR002051.fastq
 46675548  2016-06-01 21:05   seqtools_testdata-master/GSE11209-master/SRR002059.fastq
        0  2016-06-01 21:05   seqtools_testdata-master/GSE11209-master/Saccharomyces_cerevisiae/
...

Larger than 100MB

remote: error: File hg19/chr1.fa is 242.46 MB; this exceeds GitHub's file size limit of 100.00 MB
remote: error: File hg19/chr1.fa.bwt is 237.70 MB; this exceeds GitHub's file size limit of 100.00 MB
remote: error: File hg19/chr1.fa.sa is 118.85 MB; this exceeds GitHub's file size limit of 100.00 MB
To https://github.com/arraytools/GSE48215.git
 ! [remote rejected] master -> master (pre-receive hook declined)

git submodule

Import from CVS

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

Zip up the folder but exclude the .git subfolder

zip -r myproject.zip myproject -x *.git*

On Mac, we should add --exclude=*.DS_Store* to exclude Mac OS X directory display metadata files.

Preview PDF files

  • It has a built-in support.

Open a PDF file from raw.githubusercontent.com

Preview HTML files from Github and Bitbucket

http://htmlpreview.github.io/

Example: data.table cookbook

General resources

Backup all your GitHub and GitLab git repositories

A simple way to backup all your GitHub and GitLab git repositories

Git hosting services

Self-hosted

Gitlab

Compared to Github, Gitlab can

  1. host private projects for free
  2. host static web pages on http://pages.gitlab.io/.

Host web site

http://pages.gitlab.io/

http://monitor.gitlab.net/

How to install and configure Gitlab on Ubuntu

Running an R Script on a Schedule

Bitbucket

ssh-keygen -R bitbucket.org && curl https://bitbucket.org/site/ssh >> ~/.ssh/known_hosts

ssh [email protected] host_key_info # verify

Large files

Manage huge files in Bitbucket with Git LFS

Gitbucket

How to Install GitBucket with Nginx on Ubuntu 18.04 LTS

Github

Github Status

Gist

  • Creating a personal access token
  • gist-backup, Backup (clone) all your own gists
  • Downloading All Public GitHub Gist Files (it works, python3)
    import requests, json
    headers = {"content-type" : "application/json"}
    url = 'https://api.github.com/users/mydatahack/gists'
    r = requests.get(url, headers = headers)
    metadata_file = './data/my_gist_list.json'
    # Getting metadata
    prettyJson = json.dumps(r.json(), indent=4, sort_keys=True)
    f = open(metadata_file, 'w')
    f.write(prettyJson)
    
    print('Metadata obtained as {}'.format(metadata_file))
    
    # Downloading files 
    data = r.json()
    counter = 0
    for i in data:
        files_node = i['files']
        file_name = [k for k in files_node][0]
        r = requests.get(files_node[file_name]['raw_url'])
        f = open('./data/{}'.format(file_name), 'w')
        f.write(r.text)
        f.close()
        print('Downloaded {}'.format(file_name))
        counter += 1
    
    print('{} files successfully downloaded.'.format(counter))
    

Large files (eg binary)

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
  • Compare git remote add (set up remote url) and git remote set-url (switch remote url)
  • 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.

Archive a repository

Host web site: pages and wiki

# pip install ghp-import
Rscript -e "devtools::build_vignettes()"
ghp-import inst/doc
git push
# Create a new repository in Github using the web interface
# clone it to the local pc
git clone https://github.com/user/repository.git

# create a new branch
cd repository
git checkout --orphan gh-pages
git status # double check we are in the gh-pages branch
git rm -rf .

# create new files. 
touch index.html
git add -a 
git commit -m "Adding pages"

# push to github
git push origin gh-pages

# see the web page at
# http://username.github.io/repository/.

Some Examples:

Create a documentation site with Docsify and GitHub Pages

GitHub Action to Deploy Static Assets to GitHub Pages

ghpages

Github Docker Container Registry

How to Get Started with Github’s New Docker Container Registry

Github Actions (GHA)

  • Self-hosted runners.
    • Self-hosted runners for GitHub Actions is now in beta
    • setup-r@v1 stalls on a self-hosted ubuntu-18.04 runner? #173. It ask sudo password for apt command.
    • https://github.com/tcardonne/docker-github-runner This Docker image allows you to create your own runners on Docker.
    • Deploying Self-Hosted Github Actions Runners with Docker
    • Google: githubactions self host apt command
    • A working example (ga_readme private repo). Note the runner has an access all to my host OS's apps like R/Rscript and all R's libraries. We can put the GHA in a docker; see the next item for a step-by-step tutorial.
      # For convenience I extract the actions-runner to the repo directory and I add actions-runner to .gitignore.
      $ ~/github/ga_readme/actions-runner$ ./run.sh
      
      √ Connected to GitHub
      
      2020-11-22 13:09:50Z: Listening for Jobs
      2020-11-22 13:09:53Z: Running job: build
      2020-11-22 13:09:59Z: Job build completed with result: Succeeded
      
      # The yml file contains several names:
      #   CI - workflow name
      #   build - job name
      #   Run a one-line script - step name
      
      $ cat .github/workflows/main.yml
      name: CI
      on:
        push:
          branches: [ main ]
        # Allows you to run this workflow manually from the Actions tab
        workflow_dispatch:
      # A workflow run is made up of one or more jobs that can run sequentially or in parallel
      jobs:
        # This workflow contains a single job called "build"
        build:
          runs-on: self-hosted
          # Steps represent a sequence of tasks that will be executed as part of the job
          steps:
            # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
            - uses: actions/checkout@v2
      
            # Runs a single command using the runners shell
            - name: Run a one-line script
              run: Rscript --vanilla -e "library()"
      
            # Runs a set of commands using the runners shell
            - name: Render README
              run: Rscript -e 'rmarkdown::render("README.Rmd")'
            - name: Commit results
              run: |
                git config --local user.email "[email protected]"
                git config --local user.name "GitHub Actions"
                git commit README.md -m 'Re-build README.Rmd' || echo "No changes to commit"
                git push origin || echo "No changes to commit"
      
    • Ephemeral Self-Hosted Github Actions Runners: Dockerizing a runner
  • Using bookdown with gh-pages (5/19/2023)
  • Why use Github Actions (as an R programmer) ? (7/14/2024)
  • Should You Use GitHub Actions, or a Self-Hosted Build Server?

Workflow status badge, DOI

Passkey

VS code

One-Click VS Code in Browser from GitHub Repo. This assumes we have logged in the github account and it does not matter whether the repository is owned by me or not.

12 件可以用 GitHub 完成的很酷的事情

12 cool things you can do with GitHub

Create Websites

Documentation generator

Rmarkdown

Creating websites in R by Emily C. Zabor. The makes use of Jekyll theme. It covers

  • Personal websites: index.Rmd, _site.yml. No special package is required except rmarkdown.
  • Package websites: pkgdown package is used.
  • Project websites: index.Rmd, _site.yml. No special package is required except rmarkdown.
  • Blogs: blogdown package is used.

The tutorial's source code is also on github (Click the Github icon at the top).

Slides

An Introduction to Reproducible Analyses in R and its source

Math

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

RStudio

R Blogging on a Chromebook. A simple approach using Jekyll, GitHub, and RStudio Cloud.

Example

Script

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 & Read The Docs

Simple GitHub repo and ReadTheDocs set up

http://tutos.readthedocs.io/en/latest/source/git_rtd.html#creating-repository-on-github

Examples

Raspberry Pi/Python

Creating a project website with Sphinx from Documenting your code.

Hugo

Install

Start a blog in 30 minutes with Hugo, a static site generator written in Go (Unix and Windows). Note Hugo generates HTML for you. You then take that HTML and serve it on some web server, such as Apache HTTPD, or Nginx.

On Ubuntu

sudo apt-get install hugo

How To Install and Use Hugo, a Static Site Generator, on Ubuntu 14.04. See the latest binary version (32/64-bit or ARM/ARM64, Windows/Linux/Mac) at https://github.com/gohugoio/hugo/releases/.

wget https://github.com/gohugoio/hugo/releases/download/v0.31.1/hugo_0.31.1_Linux-64bit.deb
sudo dpkg -i hugo*.deb

# Install the Hugo Themes
# SKIP FOR NOW

# Install the Pygments Syntax Highlighter
sudo apt-get install python-setuptools python-dev build-essential
sudo easy_install pip
pip install --user Pygments # https://github.com/pypa/pip/issues/4186

How to Install Hugo Site Generator On Ubuntu 18.04 LTS

Create a new site

Follow https://gohugo.io/getting-started/quick-start/

(trusty)brb@localhost:~/Downloads$ hugo new site quickstart
Congratulations! Your new Hugo site is created in /home/brb/Downloads/quickstart.

Just a few more steps and you're ready to go:

1. Download a theme into the same-named folder.
   Choose a theme from https://themes.gohugo.io/, or
   create your own with the "hugo new theme <THEMENAME>" command.
2. Perhaps you want to add some content. You can add single files
   with "hugo new <SECTIONNAME>/<FILENAME>.<FORMAT>".
3. Start the built-in live server via "hugo server".

Visit https://gohugo.io/ for quickstart guide and full documentation.

(trusty)brb@localhost:~/Downloads$ cd quickstart;\
git init;\
git submodule add https://github.com/budparr/gohugo-theme-ananke.git themes/ananke;\

# Edit your config.toml configuration file
# and add the Ananke theme.
echo 'theme = "ananke"' >> config.toml

(trusty)brb@localhost:~/Downloads/quickstart$ hugo new posts/my-first-post.md
/home/brb/Downloads/quickstart/content/posts/my-first-post.md created

(trusty)brb@localhost:~/Downloads/quickstart$ ls -l content/posts
total 12
-rw-rw-r-- 1 brb brb 76 Dec 19 16:00 my-first-post.md

(trusty)brb@localhost:~/Downloads/quickstart$ ls -l
total 40
drwxrwxr-x 2 brb brb 4096 Dec 19 15:58 archetypes
-rw-rw-r-- 1 brb brb   91 Dec 19 16:03 config.toml
drwxrwxr-x 3 brb brb 4096 Dec 19 16:00 content
drwxrwxr-x 2 brb brb 4096 Dec 19 15:58 data
drwxrwxr-x 2 brb brb 4096 Dec 19 15:58 layouts
drwxrwxr-x 6 brb brb 4096 Dec 19 16:20 public
drwxrwxr-x 2 brb brb 4096 Dec 19 15:58 static
drwxrwxr-x 3 brb brb 4096 Dec 19 16:00 themes

(trusty)brb@localhost:~/Downloads/quickstart$ cat config.toml 
baseURL = "http://example.org/"
languageCode = "en-us"
title = "TAICHIMD"
theme = "ananke"

# Start the server
(trusty)brb@localhost:~/Downloads/quickstart$ hugo server -D 
# prompt will not be returned, Press Ctrl+C to stop
# -D/--buildDrafts: include content marked as draft

Started building sites ...

Built site for language en:
1 of 1 draft rendered
0 future content
0 expired content
1 regular pages created
8 other pages created
0 non-page files copied
1 paginator pages created
0 tags created
0 categories created
total in 27 ms
Watching for changes in /home/brb/Downloads/quickstart/{data,content,layouts,themes,static}
Serving pages from memory
Running in Fast Render Mode. For full rebuilds on change: hugo server --disableFastRender
Web Server is available at http://localhost:1313/ (bind address 127.0.0.1)
Press Ctrl+C to stop

Hugo quickstart.png

Deploy Your Website

After running hugo server for local web development, you need to do a final hugo run without the server part of the command to rebuild your site. You may then deploy your site by copying the public/ directory to your production web server.

(trusty)brb@localhost:~/Downloads/quickstart$ hugo 
Started building sites ...

Built site for language en:
0 of 1 draft rendered
0 future content
0 expired content
0 regular pages created
6 other pages created
0 non-page files copied
0 paginator pages created
0 tags created
0 categories created
total in 15 ms

Dev vs Deploy Destinations

Directory Structure

Configure Hugo

Hugo themes

(trusty)brb@localhost:~$ cd Downloads
(trusty)brb@localhost:~$ git clone https://github.com/gesquive/hugo-slate-demo
(trusty)brb@localhost:~$ cd hugo-slate-demo/
(trusty)brb@localhost:~/Downloads/hugo-slate-demo$ hugo server -t slate

Examples

Gitlab

Porting and redirecting a Hugo-based blogdown website to an HTTPS-enabled custom domain and how to do it the easy way

roxygen

Pelican

Git hooks

Markdown

  • CommonMark - A strongly defined, highly compatible specification of Markdown

Cheat sheet

Software

Atom screenshot.png

R markdown

For code chunks, use

```{r eval=FALSE echo=FALSE}
library(dplyr); library(ggplot2); library(ggthemes);
```

For internal links, see How to link to part of the same document in Markdown?

Tip: just one # for all heading sizes, no space between # and anchor name, anchor tag names must be lowercase, and delimited by dashes if multi-word.

[click on this link](#my-multi-word-header)

### My Multi Word Header

Github Markdown

To show images on readme.md file use

<img src="https://raw.github.com/arraytools/arduino/master/images/%E5%9B%9B%E6%B5%B7%E4%B8%80%E5%AE%B6.jpg"/>
# or relative paths (assume readme.md is at the root of your repository
<img src="master/images/%E5%9B%9B%E6%B5%B7%E4%B8%80%E5%AE%B6.jpg"/>

For code, use

Some basic Git commands are:
```
git status
git add
git commit
```

Or

```R
library(dplyr); library(ggplot2); library(ggthemes);
```

Bitbucket Markdown

To show images on readme.md, use for example

![Alt text](https://bitbucket.org/mingchung/qt/raw/master/example/drawer/drawer0.png)

Note that it seems there is no way to resize the image if we use markdown files.

For code syntax highlight or preformatted text, use 3 ticks (```). See https://confluence.atlassian.com/bitbucketserver/markdown-syntax-guide-776639995.html. For example,

```c++
MainWindow w;
```

Continuous Integration, Travis-CI, Continuous Deployment

Mobile apps

  • iOS: Working Copy works fine. It will create a new SSH key and added to your bitbucket account.

Software copyrighted by NIH