Add git submodule using a specific commit number - git-submodules

I'm using git submodule commands to add this FSM repo in my project. I want to checkout a specific release commit. By default the master branch is checked out.
After adding the git repo, when I run
$ git submodule
It gives
d1b66d66cfa95f238a7498465908a262f4b2326a directory_path/fsmlite
The commit number here belongs to a master branch commit. How can I checkout another commit instead, using its commit number?

There might be some other way to do this, but I got the desired commit by
$ cd directory_path/fsmlite
$ git checkout v0.7.1 (this is the branch I wanted to point to)
$ git submodule update
$ cd parent_dir
$ git submodule
+de19ea0a71cb6082fe9311694a27e8f0cc2f972a directory_path/fsmlite (v0.7.1)
which is the specific commit number I wanted

Related

How to solve merge conflict in a approved review in gerrit?

I made a change in gerrit which was code reviewed and after 7 revisions approved. But, now it cannot be merged and trying to rebase in gerrit website is not working due to merge conflict. How can I resolve this merge conflict and merge the same approved change and not create a new one.
(Full steps from cloning the repo would be appreciated.)
1) Clone the Gerrit repository
git clone https://USER#GERRIT-SERVER/a/REPO-FULL-PATHNAME
2) Go to the change page on Gerrit and copy the checkout patch command
git fetch https://USER#GERRIT-SERVER/a/REPO-FULL-PATHNAME refs/changes/XX/YYYYY/Z && git checkout FETCH_HEAD
3) Rebase the change
git rebase origin/BRANCH
4) Solve the conflicts
git mergetool
5) Continue the rebase
git rebase --continue
Repeat the steps 4 and 5 until the end of conflicts
git commit --amend
Note: Keep the same Change-Id
6) Send the new patchset to Gerrit
git push origin HEAD:refs/for/BRANCH
The accepted solution works but I personally disagree with this workflow. It is unnecessarily cumbersome.
I prefer a workflow with exactly one merge and therefore less steps.
Clone the Gerrit repository if not already available
git clone https://[USER]#[GERRIT-SERVER]/a/[REPO-FULL-PATHNAME]
Checkout the Gerrit patch
git fetch https://[USER]#[GERRIT-SERVER]/a/[REPO-FULL-PATHNAME] refs/changes/46/12346/N && git checkout FETCH_HEAD
Soft-reset the change and stash it
git reset --soft HEAD~1 && git stash
Checkout branch or the Gerrit patch you want to rebase onto
git checkout origin/BRANCH
# or fetch other Gerrit patch:
# git fetch https://[USER]#[GERRIT-SERVER]/a/[REPO-FULL-PATHNAME] refs/changes/45/12345/N && git checkout FETCH_HEAD
Unstash the previously stashed changes
git stash pop
Solve the conflicts with your favourite 3-way merge tool.
Commit the merged changes - NOT (!!) amend them - and use the same Change-Id from the merged patch in the message:
git commit -am "[COMMIT-MESSAGE]\
\
Change-Id: [FORMER-CHANGE-ID]"
Send the new patchset to Gerrit
git push origin HEAD:refs/for/BRANCH
Done. One merge!
I additionally use the gitreview tool. That makes it extra easy. Steps 2, 3, 4 and 5 then can be chained.
git review -d 12346 && git reset --soft HEAD~1 && git stash && git review -d 12345 && git stash pop

submodule project not present in `git submodule status` roster and unable to commit from parent as single object

I use git submodule add <GitHubURL.git> to add projects as submodules to a main "parent" project repository.
Parent_Project_repo
- SubA_repo
- SubB_repo
- SubC_repo
- Sub_Problem_Child_repo
As I work in the submodules, I make commits within the Sub*_repo project (per usual, committing whichever files I have worked on). In the parent project, however, usually I am just making a single commit for all the submodules commits. This single commit of the submodule usually shows up like so in the Parent_Project_repo:
I have recently added a submodule which, from the parent repository, displays each individual file in the commit history instead of just accessing all the files/commits in one single "Subproject" commit object.
Of note:
this problematic submodule does not show up in the roster when I
invoke:
git submodule status
It is listed in the
Parent_Project_repo/.gitmodules
Parent_Project_repo/.git/config
file as a submodule & there is a corresponding
Parent_Project_repo/.git/modules/Sub_Problem_Child_repo/ folder.
How can I get the problem child into the roster and able to have all it's commits handled by the Parent_Project_repo as one object?
UPDATE:
The only difference I have discerned with the “problem child” submodule is that it doesn’t have a “historySha” key in the /.git/modules/config file, e.g.:
[atomGithub]
historySha = 1936e4c373c130860a8f92683b517dad713ec37
Also, these commands don't get the Problem child listed in the status:
$ git submodule update --init --recursive
$ git submodule update --recursive
$ git submodule init
...nor showing up on GitHub in the Parent project with a "# e78c392" which indicates I can double click the link and got to that repo instead of a copy inside the superproject (Parent).
If git submodule add <URL> was used to set up a git repository as a submodule within a "super-project" and the submodule is NOT committing within the super-project as a single object (i.e. if, when committing the submodule from within the Super project you are having to commit each individual file from the submodule), then follow these steps to reconfigure:
Save all work in the submodule.
Stage and commit all file changes.
Push all commits to GitHub.
Make a safety copy of the submodule folder if you are cautious
Delete the relevant submodule section from the super-projects .gitmodules file (i.e. remove the listing of the problem submodule).
Stage the .gitmodules changes git add .gitmodules
Delete the relevant sunmodule section from super-projects .git/config.
Run git rm --cached -rf PATH_TO_SUBMODULE where PATH_TO_SUBMODULE is the actual path to the submodule folder.
Run rm -rf .git/modules/PATH_TO_SUBMODULE.
Commit git commit -m "Removed submodule commit message".
Delete the now untracked submodule files: rm -rf PATH_TO_SUBMODULE
git submodule add <URL>
Test to see if a change (fwiw, modify two files) in the submodule is handled as a single object when committing in the super-project.
Success? Delete the safety copy of the submodule project.

