Similar to GitHub, Bitbucket makes it very easy to host your code. We all know that GitHub works great for open-source. However, you have to pay if you want to create private repositories. On the other hand, Bitbucket enables you to create unlimited free private repositories. This is an important reason why more and more people are using Bitbucket nowadays. In this post, I will show how to use Bitbucket to easily host your code (over TortoiseHg specifically).
Setup Bitbucket over Internet
- Login
Bitbucket > Repositories > Create repository
. - In the Create a new repository page:
- Name: Fill in the repository name (
testRepo
as an example). - Description: I will always leave this empty because I prefer to use a
README.text
file instead, which supports Python-Markdown and is much more powerful. - …
- Name: Fill in the repository name (
Setup TortoiseHg
Simple way is to use SSH keys and follow setup sets by this post: Set up SSH for Mercurial. One key step is to add the following content to mercurial.ini
(TortoiseHg’s global setting file):
1 | [ui] |
Another key step is to generate your private SSH key file using PuTTYGen and copy the key to your online Bitbucket profile.
Note:
- Make sure
Pageant.exe
is running in background in order to make it work (Add key > load >
input passphrase). It’s possible to make
Pageant.exe
automatically load keys on system startup, see this post. Key step is add a shortcut ofPageant.exe
to PC’sStartup
folder and change itsTarget
to be something like:1
"C:\Program Files\TortoiseHg\Pageant.exe" "-path-of-your-ssh-key-file-.ppk"
Commit your code using TortoiseHg
File > New Repository >
ChangeDestination path
to where your code is> Create
.- Click
Commit
button in toolbar. It will list all the modified (including edit/add/delete…) files in the left window. Note, clickRefresh current repository
button in toolbar when needed if you cannot see the new updated files. Check the files that we want to check in. And you can right click >Ignore
to ignores files to check in. - Fill in some commit update information in the right window and then click
Commit
. - Click
Push outgoing changes to selected URL
button in toolbar. - In
Remote Repository >
Selecthttps
>Add the URL of the repo
testRepo> Click
save` button in just this left to remember this URL so that you have no need to type again when doing further commit this repo to this URL.
Note: all you need to do is to loop in step 2~5 for further commits.
Sync between multiple users/PCs
- Get latest: Before editing, always get current latest version by
Repository > Synchronize > Pull
. - Update local to latest: Right click current local version >
Update
> Write the latest revision inUpdate to > Update
. - Edit source.
- Push:
Commit > Push outgoing changes to selected URL
.
Done if no conflict found with server version (e.g. no one pushed new revisions during our editing). If do find conflict, it will showsabort: push creates new remote head xxxxxxx!
in TortoiseHg. - Resolve conflicts:
- Get latest:
Repository > Synchronize > Pull
. - Merge: Right click latest revision by others that is just pulled
> Merge with Local… > Next >
Clickresolved
in current Merge window to resolve conflicts > Click the file (do this one by one) that we need to resolve inUnresolved conflicts
sub-window and clickTool Resolve
(assumeKDiff3
has been installed, this will call KDiff3 to compare both versions side by side) > In theOutput
window, right click?<Merge Conflick> > Select Line(s) from
the version that you want (or both versions)> Save
andClose
KDiff3 >Close
the Resolve Conflicts window > Change Commit message if you need in theMerge
window> Commit Now > Finish
.
- Get latest:
- Push: Push outgoing changes to selected URL.
Other remarks
Repo grouping
Use teams to group repos (only way currently). Issues can also be import/export in Settings->Import & export->…
Get some specific version
If there is no corresponding repo in your PC:
- Clone the repo to PC (done in TortoiseHg).
- Open it by TortoiseHg. Then all its revisions will show in the right view.
Select the revision you want to get > Right click >
Export > Archive
> Choose theDestination path > Archive
.Clone vs. Archive:
- Clone will copy everything including
.hg
folder (can be opened by TortoiseHg). - Archive will copy everything except .hg folder (can NOT be opened by TortoiseHg).
- Clone will copy everything including
Otherwise:
- Select current revision > Right click >
Update…
> Put the revision you want to get in theUpdate to
box >Update
.
- Select current revision > Right click >
Link to most-recent version of given file1
- Get the file link of any version, e.g. https://bitbucket.org/herohuyongtao/files/src/f7b75d07772182019e80200a18e5f1130f75fc70/files/VC_call_MATLAB.cpp?at=default
Change string corresponding to version (
f7b75d07772182019e80200a18e5f1130f75fc70
in above example) totip
ordefault
(or any other branch name) and delete the tail until to the file type, i.e. to be https://bitbucket.org/herohuyongtao/files/src/tip/files/VC_call_MATLAB.cpp or https://bitbucket.org/herohuyongtao/files/src/default/files/VC_call_MATLAB.cpp.The difference between
tip
anddefault
is that usingtip
for the very latest commit, regardless of branch. Instead,default
or any other branch would link to the latest version under that branch.
Delete local commits
- If only need to delete last commit,
Repository > Rollback/Undo...
. This will keep changes in local. If want to delete all local commits2,6 (this will also revert all changes):
Enable
mq
extension by adding the following tomercurial.ini
or enable it viaFile > Settings > Extensions > mq
:1
2[extensions]
mq=- Run
hg strip 'roots(outgoing())'
in console.Note: it seems that this doesn’t work for
graft
commits, in this case, just usehg strip #changeset#
.
Copy changes from other commits
This can be viewed as one kind of merging except that all files are updated to other commits. This is very useful when you want to update old default
branch to one new branch
.
This can be done in the following steps5:
- Set the current commit to which you want to be overwritten by other commits by right click \(\rightarrow\)
Update...
\(\rightarrow\) set the commit number. - Select the commit that you want to copy changes from \(\rightarrow\) right click \(\rightarrow\)
Graft to Local...
.
Ignore given files/folders
- Ignore all its content under folder, simply add
-path-to-folder-/folderName/
to file.hgignore
. Ignore all its content under folder except given files or given sub-folders, add similar conent to file
.hgignore
(note that, unlike folders, files should end with$
):1
2syntax: regexp
-path-to-folder-/folderName/(?!exceptFile1.ext1$|exceptFile2.ext2$|exceptSubFolder1|exceptSubFolder2|)
Sub-repos
Subrepositories allow you to have a standalone repository included within a parent repository3 (hg example / git example).
- In the main repo, create file
.hgsub
. Add sub-repo mapping info in file
.hgsub
with format:local_subrepo_path = external_repo_path
(wherelocal_subrepo_path
is relative to the root of your main repo). Suppose we want to add repo hosted athttps://me@bitbucket.org/me/subrepo
to folder-path-to-main-repo-path-/libs/subrepo
, the content of file.hgsub
will be like:1
libs/subrepo = https://me@bitbucket.org/me/subrepo
- Add and commit file
.hgsub
to the main repo. File structure identified bylocal_subrepo_path
will be created. E.g. in above example, folderlibs/subrepo
will be created automatically.
Note: You must revert anything done to the sub-repo when pushing changes to the main repo, though you can modify it to fit your needs during development.
Note that, when cloning the main repo, by default, all sub-repos (and their contents) are also cloned. If you only want to download some of the sub-repos (especially useful if the sub-repos are huge in terms of number and size), follow the following steps:
- Download the main repo from its download page.
- In TortoiseHg \(\rightarrow\)
File
\(\rightarrow\)New Repository...
\(\rightarrow\) browse to the download main folder \(\rightarrow\)Create
. - Check on all files to commit (may need to press commit button twice).
Download sub-repos.
- One-by-one:
- In
Repository Registry
window \(\rightarrow\) click the main repo to expand all its sub-repos \(\rightarrow\) double click the sub-repo needed to download \(\rightarrow\) clickPull
button.
- In
Batch style:
- Download file
onsub.py
and put anywhere on your PC. In TortoiseHg \(\rightarrow\) right click the main repo \(\rightarrow\) on the main repo’s repository setting window \(\rightarrow\) click
Edit File
\(\rightarrow\) add the following content to the opened file (i.e.hgrc
file) andSave
.1
2[extensions]
onsub = -path-to-onsub.py-/onsub.py- Edit both files
.hgsub
and.hgsubstate
to keep only the lines for the sub-repos that you want to download. - Run
hg onsub "hg pull -u"
in console4. - (optional) If you want to download given commit of one sub-repo, after the above steps, go to the sub-repo that you want to edit and update to the commit you want.
- Download file
- One-by-one:
1. Link to most-recent version of static file: https://bitbucket.org/site/master/issue/3769/link-to-most-recent-version-of-static-file. ↩
2. Delete all local changesets and revert to tree: http://stackoverflow.com/a/2143711/2589776. ↩
3. Getting Started With Mercurial Subrepositories: https://tomtech999.wordpress.com/2011/12/17/getting-started-with-mercurial-subrepositories/. ↩
4. OnsubExtension: https://www.mercurial-scm.org/wiki/OnsubExtension. ↩
5. Copy changes from other branches onto the current branch: https://selenic.com/hg/help/graft. ↩
6. Is there any way to delete local commits in Mercurial?: http://stackoverflow.com/questions/2338986/is-there-any-way-to-delete-local-commits-in-mercurial ↩