Needing a little help performing operations on remote repository - libgit2sharp

I've been tinkering around, and reading through what little Wiki information that I could find, and looked through tests that I thought may be relevant, however I'm having problems coming up with a working solution for a few things.
Mostly, I'm looking for a way to list commits that have been pushed to the server ahead of your working repository / local commits. I've tried using Fetch, and FetchHeads, but looking through all of the documentation for the Network class doesn't seem to yield anything that I can understand, I guess. Ideally, I'd be interested in seeing something like:
IQueriableCommitLog Repository.Network.GetCommitsAhead
OR
IQueriableCommitLog Repository.Remote.GetCommitsAhead
Then, just use the results like you would in:
IQueriableCommitLog Repository.Commits
Also, perhaps a method like Commit.UpdateTo() for the remote commit.
Am I too far off base for what I'm looking for? Is it possible at this time to perform actions such as this? Is it supported by libgit2?

Mostly, I'm looking for a way to list commits that have been pushed to the server ahead of your working repository / local commits.
A Branch is either local or remote. Local Branches which are tracking other ones expose a TrackedBranch property.
Considering a local branch with a not null TrackedBranch property
Commits that have been performed on this local branch and aren't known from the tracked one.
repo.Commits.QueryBy(new Filter { Since = branch.Tip, Until = branch.TrackedBranch });
Commits that exist in the tracked branch and aren't known from the local one
repo.Commits.QueryBy(new Filter { Since = TrackedBranch, Until = Tip })

Related

How do I preserve an approval in Gerrit with new patchset

I'm setting up a Gerrit server for the team. I've used Gerrit in the past, but I've never set one up.
One feature I know I've used in the past is, once I get a CL approved, I can rebase the branch without losing the approval. I assume this is a setting somewhere, but I can't find it.
You need to set the "Submit Type" of the repository (in the repository configuration page) to one of these:
Rebase If Necessary
If the change being submitted is a strict superset of the destination branch, then the branch is fast-forwarded to the change. If not, then the change is automatically rebased and then the branch is fast-forwarded to the change.
When Gerrit tries to do a merge, by default the merge will only succeed if there is no path conflict. A path conflict occurs when the same file has also been changed on the other side of the merge.
Rebase Always
Basically, the same as Rebase If Necessary, but it creates a new patchset even if fast forward is possible AND like Cherry Pick it ensures footers such as Change-Id, Reviewed-On, and others are present in resulting commit that is merged.
Thus, Rebase Always can be considered similar to Cherry Pick, but with the important distinction that Rebase Always does not ignore dependencies.
See more details in the Gerrit documentation here.
I think you are looking for the Copy All Score On Trivial Rebase labels.
The example below is from our project.config. For the Verified label the scores will be copied if there is a Trivial Rebase or a No Code Change patchset added, the No Code Change basically means an updated commit message.
[label "Verified"]
function = MaxWithBlock
value = -1 Fails
value = 0 No score
value = +1 Verified
copyAllScoresIfNoCodeChange = true
copyAllScoresOnTrivialRebase = true
defaultValue = 0

How to remove a remote using LibGit2Sharp?

