在使用 php curl 将文件上传到 Azure DevOps Git 之前如何获取 oldObjectId?
How can I get oldObjectId before uploading a file to Azure DevOps Git using php curl?
问题
在文档 add-a-binary-file 中,您可以看到我们需要一个 oldObjectId
参数来将文件上传到 Azure DevOps git:
{
"refUpdates": [
{
"name": "refs/heads/master",
"oldObjectId": "1380164a8118686087e38ce91f36b24b58c2df02"
}
],
"commits": [
{
"comment": "Added new image file.",
"changes": [
{
"changeType": "add",
"item": {
"path": "/images/people/default.jpg"
},
"newContent": {
"content": "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",
"contentType": "base64encoded"
}
}
]
}
]
}
这是我的代码片段:
/**
* getPushesList
* @param string $lastCommitUrl
*
* @return bool|string
*/
function getPushesList($lastCommitUrl=''){
global $baseUri;
global $organization;
global $project;
global $repositoryId;
global $branch;
global $username;
global $accessToken;
$url = $baseUri . '/' . $organization . '/' . $project . '/_apis/git/repositories/' . $repositoryId . '/pushes?api-version=5.1';
$url = $lastCommitUrl ? $lastCommitUrl : $url;
$queryArr = [
'searchCriteria.refName' => 'refs/heads/' . $branch,
'$top' => 1,
];
$queryStr = http_build_query($queryArr);
$url .= '&' . urldecode($queryStr);
$authorization = 'basic ' . base64_encode($username . ':' . $accessToken);
//$url sample: https://dev.azure.com/kmx3ecup/img_bed/_apis/git/repositories/img_bed/pushes?api-version=5.1&searchCriteria.refName=&searchCriteria.includeRefUpdates=false&$top=1
// echo $url;exit;
$ch = curl_init();
$options = [
CURLOPT_URL => $url,
CURLOPT_HTTPHEADER => [
'authorization: ' . $authorization
],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => 0,
];
//In case you need a proxy
// $options[CURLOPT_PROXY] = 'http://127.0.0.1:1087';
curl_setopt_array($ch, $options);
$responseJson = curl_exec($ch);
if(curl_errno($ch)){
echo 'Error: ' . curl_error($ch);
}
$retArr = json_decode($responseJson, true);
curl_close($ch);
return $retArr;
}
/**
* getLastCommitUrl
* @return mixed|string
* @throws \GuzzleHttp\Exception\GuzzleException
*/
function getLastCommitUrl(){
$repoList = getPushesList();
$lastCommitUrl = '';
if(is_array($repoList) && isset($repoList['value'][0]['url'])){
$lastCommitUrl = $repoList['value'][0]['url'];
}
return $lastCommitUrl;
}
/**
* getLastCommitId
* @return mixed|string
* @throws \GuzzleHttp\Exception\GuzzleException
*/
function getLastCommitId(){
$lastCommitUrl = getLastCommitUrl();
//forty 0
$lastCommitId = str_repeat('0', 40);
if($lastCommitUrl){
$result = getPushesList($lastCommitUrl);
if(isset($result['commits'][0]['commitId'])){
$lastCommitId = $result['commits'][0]['commitId'];
}
}
return $lastCommitId;
}
/**
* create a file in the specified repo and branch
* @param $uploadFilePath
* @param $path
*
* @return mixed
*/
function create($uploadFilePath, $path){
global $baseUri;
global $organization;
global $project;
global $repositoryId;
global $branch;
global $username;
global $accessToken;
$url = $baseUri . '/' . $organization . '/' . $project . '/_apis/git/repositories/' . $repositoryId . '/pushes?api-version=5.1';
$authorization = 'basic ' . base64_encode($username . ':' . $accessToken);
//$url sample: https://dev.azure.com/kmx3ecup/img_bed/_apis/git/repositories/img_bed/pushes?api-version=5.1&searchCriteria.refName=&searchCriteria.includeRefUpdates=false&$top=1
// echo $url;exit;
$lastCommitId = getLastCommitId();
// var_dump($lastCommitId);exit;
$postFields = [
'refUpdates' => [
[
'name'=> 'refs/heads/' . $branch,
'oldObjectId' => $lastCommitId,
],
],
'commits' => [
[
'comment' => 'This is a test push',
'changes' => [
[
//add, edit, delete
'changeType' => 'add',
'item' => [
'path' => $path,
],
'newContent' => [
'content' => base64_encode(file_get_contents($uploadFilePath)),
'contentType' => 'base64encoded'
]
]
],
],
],
];
$ch = curl_init();
$options = [
CURLOPT_URL => $url,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'authorization: ' . $authorization,
'content-type: application/json',
],
CURLOPT_POSTFIELDS => json_encode($postFields),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => 0,
];
//In case you need a proxy
// $options[CURLOPT_PROXY] = 'http://127.0.0.1:1087';
curl_setopt_array($ch, $options);
$responseJson = curl_exec($ch);
if(curl_errno($ch)){
echo 'Error: ' . curl_error($ch);
}
curl_close($ch);
return json_decode($responseJson, true);
}
$baseUri = 'https://dev.azure.com';
$organization = '<YOUR_ORGANIZATION>';
$project = '<YOUR_PROJECT_NAME>';
$repositoryId = '<YOUR_REPOSITORY_ID_OR_REPOSITORY_NAME>';
$branch = 'master';
$username = '<YOUR_USERNAME>';
$accessToken = '<YOUR_ACCESS_TOKEN>';
$uploadFilePath = '/path/to/test.jpg';
$path = '/images/' . date('Y/m/d');
$returnArr = create($uploadFilePath, $path);
var_dump($returnArr) ;
我得到的方式oldObjectId
:
- 从推送列表第一个条目中获取
lastCommitUrl
- 使用
lastCommitUrl
获取lastCommitId
(但失败,返回NULL。)
相关文档:
Get pushes list
Get a specified push
Push changes to repository(upload a file)
问题:是不是我获取lastCommitId的方式不对?
原来oldObjectId
是refs
的objectId
,你可以试试我下面的代码,对我来说没问题。
/**
* getRefsList
* Doc: https://docs.microsoft.com/en-us/rest/api/azure/devops/git/refs/list?view=azure-devops-rest-5.1#refs
*
* @param $branch
* @return bool|string
*/
function getRefsList($branch){
global $baseUri;
global $organization;
global $project;
global $repositoryId;
global $username;
global $accessToken;
//GET https://dev.azure.com/{organization}/{project}/_apis/git/repositories/{repositoryId}/refs?api-version=5.1
$url = $baseUri . '/' . $organization . '/' . $project . '/_apis/git/repositories/' . $repositoryId . '/refs?api-version=5.1';
$queryArr = [
'filter' => 'heads/' . $branch,
];
if(!empty($queryArr)){
$queryStr = http_build_query($queryArr);
$url .= '&' . $queryStr;
}
// echo($url);exit;
$authorization = 'basic ' . base64_encode($username . ':' . $accessToken);
// echo $url;exit;
$ch = curl_init();
$options = [
CURLOPT_URL => $url,
CURLOPT_HTTPHEADER => [
'authorization: ' . $authorization
],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => 0,
];
//In case you need a proxy
// $options[CURLOPT_PROXY] = 'http://127.0.0.1:1087';
curl_setopt_array($ch, $options);
$responseJson = curl_exec($ch);
if(curl_errno($ch)){
echo 'Error: ' . curl_error($ch);
}
$retArr = json_decode($responseJson, true);
curl_close($ch);
$refs = [];
if(isset($retArr['count']) && $retArr['count'] > 0){
$refs = $retArr['value'];
}
return $refs;
}
/**
* getObjectIdOfRef
* @param $branch
*
* @return mixed|string
*/
function getObjectIdOfRef($branch){
$refs = getRefsList($branch);
$objectId = '';
if($refs){
foreach($refs as $ref){
if($ref['name'] == 'refs/heads/'.$branch){
$objectId = $ref['objectId'];
break;
}
}
}
return $objectId;
}
/**
* create a file in the specified repo and branch
* Doc: https://docs.microsoft.com/en-us/rest/api/azure/devops/git/pushes/create?view=azure-devops-rest-5.1
* @param $uploadFilePath
* @param $path
*
* @return mixed
*/
function create($uploadFilePath, $path){
global $baseUri;
global $organization;
global $project;
global $repositoryId;
global $branch;
global $username;
global $accessToken;
$url = $baseUri . '/' . $organization . '/' . $project . '/_apis/git/repositories/' . $repositoryId . '/pushes?api-version=5.1';
$authorization = 'basic ' . base64_encode($username . ':' . $accessToken);
//$url sample: https://dev.azure.com/kmx3ecup/img_bed/_apis/git/repositories/img_bed/pushes?api-version=5.1&searchCriteria.refName=&searchCriteria.includeRefUpdates=false&$top=1
// echo $url;exit;
$oldObjectId = getObjectIdOfRef($branch);
// var_dump($oldObjectId);exit;
$postFields = [
'refUpdates' => [
[
'name'=> 'refs/heads/' . $branch,
'oldObjectId' => $oldObjectId,
],
],
'commits' => [
[
'comment' => 'This is a test push',
'changes' => [
[
//add, edit, delete
'changeType' => 'add',
'item' => [
'path' => $path,
],
'newContent' => [
'content' => base64_encode(file_get_contents($uploadFilePath)),
'contentType' => 'base64encoded'
]
]
],
],
],
];
$ch = curl_init();
$options = [
CURLOPT_URL => $url,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'authorization: ' . $authorization,
'content-type: application/json',
],
CURLOPT_POSTFIELDS => json_encode($postFields),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => 0,
];
//In case you need a proxy
// $options[CURLOPT_PROXY] = 'http://127.0.0.1:1087';
curl_setopt_array($ch, $options);
$responseJson = curl_exec($ch);
if(curl_errno($ch)){
echo 'Error: ' . curl_error($ch);
}
curl_close($ch);
return json_decode($responseJson, true);
}
$baseUri = 'https://dev.azure.com';
$organization = '<YOUR_ORGANIZATION>';
$project = '<YOUR_PROJECT_NAME>';
$repositoryId = '<YOUR_REPOSITORY_ID_OR_REPOSITORY_NAME>';
$branch = 'master';
$username = '<YOUR_USERNAME>';
$accessToken = '<YOUR_ACCESS_TOKEN>';
$uploadFilePath = '/path/to/test.jpg';
$path = '/images/' . date('Y/m/d') . '/' . basename($uploadFilePath);
$retArr = create($uploadFilePath, $path);
$publicUrl = $retArr['repository']['url'] . '/items?path=' . $path . '&versionDescriptor[versionOptions]=0&versionDescriptor[versionType]=0&versionDescriptor[version]=' . $branch . '&resolveLfs=true&$format=octetStream&api-version=5.0';
echo $publicUrl;
问题
在文档 add-a-binary-file 中,您可以看到我们需要一个 oldObjectId
参数来将文件上传到 Azure DevOps git:
{
"refUpdates": [
{
"name": "refs/heads/master",
"oldObjectId": "1380164a8118686087e38ce91f36b24b58c2df02"
}
],
"commits": [
{
"comment": "Added new image file.",
"changes": [
{
"changeType": "add",
"item": {
"path": "/images/people/default.jpg"
},
"newContent": {
"content": "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",
"contentType": "base64encoded"
}
}
]
}
]
}
这是我的代码片段:
/**
* getPushesList
* @param string $lastCommitUrl
*
* @return bool|string
*/
function getPushesList($lastCommitUrl=''){
global $baseUri;
global $organization;
global $project;
global $repositoryId;
global $branch;
global $username;
global $accessToken;
$url = $baseUri . '/' . $organization . '/' . $project . '/_apis/git/repositories/' . $repositoryId . '/pushes?api-version=5.1';
$url = $lastCommitUrl ? $lastCommitUrl : $url;
$queryArr = [
'searchCriteria.refName' => 'refs/heads/' . $branch,
'$top' => 1,
];
$queryStr = http_build_query($queryArr);
$url .= '&' . urldecode($queryStr);
$authorization = 'basic ' . base64_encode($username . ':' . $accessToken);
//$url sample: https://dev.azure.com/kmx3ecup/img_bed/_apis/git/repositories/img_bed/pushes?api-version=5.1&searchCriteria.refName=&searchCriteria.includeRefUpdates=false&$top=1
// echo $url;exit;
$ch = curl_init();
$options = [
CURLOPT_URL => $url,
CURLOPT_HTTPHEADER => [
'authorization: ' . $authorization
],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => 0,
];
//In case you need a proxy
// $options[CURLOPT_PROXY] = 'http://127.0.0.1:1087';
curl_setopt_array($ch, $options);
$responseJson = curl_exec($ch);
if(curl_errno($ch)){
echo 'Error: ' . curl_error($ch);
}
$retArr = json_decode($responseJson, true);
curl_close($ch);
return $retArr;
}
/**
* getLastCommitUrl
* @return mixed|string
* @throws \GuzzleHttp\Exception\GuzzleException
*/
function getLastCommitUrl(){
$repoList = getPushesList();
$lastCommitUrl = '';
if(is_array($repoList) && isset($repoList['value'][0]['url'])){
$lastCommitUrl = $repoList['value'][0]['url'];
}
return $lastCommitUrl;
}
/**
* getLastCommitId
* @return mixed|string
* @throws \GuzzleHttp\Exception\GuzzleException
*/
function getLastCommitId(){
$lastCommitUrl = getLastCommitUrl();
//forty 0
$lastCommitId = str_repeat('0', 40);
if($lastCommitUrl){
$result = getPushesList($lastCommitUrl);
if(isset($result['commits'][0]['commitId'])){
$lastCommitId = $result['commits'][0]['commitId'];
}
}
return $lastCommitId;
}
/**
* create a file in the specified repo and branch
* @param $uploadFilePath
* @param $path
*
* @return mixed
*/
function create($uploadFilePath, $path){
global $baseUri;
global $organization;
global $project;
global $repositoryId;
global $branch;
global $username;
global $accessToken;
$url = $baseUri . '/' . $organization . '/' . $project . '/_apis/git/repositories/' . $repositoryId . '/pushes?api-version=5.1';
$authorization = 'basic ' . base64_encode($username . ':' . $accessToken);
//$url sample: https://dev.azure.com/kmx3ecup/img_bed/_apis/git/repositories/img_bed/pushes?api-version=5.1&searchCriteria.refName=&searchCriteria.includeRefUpdates=false&$top=1
// echo $url;exit;
$lastCommitId = getLastCommitId();
// var_dump($lastCommitId);exit;
$postFields = [
'refUpdates' => [
[
'name'=> 'refs/heads/' . $branch,
'oldObjectId' => $lastCommitId,
],
],
'commits' => [
[
'comment' => 'This is a test push',
'changes' => [
[
//add, edit, delete
'changeType' => 'add',
'item' => [
'path' => $path,
],
'newContent' => [
'content' => base64_encode(file_get_contents($uploadFilePath)),
'contentType' => 'base64encoded'
]
]
],
],
],
];
$ch = curl_init();
$options = [
CURLOPT_URL => $url,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'authorization: ' . $authorization,
'content-type: application/json',
],
CURLOPT_POSTFIELDS => json_encode($postFields),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => 0,
];
//In case you need a proxy
// $options[CURLOPT_PROXY] = 'http://127.0.0.1:1087';
curl_setopt_array($ch, $options);
$responseJson = curl_exec($ch);
if(curl_errno($ch)){
echo 'Error: ' . curl_error($ch);
}
curl_close($ch);
return json_decode($responseJson, true);
}
$baseUri = 'https://dev.azure.com';
$organization = '<YOUR_ORGANIZATION>';
$project = '<YOUR_PROJECT_NAME>';
$repositoryId = '<YOUR_REPOSITORY_ID_OR_REPOSITORY_NAME>';
$branch = 'master';
$username = '<YOUR_USERNAME>';
$accessToken = '<YOUR_ACCESS_TOKEN>';
$uploadFilePath = '/path/to/test.jpg';
$path = '/images/' . date('Y/m/d');
$returnArr = create($uploadFilePath, $path);
var_dump($returnArr) ;
我得到的方式oldObjectId
:
- 从推送列表第一个条目中获取
lastCommitUrl
- 从推送列表第一个条目中获取
- 使用
lastCommitUrl
获取lastCommitId
(但失败,返回NULL。)
- 使用
相关文档:
Get pushes list
Get a specified push
Push changes to repository(upload a file)
问题:是不是我获取lastCommitId的方式不对?
原来oldObjectId
是refs
的objectId
,你可以试试我下面的代码,对我来说没问题。
/**
* getRefsList
* Doc: https://docs.microsoft.com/en-us/rest/api/azure/devops/git/refs/list?view=azure-devops-rest-5.1#refs
*
* @param $branch
* @return bool|string
*/
function getRefsList($branch){
global $baseUri;
global $organization;
global $project;
global $repositoryId;
global $username;
global $accessToken;
//GET https://dev.azure.com/{organization}/{project}/_apis/git/repositories/{repositoryId}/refs?api-version=5.1
$url = $baseUri . '/' . $organization . '/' . $project . '/_apis/git/repositories/' . $repositoryId . '/refs?api-version=5.1';
$queryArr = [
'filter' => 'heads/' . $branch,
];
if(!empty($queryArr)){
$queryStr = http_build_query($queryArr);
$url .= '&' . $queryStr;
}
// echo($url);exit;
$authorization = 'basic ' . base64_encode($username . ':' . $accessToken);
// echo $url;exit;
$ch = curl_init();
$options = [
CURLOPT_URL => $url,
CURLOPT_HTTPHEADER => [
'authorization: ' . $authorization
],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => 0,
];
//In case you need a proxy
// $options[CURLOPT_PROXY] = 'http://127.0.0.1:1087';
curl_setopt_array($ch, $options);
$responseJson = curl_exec($ch);
if(curl_errno($ch)){
echo 'Error: ' . curl_error($ch);
}
$retArr = json_decode($responseJson, true);
curl_close($ch);
$refs = [];
if(isset($retArr['count']) && $retArr['count'] > 0){
$refs = $retArr['value'];
}
return $refs;
}
/**
* getObjectIdOfRef
* @param $branch
*
* @return mixed|string
*/
function getObjectIdOfRef($branch){
$refs = getRefsList($branch);
$objectId = '';
if($refs){
foreach($refs as $ref){
if($ref['name'] == 'refs/heads/'.$branch){
$objectId = $ref['objectId'];
break;
}
}
}
return $objectId;
}
/**
* create a file in the specified repo and branch
* Doc: https://docs.microsoft.com/en-us/rest/api/azure/devops/git/pushes/create?view=azure-devops-rest-5.1
* @param $uploadFilePath
* @param $path
*
* @return mixed
*/
function create($uploadFilePath, $path){
global $baseUri;
global $organization;
global $project;
global $repositoryId;
global $branch;
global $username;
global $accessToken;
$url = $baseUri . '/' . $organization . '/' . $project . '/_apis/git/repositories/' . $repositoryId . '/pushes?api-version=5.1';
$authorization = 'basic ' . base64_encode($username . ':' . $accessToken);
//$url sample: https://dev.azure.com/kmx3ecup/img_bed/_apis/git/repositories/img_bed/pushes?api-version=5.1&searchCriteria.refName=&searchCriteria.includeRefUpdates=false&$top=1
// echo $url;exit;
$oldObjectId = getObjectIdOfRef($branch);
// var_dump($oldObjectId);exit;
$postFields = [
'refUpdates' => [
[
'name'=> 'refs/heads/' . $branch,
'oldObjectId' => $oldObjectId,
],
],
'commits' => [
[
'comment' => 'This is a test push',
'changes' => [
[
//add, edit, delete
'changeType' => 'add',
'item' => [
'path' => $path,
],
'newContent' => [
'content' => base64_encode(file_get_contents($uploadFilePath)),
'contentType' => 'base64encoded'
]
]
],
],
],
];
$ch = curl_init();
$options = [
CURLOPT_URL => $url,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'authorization: ' . $authorization,
'content-type: application/json',
],
CURLOPT_POSTFIELDS => json_encode($postFields),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => 0,
];
//In case you need a proxy
// $options[CURLOPT_PROXY] = 'http://127.0.0.1:1087';
curl_setopt_array($ch, $options);
$responseJson = curl_exec($ch);
if(curl_errno($ch)){
echo 'Error: ' . curl_error($ch);
}
curl_close($ch);
return json_decode($responseJson, true);
}
$baseUri = 'https://dev.azure.com';
$organization = '<YOUR_ORGANIZATION>';
$project = '<YOUR_PROJECT_NAME>';
$repositoryId = '<YOUR_REPOSITORY_ID_OR_REPOSITORY_NAME>';
$branch = 'master';
$username = '<YOUR_USERNAME>';
$accessToken = '<YOUR_ACCESS_TOKEN>';
$uploadFilePath = '/path/to/test.jpg';
$path = '/images/' . date('Y/m/d') . '/' . basename($uploadFilePath);
$retArr = create($uploadFilePath, $path);
$publicUrl = $retArr['repository']['url'] . '/items?path=' . $path . '&versionDescriptor[versionOptions]=0&versionDescriptor[versionType]=0&versionDescriptor[version]=' . $branch . '&resolveLfs=true&$format=octetStream&api-version=5.0';
echo $publicUrl;