Enabling SVN tracking in a git clone of a git-svn clone that didn't start at revision 1?

Suppose I have a git svn clone that I created like this:
$ mkdir foo
$ cd foo
$ git svn clone -s -r 100:HEAD http://svn.example.com/project
and then I git clone it like this:
$ cd ..
$ git clone foo bar
$ cd bar
So now bar has foo as its origin.
How do I make bar track the original SVN server? The git-svn man page provides an example of the case where the original git svn clone includes the full revision history, but this doesn't seem to cover the case that the original git svn clone doesn't start from r1. When I try the various things I see described, what git svn fetch does is always start a disconnected history starting at r1.

Why does git-svn dcommit leave duplicate commits in my git repo? Can I stop it doing that?

My typical git-svn workflow is:
git checkout -b story-xyz
git commit -a -m "work"
git commit -a -m "more work"
git checkout master
git svn fetch
git merge remotes/trunk
git checkout story-xyz
git rebase master (sometimes with -i)
git checkout master
git merge story-xyz
At this point I have my master and story-xyz branches pointing to the same commit, one or more commits ahead of remotes/trunk. Everything since remotes/trunk is in one linear history.
last svn commit [remotes/trunk] <--- work <--- more work [master, story-xyz]
I then run
git svn dcommit
I expected to see the commits between remotes/trunk and master become Subversion revisions, and end up with a single linear history with remotes/trunk, master and story-xyz all pointing to the latest revision, like so:
last svn commit <--- work <--- more work [master, story-xyz, remotes/trunk]
My Subversion revisions go in fine, but I end up with a two-branched structure. The common root of the branch is the Subversion HEAD before I committed. Both branches contain the same series of commits, in the sense that they contain the same diffs. The branch story-xyz is at the head of one branch, remotes/trunk and master at the other:
last svn commit <--- work <--- more work [master, remotes/trunk]
|
\- work <--- more work [story-xyz]
The git commits that I had before running git svn dcommit are on the lower branch (story-xyz), with my git commit messages, git user name and email, and git commit timestamps. The commits on the upper branch are new git commits. They use my Subversion username, the timestamp when I ran the dcommit, and the commit messages have the git-svn-id field appended to them.
This is all OK, and I can carry on working. The problem is that I look in gitk and see what looks like an unmerged branch story-xyz. It's pretty hard to tell the difference between a story branch that I have merged back into master, and one that I haven't. The most obvious way to spot it is the duplicate commit messages. I could delete the story-xyz branch, but that feels like I'm not using git properly and I've lost some of my history.
Am I missing something that would stop git-svn from doing this? Or is this just one of the ways that interacting with Subversion dilutes the power and freedom of git?
I don't think you're really missing anything. You might be doing some unnecessary work, though. In this case, you have two pointers to the "more work" commit, and you are asking git-svn to move one of them. The other one still stays where it is.
You don't really need the master branch. Git-svn doesn't care about what branch you are dcommiting. IIRC, it uses the first svn-remote it can find among the ancestors of the current commit.
I'll offer another version of the workflow:
git checkout -b story-xyz remotes/trunk
git commit -a -m "work"
git commit -a -m "more work"
git svn fetch
git rebase remotes/trunk (with -i, perhaps)
git svn dcommit
This should give you a tree without the extra branch. You need to be careful with fast-forward merges, though.

How to commit a Git repo to an empty repo SVN server?

I have setup an empty svn on a server and I have been working on locally making commits along the way. Now I wish to commit my repo to an svn server. For this I tried:
git-svn checkout http://remote.svn.server.com
git-svn dcommit
Git complains that:
Use of uninitialized value in concatenation (.) or string at /usr/bin/git-svn line 411.
Committing to ...
Unable to determine upstream SVN information from HEAD history
Since I started on my local computer first, and the repo online is empty, I can't find any info on how to make this work.
I needed something like this recently and the process is relatively straightforward.
There's good tutorial by Brandon Dimcheff, "Commit a linear git history to subversion" (replaces old broken link), which these steps are based on.
As of Git version 1.6.3 these are the steps:
$ svnadmin create svn_repository
$ svn mkdir -m "Initial setup" file:///full/path/to/svn_repository/trunk
$ mkdir gitrepo && cd gitrepo
$ git init
$ echo 'Hello from Git' > file.txt
$ git add file.txt
$ git commit -m "Hello from Git"
$ git svn init --trunk=trunk file:///full/path/to/svn_repository/
$ git svn fetch
$ git branch -a # Lists remotes/trunk
$ git rebase --onto remotes/trunk --root master
# => Applying: Hello from Git etc.
$ git svn dcommit
# => Committing to ... Committed r2 ... etc
You can do a svn checkout of svn_repository now and see your Git repo.
Here is what I would do:
git-svn clone http://remote.svn.server.com otherdir
Then in other dir pull the changes locally from your previous dir. Then you should have a git repo that is "connected" via git-svn and you should be able to use dcommit on it.
This might also be a useful read.