I've checked libgit2sharp v0.15.0 and it seems like there is no method for removing a remote.
Is there any way to do it?
I've checked libgit2sharp v0.15.0 and it seems like there is no method for removing a remote.
That's completely correct. Such a method doesn't exist yet as it's not supported by libgit2 yet.
There's a work in progress (see PR #1199) to implement this. Subscribing to this PR would let you know about it's future progress.
Is there any way to do it?
You can do it by hand this way:
Remove the whole config section that describes the remote to be deleted
Delete from the config every branch (remote, merge) tuple that depends on the remote to be deleted
Delete from .git/refs/remotes/ every remote tracking branch reference
For instance, if you're willing to drop the remote "useless"
Drop this whole section from the config
[remote "useless"]
url = https://github.com/useless/project.git
fetch = +refs/heads/*:refs/remotes/useless/*
Remove remote and merge entries from the two following branches
[branch "vNext"]
remote = useless
merge = refs/heads/vNext
[branch "topic/awesome_feature"]
remote = useless
merge = refs/heads/topic/awesome_feature
Delete the following references
- .git/refs/remotes/useless/vNext
- .git/refs/remotes/useless/topic/awesome_feature
Update
Pull Request #731 just made possible the removal of remotes through the API.
Syntax: repo.Network.Remotes.Remove(remoteName)

How to calculate ahead or behind branchs

Use libgit2sharp, how to calculate ahead or behind metrics. like this page https://github.com/libgit2/libgit2sharp/branches
How to calculate ahead or behind metrics
Each Branch bears a TrackingDetails property. This property exposes AheadBy and BehindBy nullable values (null will be returned when the branch has no upstream configuration or if the upstream branch does not exist).
Those values will represent the number of commits the local branch is ahead/behind compared to the upstream branch (ie. the remote branch being tracked).
This outputs similar results than git status -sb
like this page https://github.com/libgit2/libgit2sharp/branches
This page actually compares each branch of the upstream (ie. the one hosted on GitHub) repository against the current tip of the remote HEAD. This feature (comparing two local branches) is not available in LibGit2Sharp.
Provided you're interested with it, please feel free to open a feature request.
Update
A pull request (see #564) introducing a new method repo.ObjectDatabase.CalculateHistoryDivergence(Commit, Commit) is cooking up.
This will allow the user to determine the ahead-by and behind-by counts, along with the merge-base that's been used to calculate those distances.
For those searching (as of pygit2 v 0.27.4), the API is ahead_behind.
Sample code gist:
import pygit2
repo = pygit2.Repository('your-repo-path')
upstream_head = repo.revparse_single('origin/HEAD')
local_head = repo.revparse_single('HEAD')
diff = repo.ahead_behind(local_head.id, upstream_head.id)

Can Jenkins show me the total number/percent of broken builds per month?

I have a Jenkins server that builds/tests about 50 projects. Unfortunately, some of these builds fail, but I don't have a good way to measure whether build failures are increasing or decreasing in frequency over time.
What I'd like is something along these lines:
A report that shows me, over the course of a month, how many jobs were unstable/failed
A report that says "X Days without a broken build" (kind of like at construction sites)
A "Red/Green calendar", that would show on a per-day basis whether any builds were broken
I didn't see any plugins that visualized data in any of these ways, but I'm willing to scrape the Jenkins logs to get the information. Is there a better way to see data similar to this?
I think this work pretty decent using the API. You can get all jobs from your view, then go into the job details and get the build numbers and build date. With those build numbers you can get the corresponding status. You would have to do some coding to collect and display the data, but this would be a possible way.
Another possibility would be using a Groovy script over the console in Manage Jenkins. I do not have much experience working with that feature though, but as you have access to the internal representation it should be pretty easy to get some data out of there.
Finally, the optimal solution would be to write a plugin that does the work, but this is of course also the solution that requires the most effort and know-how.
The Global Build Stats plugin might provide the reporting you're looking for.
(And if you already considered this plugin, I'm curious what problems you ran into.)
As #pushy mentions, the Groovy script console is a good tool to use for these types of statistics gathering. You can use the groovy script in the remote API as well. Here is a starting point for gathering information from all jobs matching a pattern.
def jobPattern='pattern'
Hudson.instance.getItems(Project).each {project ->
def results = [:]
if (project.name.contains(jobPattern)) {
results."$project.name" = [SUCCESS:0,UNSTABLE:0,FAILURE:0,ABORTED:0]
def build = project.getLastBuild()
while (build){
//println "$project.name;$build.id;$build.result"
results."$project.name"."$build.result" = results."$project.name"."$build.result" +1
build=build.getPreviousBuild()
}
}
results.each{name,map->
map.each{result,count->
println "$name : $result = $count"
}
}
}
"Done"
Use this as a start and modify according to your specific requirements.
Try build metric plugin along with Global Build Stat plugin.

Git merge from a specific folder only

I've created a rails website for client X. I now have a client, Y, who wants a website that does the exact same thing as client X, but with a different skin.
I made a git branch from clientXcode and called it clientYcode. I then did all the changes to the views to make it look different, and lala, the same website with a different skin.
Now here's what I don't understand about git: I've made many changes to clientXcode in the views, models, and controllers; and now I want to merge those changes into clientYcode, excluding any view changes. Since views, models, and controllers each have their own folder in rails I was hoping to be able to do something like:
git merge client_x_code 'app/controllers/*', 'app/models/*'
QUESTION 1: Is something like that possible with git? If so, how would I do it?
QUESTION 2: Was branching the best solution to make a copy of my project?
Well I found the easiest solution to my problem...
git checkout clientYcode
git checkout clientXcode "app/controllers/"
git checkout clientXcode "app/models/"
And that does what I want!
The simplest course of action is to merge everything, except the content of the directory you want to keep.
You can do that by adding a merge driver in that directory, as the How do I tell git to always select my local version for conflicted merges on a specific file? question details.
With that merge driver in place, Branching is a good solution in this case.
Extract:
We have a .gitattributes file defined in the dirWithCopyMerge directory (defined only in the branch where the merge will occurs: myBranch), and we have a .git\config file which now contains a merge driver.
[merge "keepMine"]
name = always keep mine during merge
driver = keepMine.sh %O %A %B

Resources