Let's say I have a branch called parent-branch and I create a branch right off of that branch by doing
git checkout -b child-branch parent-branch
That's all fine and well of course, but what I am looking (hoping) to do, is to be able to somehow reference parent-branch from within a bash script. So for example, something like git_current_branch and git_main_branch will print the current local branch I am in, and print the master branch, respectively.
Is there a way where I can do something like git_parent_branch (or something along those lines) to have access to the parent-branch in bash and the command line. Whether that be a bash script function, or whatever other potential possibilities might work.
Is there something involving GitHub and / or any associated APIs perhaps where this is possible. I'm not overly familiar with connecting to GitHub other than just using their web interface, so anything in that respect would most likely be of big help (ideally pertaining to my issue here)!
In Git at a fundamental level, branches simply don't have parents. Well, I say simply, but it's not that simple, because we haven't defined branch, and users of Git use the word very loosely and often mean different—and contradictory, sometimes—things when they say it. So let's define branch name first, which at least has a simple, definite meaning:
A branch name is a name whose full spelling starts with refs/heads/, which—in order to exist—contains the hash ID of some existing, valid commit.
The last bit here—which is kind of redundant: an existing commit is valid, and a valid commit (whatever that means) must exist—is a concession to the fact that we can have branch names that don't exist (yet, or any more): xyzzy, for instance, is fine as a branch name, but until you create it, it's just a sort of potential branch name, floating in limbo as it were.
Because a branch name must contain a commit ID to exist, a new, empty repository—which has no commits—has no branch names either. And yet you're on the initial branch. It's in limbo, as yet nonexistent. When you make your first commit in this empty repository, then the branch name actually exists. If you like, you can re-create this special case in a non-empty repository using git checkout --orphan or git switch --orphan. (These are subtly different in how they manipulate Git's index, but both put you in this funky state of being on a branch that does not yet exist.)
This kind of special case aside, because a branch name has to contain some commit hash ID, we normally create a branch by picking some existing hash ID, just as in your example:
git checkout -b child-branch parent-branch
But what Git does with this is to resolve the name parent-branch to a commit hash ID first, then create a new branch—in this case, named child-branch—containing that hash ID. The two branch names have no parent/child relationship; we could run git checkout -b daddy kid or git checkout -b xyzzy plugh and there's no parent/child relationships here either, despite the misleading name in the daddy kid version and the neutral names in the xyzzy plugh case.
Now we come to your own question, though:
Is there a way where I can do something like git_parent_branch (or something along those lines) to have access to the parent-branch in bash and the command line.
Git contains, as a useful tool—parts of Git make use of this in various ways—a fully general string-based configuration system, where we run git config to set some arbitrary string to some arbitrary value. By convention, these strings have a hierarchical structure: user.name and user.email live within the user space; push.default is composed of push + default; and so on. Git even stores them using an INI-file-style syntax.
What this means is that although Git itself has no parent/child relationship, you can make up your own. There are a few obvious drawbacks to doing so:
Git won't maintain it for you.
You need to choose names that Git won't clobber, even in some future release (Git version 3.14 perhaps).
Nobody else will understand what the heck you're doing.
So, if you choose to do this, you're on your own—but let's note that Git does store some per-branch information in the branch.name namespace:
branch.xyzzy.remote is the remote setting for the branch named xyzzy;
branch.xyzzy.rebase is the git pull setting controlling whether the second command to use is git merge or git rebase, and depending on which second command is to be used, what flags, if any, to pass to that second command, when you're on branch xyzzy and you run git pull;
branch.xyzzy.description is the descriptive text that git format-patch will include in a cover letter, when run for branch xyzzy;
and so on. So if you were to add a branch.name.parent string value, you could store your string here. You then merely need to hope that the Git developers don't steal that name—parent—from you in the future.
Since this stuff is totally free-form, you'd just run git symbolic-ref or similar to find the current branch name, then git config --get branch.$branch.parent to get its parent setting, if it has one. If it does not have one, this must be a normal everyday parentless Git branch, rather than one of your own specially decorated branches that does have a nominal parent. To set the parent for some branch, you'd run git config branch.$branch.parent $parent, where $parent is the setting you want. (It's your decision as to whether $parent is required to be a branch name, in which case strings like xyzzy and main and plugh are fine, or whether it could be a remote-tracking name as well, in which case, you'd better use fully-qualified strings like refs/heads/xyzzy, refs/heads/main, and so forth. That will allow you to use refs/remotes/origin/main—a remote-tracking name—as a "parent".)
Is there something involving GitHub and / or any associated APIs perhaps where this is possible.
Definitely not, and this points up another weakness in the idea of using branch.$name.parent: there is no way to record this data on GitHub. It's a purely local setting. Then again, branch names are purely local: there's noting that requires that you call your development branch dev or develop, even if the development branch name in some GitHub repository you've cloned is called dev or develop.
Before I finish this off, let me add another several definitions of branch. We'll needs a few more definitions as well:
A branch tip is the commit to which a branch name points. That is, given some branch name like main that indicates some particular commit hash ID such as a123456..., the tip commit of branch main is a123456.... Checking out a branch by its name—with git checkout or git switch—and then adding a commit automatically stores the new commit's hash ID in the branch name, so that the tip commit automatically advances. The new commit's parent will be the old branch tip.
A branch (in one of its many meanings) is a set of commits that includes the tip commit of a branch (with branch here meaning name that contains a commit hash ID). Where this set of commits begins is in the mind of the user, but if left unspecified, Git generally includes every commit reachable from the tip commit.
To define reachable, see Think Like (a) Git.
A remote-tracking name is a name that exists in your Git repository but was created due to a branch name that your Git saw in some other Git repository. These names live in the refs/remotes/ namespace, which is further qualified by the remote, such as origin. For instance, refs/remotes/origin/main would be a remote-tracking name in your repository, in which your Git remembers the hash ID stored in origin's branch name main, the last time your Git got an update from their Git.
For some users, a remote branch is a branch (in the meaning of series of commits terminating at a tip commit) where the tip commit is given by a remote-tracking name. For other users—or the same user speaking at some other time—a remote branch is a branch that exists in some remote repository, such as origin. These two are easily conflated since your own origin/main tracks the other Git's main, hence the term remote-tracking name. (Git calls this a remote-tracking branch name, but the adjective remote-tracking in front of the noun name seems sufficient here.)
As you can see, the word branch is so loosely defined as to be nearly valueless. We can often reconstruct the correct definition—the one a speaker or writer had in mind—based on context, but for clarity, it's often better to use some other term.
I want to have part of my destination path in build.cake be based on the branch being built. The top of my build.cake script says:
var branch = Argument("branch", "Master");
and I modified my Team City Build step to include
.\build.ps1 ... -Branch %teamcity.build.branch%
but Team City complains that I have no eligible agents
Implicit requirements: teamcity.build.branch defined in Build step:
Build
I'm new to TC and Cake so I'm likely missing something obvious. How do I hook this up?
You are correct that %teamcity.build.branch% will give access to your branch name. However, this variable is blank unless you have a branch specification in your VCS root settings. In order to use say master as your build.branch parameter you need to add: +:refs/heads/(master) to your branch specification. Whatever is in between the parens will be put in the build.branch variable. If you might be building from multiple branches, you might have something like the following:
+:refs/heads/Release/(765/1.0)
+:refs/heads/Release/*
This would give your build.branch the name of branch as it appears in git after the Release/.
Also see Johan's answer: https://stackoverflow.com/a/27829516/6222375
I have the following tree in TFS2012
Base-->Branch1-->Dev1
|
\/
Dev2
I want to reparent Dev2 from Base to Branch1 so that the new tree will look like this:
Base-->Branch1-->Dev1
|
\/
Dev2
Possibly important detail: Base and Branch1 are identical in every way. The only item in the history for Branch1 is its original creation from Base. Dev1 and Dev2 both have significant changes but are effectively based off the same original.
Is there any way to accomplish this without using a baseless merge?
Alternatively, if I create a new branch Dev3 off of Branch1, is there any way to apply all of the change sets from the history of Dev2 to Dev3. This would, in theory, result in Dev3==Dev2. I could then delete Dev2.
An easy way is to use baseless merge to create relationship between Branch1 and Dev2, then reparent Dev2 by right click Dev2 branch and select Reparent (reparent to Branch1) as the screenshot below:
I'm new at working with StarTeam, having previously used Subversion in projects.
In order to find out how the change packages work, I've experimented a bit - and not quite gotten the results I would've liked.
I have tried to following steps:
(I have 2 views, one called 'trunk' and one called branch1.1 which is a child of trunk)
trunk: Creating file TestMerge.txt with the content 'A'
trunk: TestMerge.Txt -> adding a new line with content 'B'
trunk: TestMerge.Txt -> adding a new line with content 'C'
I go to 'Show Change Perspective' and find my 3 check-ins.
I select 1 and 3, right-click, advanced, View Compare/Merge.
I select rebase with trunk as source and branch1.1 as target.
Under include I select 'Selected change packages'.
I dont change options or properties.
Finish now brings up a window called 'Rebase from trunk'
The TestMerge.txt has merge status: Resolved, Merge Action: ignore.
I can only change this to 'share' (and I cannot commit if it is ignored, since nothing is changed).
When I commit these changes, branch1.1 now contains a file called TestMerge.txt - however that file contains A B and C.
I would only expect it to contain A+C, since I didn't ask for my second commit to be included in the change package.
Is that just the way StarTeam (doesn't) work or is there somewhere I can get what I want?
StarTeam does not support merging two versions of the same file in the same view,
especially not via the "Change-Packets" process, or the "View Compare/Merge" tool.
"Change-Packets" process and the "View Compare/Merge" tool are designed
for merging files and folders from different views.
(Try this with two versions of the same files that are sitting in different views.)
How can I find changesets in Branch A that were not merged to branch B programmatically.
This what Merge Window does in TFS client GUI but I need to programmatically get the list of changesets.
Say I have Microsoft.TeamFoundation.VersionControl.Client.Workspace reference.
You probably want the VersionControlServer.GetMergeCandidates() method. This gets the candidates for merging between two paths.
public MergeCandidate[] GetMergeCandidates(
string sourcePath,
string targetPath,
RecursionType recursion
)