Mercurial and Git clients can push and pull from this alias URL to interact with this repository. You can change to which repository an alias points by going to the Aliases link on the project page.
packagemainimport("fmt""net/url""os""os/exec""strings""developers.kilnhg.com/Code/Kiln/Group/gitkiln/kiln")constdocumentation=`USAGE: git-kiln [<command> [args]]git-kiln provides quick access to the Kiln repository associated with thisrepository. To work, git-kiln must be run from within a Git repositorythat either has a Kiln HTTP repository as the upstream remote, or has theconfig value "kiln.url" set to an HTTP-accessible Kiln repository. Thelatter is helpful if you access Kiln via SSH, or have an alternativerepository as your upstream remote.Commands: add-remote [--ssh] <repository> [<remote-alias>] add the provided repository as a remote; if no local alias is provided, then the name of the repository will be used as the remote annotate <file> [<file2> [...]] annotate one or more files in Kiln create-branch <branch-name> create a branch repository in Kiln, which can be added to your remotes via "gitkiln add-remote" filehistory <file> [<file2> [...]] show the history for one or more files in Kiln hg-sha <sha> [<sha> [...]] show the equivalent Mercurial SHAs corresponding to the given Git SHAs history go to the history of this repository in Kiln logout log out of Kiln, disposing your authentication token related show related repositories in Kiln, including the entire graph of which commits have and have not been merged into branch repositories settings go to the settings tab for this repository in Kiln show <commit> [<commit2> [...]] go to the provided commits in Kiln. Commit IDs are expanded locally, so "git-kiln show HEAD^" and similar commands will work fine. show-file <file> [<file2> [...]] show the contents of one or more files in Kiln version show gitkiln's version numberIf you provide no command, git-kiln will take you to the repository inKiln.`constkilnUrlSuffix="kiln/"funcextractUrlsAndPaths(sstring)(base*url.URL,pathstring,errerror){out,err:=exec.Command("git","config","kiln.url").Output()iferr==nil&&len(out)>0{base,err=url.Parse(strings.TrimSpace(string(out)))}else{ifstrings.HasPrefix(s,"ssh://"){components:=strings.SplitN(strings.TrimPrefix(s,"ssh://"),"/",2)fullDomain:=strings.Split(components[0],"@")domain:=fullDomain[len(fullDomain)-1]rest:=""iflen(components)>1{rest=components[1]}ifstrings.HasSuffix(domain,".kilnhg.com"){s="https://"+domain+"/Code/"+rest+".git"}}base,err=url.Parse(s)iferr!=nil||(base.Scheme!="http"&&base.Scheme!="https"){err=fmt.Errorf("must either have an HTTP remote or kiln.url specified in config")return}}components:=strings.Split(base.Path,"/")l:=len(components)components[l-1]=strings.TrimSuffix(components[l-1],".git")path=strings.Join(components[l-3:l],"/")ifstrings.HasSuffix(base.Host,".kilnhg.com"){base.Path=""}else{idx:=strings.Index(base.Path,kilnUrlSuffix)ifidx<0{err=fmt.Errorf("not sure where Kiln is based on %v",base)return}base.Path=base.Path[0:idx+len(kilnUrlSuffix)]}return}funcisGitAvailable()bool{iferr:=exec.Command("git","version").Run();err!=nil{returnfalse}else{returntrue}}funcshowHelp(){fmt.Println(documentation)}funcshowVersion(){fmt.Println(VERSION)}funcensureArgs(nint,explanationstring)bool{iflen(os.Args)<n{fmt.Fprintln(os.Stderr,explanation)showHelp()returnfalse}else{returntrue}}funcrequireAuth(k*kiln.Client){iferr:=k.EnsureCredentials();err!=nil{fmt.Fprintf(os.Stderr,"unable to logon: %v\n",err)os.Exit(1)}}funcsplitRepoPath(repoPathstring)(project,group,repostring){parts:=strings.Split(repoPath,"/")repo=parts[len(parts)-1]iflen(parts)>1{group=parts[len(parts)-2]}iflen(parts)>2{project=parts[len(parts)-3]}return}funcfindTargets(related[]kiln.Repo,project,group,repostring)[]kiln.Repo{targets:=make([]kiln.Repo,0)for_,r:=rangerelated{ifr.Slug==repo&&(len(group)==0||r.GroupSlug==group)&&(len(project)==0||r.ProjectSlug==project){targets=append(targets,r)}}returntargets}funcdispatch(k*kiln.Client,repoPathstring){varcommandstringiflen(os.Args)==1{command="history"}else{command=os.Args[1]}switchcommand{case"add-remote":iflen(os.Args)<3||len(os.Args)>5{fmt.Fprintf(os.Stderr,"you must provide a repo to add as the remote")showHelp()return}requireAuth(k)args:=os.Args[2:len(os.Args)]ssh:=falseifargs[0]=="--ssh"{ssh=trueargs=args[1:len(args)]}related,err:=k.RelatedRepos(repoPath)iferr!=nil{fmt.Fprintf(os.Stderr,"unable to query related repos: %v\n",err)return}project,group,repo:=splitRepoPath(args[0])targets:=findTargets(related,project,group,repo)iflen(targets)==0{fmt.Fprintf(os.Stderr,"nothing found; you must use exact matches\n")}elseiflen(targets)>1{fmt.Fprintf(os.Stderr,"too many matches; please provide more components\n")fmt.Fprintf(os.Stderr,"Matches:\n")for_,r:=rangetargets{fmt.Fprintf(os.Stderr,"\t%v/%v/%v\n",r.ProjectSlug,r.GroupSlug,r.Slug)}fmt.Fprintln(os.Stderr,"")}else{varremoteNamestringiflen(args)==2{remoteName=args[1]}else{remoteName=repo}varremoteURLstringifssh{remoteURL=targets[0].GitSshUrl}else{remoteURL=targets[0].GitUrl}out,err:=exec.Command("git","remote","add",remoteName,remoteURL).CombinedOutput()iferr!=nil||strings.HasPrefix(string(out),"fatal: "){fmt.Fprintf(os.Stderr,"could not add remote: %s",out)}}case"annotate":ifensureArgs(3,"you must provide at least one file to annotate"){for_,file:=rangeos.Args[2:len(os.Args)]{k.BrowseAnnotatedFile(repoPath,file)}}case"create-branch":ifensureArgs(3,"you must provide a branch name to create"){requireAuth(k)branchName:=os.Args[2]r,err:=k.CreateBranch(repoPath,branchName)iferr!=nil{fmt.Fprintf(os.Stderr,"could not create branch: %v\n",err)return}fmt.Printf("created branch repository \"%v\"\n",r.GitUrl)out,err:=exec.Command("git","remote","add",branchName,r.GitUrl).CombinedOutput()iferr!=nil||strings.HasPrefix(string(out),"fatal: "){fmt.Fprintf(os.Stderr,"could not add remote: %s",out)return}fmt.Printf("added \"%v\" as remote for \"%v\"\n",branchName,r.GitUrl)}case"filehistory":ifensureArgs(3,"you must provide at least one file to view"){for_,file:=rangeos.Args[2:len(os.Args)]{k.BrowseFileHistory(repoPath,file)}}case"help":showHelp()case"hg-sha":ifensureArgs(3,"you must provide at least one commit SHA to lookup"){requireAuth(k)commits:=make([]string,0,len(os.Args)-2)for_,commit:=rangeos.Args[2:len(os.Args)]{iffullSHA,err:=k.ResolveSHA(commit);err!=nil{fmt.Fprintf(os.Stderr,"WARNING: Unable to resolve %v\n",commit)}else{commits=append(commits,fullSHA)}}equivalents,err:=k.MercurialEquivalents(repoPath,commits)iferr!=nil{fmt.Printf("Unable to look up Mercurial SHAs: %v\n",err)}else{forgitSHA,hgSHAs:=rangeequivalents{fmt.Printf("Git[%v]: Hg%v\n",gitSHA,hgSHAs)}}}case"history":k.BrowseHistory(repoPath)case"logout":ifk.LoadCredentials(){k.DeleteCredentials()}case"related":k.BrowseRelated(repoPath)case"settings":k.BrowseSettings(repoPath)case"show":ifensureArgs(3,"you must supply at least one commit SHA to show"){for_,commit:=rangeos.Args[2:len(os.Args)]{iferr:=k.BrowseCommit(repoPath,commit);err!=nil{fmt.Fprintf(os.Stderr,"couldn't load commit: %v\n",err)}}}case"show-file":ifensureArgs(3,"you must provide at least one file to view"){for_,file:=rangeos.Args[2:len(os.Args)]{k.BrowseFile(repoPath,file)}}case"version":showVersion()default:showHelp()}}funcmain(){if!isGitAvailable(){fmt.Fprintln(os.Stderr,"git not found")os.Exit(1)}if_,err:=kiln.GitRoot();err!=nil{iflen(os.Args)==2&&os.Args[1]=="help"{ showHelp()
return
} else if len(os.Args) == 2 && os.Args[1] == "version" {
+ showVersion() return
} else {
fmt.Fprintln(os.Stderr, "git-kiln must be run from within a Git repository; see \"gitkiln help\"")
os.Exit(1)}}bytesOut,err:=exec.Command("git","ls-remote","--get-url").Output()repoUrl:=strings.TrimSpace(string(bytesOut))iferr!=nil||strings.HasPrefix(repoUrl,"fatal:"){fmt.Fprintln(os.Stderr,"no remote found; set one with \"git remote add\"")os.Exit(1)}kilnUrl,repoPath,err:=extractUrlsAndPaths(repoUrl)iferr!=nil{fmt.Fprintf(os.Stderr,"%v\n",err)os.Exit(1)}k:=kiln.NewClient(kilnUrl)dispatch(k,repoPath)}
Attach a Trello Card
Add a tag
Your session has expired
You are no longer logged in. Please log in and try your request again.
Filter RSS Feed
This RSS feed URL allows you to see the contents of your current filter using any feed reader.
This link includes a special authentication token. If you share the URL with anyone else, they can see this RSS feed's activity. You can disable these tokens when needed.
Your current filter is unsaved; changing it won't affect this RSS feed.